[cairo-commit] 11 commits - src/cairo-analysis-surface.c src/cairo-debug.c src/cairo-image-source.c src/cairoint.h src/cairo-paginated-surface.c src/cairo-pattern.c src/cairo-pdf-operators.c src/cairo-pdf-surface.c src/cairo-pdf-surface-private.h src/cairo-ps-surface.c src/cairo-ps-surface-private.h src/cairo-recording-surface.c src/cairo-recording-surface-private.h src/cairo-surface-wrapper.c src/cairo-surface-wrapper-private.h src/cairo-type3-glyph-surface.c test/Makefile.sources test/README test/recording-ink-extents.c test/record-neg-extents.c test/record-replay-extend.c test/reference

Adrian Johnson ajohnson at kemper.freedesktop.org
Sun Jun 5 13:02:06 UTC 2016


 dev/null                                                             |binary
 src/cairo-analysis-surface.c                                         |  124 +-
 src/cairo-debug.c                                                    |   19 
 src/cairo-image-source.c                                             |   67 -
 src/cairo-paginated-surface.c                                        |    2 
 src/cairo-pattern.c                                                  |   33 
 src/cairo-pdf-operators.c                                            |    3 
 src/cairo-pdf-surface-private.h                                      |   23 
 src/cairo-pdf-surface.c                                              |  580 +++++-----
 src/cairo-ps-surface-private.h                                       |    5 
 src/cairo-ps-surface.c                                               |  562 +++++----
 src/cairo-recording-surface-private.h                                |    3 
 src/cairo-recording-surface.c                                        |   24 
 src/cairo-surface-wrapper-private.h                                  |    1 
 src/cairo-surface-wrapper.c                                          |   13 
 src/cairo-type3-glyph-surface.c                                      |   23 
 src/cairoint.h                                                       |    8 
 test/Makefile.sources                                                |    3 
 test/README                                                          |   10 
 test/record-neg-extents.c                                            |  217 +++
 test/record-replay-extend.c                                          |  227 +++
 test/recording-ink-extents.c                                         |  172 ++
 test/reference/arc-direction.pdf.ref.png                             |binary
 test/reference/arc-direction.ref.png                                 |binary
 test/reference/arc-looping-dash.pdf.ref.png                          |binary
 test/reference/big-empty-box.ps.rgb24.ref.png                        |binary
 test/reference/big-empty-triangle.ps.rgb24.ref.png                   |binary
 test/reference/big-little-box.ps.rgb24.ref.png                       |binary
 test/reference/bitmap-font.ps.rgb24.ref.png                          |binary
 test/reference/bug-51910.pdf.ref.png                                 |binary
 test/reference/bug-51910.ps.ref.png                                  |binary
 test/reference/bug-84115.pdf.ref.png                                 |binary
 test/reference/bug-84115.ps.arg32.ref.png                            |binary
 test/reference/bug-84115.ps.argb32.ref.png                           |binary
 test/reference/bug-84115.ps.rgb24.ref.png                            |binary
 test/reference/bug-bo-ricotz.argb32.ref.png                          |binary
 test/reference/bug-bo-ricotz.pdf.rgb24.ref.png                       |binary
 test/reference/bug-bo-ricotz.ps.ref.png                              |binary
 test/reference/bug-extents.pdf.ref.png                               |binary
 test/reference/bug-source-cu.pdf.argb32.ref.png                      |binary
 test/reference/bug-source-cu.pdf.rgb24.ref.png                       |binary
 test/reference/bug-source-cu.ps.argb32.ref.png                       |binary
 test/reference/bug-source-cu.ps.rgb24.ref.png                        |binary
 test/reference/bug-spline.ps.ref.png                                 |binary
 test/reference/caps-05.pdf.ref.png                                   |binary
 test/reference/caps-05.ps.ref.png                                    |binary
 test/reference/caps-1.pdf.ref.png                                    |binary
 test/reference/caps-1.ps.ref.png                                     |binary
 test/reference/caps-2.pdf.ref.png                                    |binary
 test/reference/caps-2.ps.ref.png                                     |binary
 test/reference/caps-joins-05.pdf.ref.png                             |binary
 test/reference/caps-joins-05.ps.ref.png                              |binary
 test/reference/caps-joins-1.pdf.ref.png                              |binary
 test/reference/caps-joins-1.ps.ref.png                               |binary
 test/reference/caps-joins-2.pdf.ref.png                              |binary
 test/reference/caps-joins-2.ps.ref.png                               |binary
 test/reference/caps-joins-curve.pdf.ref.png                          |binary
 test/reference/caps-joins.pdf.ref.png                                |binary
 test/reference/caps-sub-paths.pdf.ref.png                            |binary
 test/reference/caps-tails-curve.pdf.ref.png                          |binary
 test/reference/caps.pdf.ref.png                                      |binary
 test/reference/checkerboard.pdf.ref.png                              |binary
 test/reference/clip-complex-bug61592.pdf.ref.png                     |binary
 test/reference/clip-complex-bug61592.ps.ref.png                      |binary
 test/reference/clip-device-offset.ps.rgb24.ref.png                   |binary
 test/reference/clip-disjoint-quad.pdf.ref.png                        |binary
 test/reference/clip-disjoint-quad.ps.ref.png                         |binary
 test/reference/clip-disjoint.ps.ref.png                              |binary
 test/reference/clip-fill-no-op.ps.ref.png                            |binary
 test/reference/clip-fill-rule-pixel-aligned.ps.argb32.ref.png        |binary
 test/reference/clip-fill-rule-pixel-aligned.ps.rgb24.ref.png         |binary
 test/reference/clip-fill-rule.pdf.argb32.ref.png                     |binary
 test/reference/clip-fill-rule.pdf.rgb24.ref.png                      |binary
 test/reference/clip-fill-rule.rgb24.ref.png                          |binary
 test/reference/clip-fill.ps.ref.png                                  |binary
 test/reference/clip-image.pdf.ref.png                                |binary
 test/reference/clip-intersect.ps.ref.png                             |binary
 test/reference/clip-operator.pdf.argb32.ref.png                      |binary
 test/reference/clip-operator.rgb24.ref.png                           |binary
 test/reference/clip-push-group.pdf.ref.png                           |binary
 test/reference/clip-rectilinear.ps.ref.png                           |binary
 test/reference/clip-rotate-image-surface-paint.pdf.argb32.ref.png    |binary
 test/reference/clip-rotate-image-surface-paint.pdf.rgb24.ref.png     |binary
 test/reference/clip-rotate-image-surface-paint.ps.ref.png            |binary
 test/reference/clip-stroke-no-op.ps.ref.png                          |binary
 test/reference/clip-stroke-unbounded.argb32.ref.png                  |binary
 test/reference/clip-stroke-unbounded.rgb24.ref.png                   |binary
 test/reference/clip-stroke.ps.ref.png                                |binary
 test/reference/clip-text.ps.ref.png                                  |binary
 test/reference/clipped-group.pdf.ref.png                             |binary
 test/reference/close-path-current-point.pdf.ref.png                  |binary
 test/reference/close-path.pdf.argb32.ref.png                         |binary
 test/reference/close-path.pdf.rgb24.ref.png                          |binary
 test/reference/copy-path.pdf.ref.png                                 |binary
 test/reference/culled-glyphs.ps.ref.png                              |binary
 test/reference/dash-caps-joins.pdf.ref.png                           |binary
 test/reference/dash-caps-joins.ps.ref.png                            |binary
 test/reference/dash-curve.pdf.ref.png                                |binary
 test/reference/dash-curve.ps.ref.png                                 |binary
 test/reference/dash-infinite-loop.pdf.ref.png                        |binary
 test/reference/dash-scale.pdf.ref.png                                |binary
 test/reference/dash-state.pdf.ref.png                                |binary
 test/reference/dash-zero-length.pdf.argb32.ref.png                   |binary
 test/reference/dash-zero-length.pdf.rgb24.ref.png                    |binary
 test/reference/degenerate-curve-to.pdf.ref.png                       |binary
 test/reference/degenerate-linear-gradient.pdf.ref.png                |binary
 test/reference/degenerate-path.pdf.argb32.ref.png                    |binary
 test/reference/degenerate-path.pdf.rgb24.ref.png                     |binary
 test/reference/degenerate-pen.pdf.argb32.ref.png                     |binary
 test/reference/degenerate-pen.pdf.rgb24.ref.png                      |binary
 test/reference/degenerate-radial-gradient.pdf.ref.png                |binary
 test/reference/degenerate-rel-curve-to.pdf.ref.png                   |binary
 test/reference/device-offset-fractional.pdf.ref.png                  |binary
 test/reference/device-offset-positive.ps.rgb24.ref.png               |binary
 test/reference/device-offset.ps.rgb24.ref.png                        |binary
 test/reference/extend-pad-border.pdf.ref.png                         |binary
 test/reference/fallback.pdf.ref.png                                  |binary
 test/reference/fallback.ps.ref.png                                   |binary
 test/reference/fill-alpha.ps.argb32.ref.png                          |binary
 test/reference/fill-and-stroke-alpha-add.pdf.ref.png                 |binary
 test/reference/fill-and-stroke-alpha.pdf.ref.png                     |binary
 test/reference/fill-and-stroke.pdf.argb32.ref.png                    |binary
 test/reference/fill-and-stroke.pdf.rgb24.ref.png                     |binary
 test/reference/fill-degenerate-sort-order.argb32.ref.png             |binary
 test/reference/fill-degenerate-sort-order.pdf.ref.png                |binary
 test/reference/fill-degenerate-sort-order.rgb24.ref.png              |binary
 test/reference/fill-empty.ps.rgb24.ref.png                           |binary
 test/reference/fill-image.ps.ref.png                                 |binary
 test/reference/fill-missed-stop.pdf.argb32.ref.png                   |binary
 test/reference/fill-missed-stop.pdf.rgb24.ref.png                    |binary
 test/reference/fill-rule.pdf.ref.png                                 |binary
 test/reference/fill-rule.rgb24.ref.png                               |binary
 test/reference/finer-grained-fallbacks.pdf.argb32.ref.png            |binary
 test/reference/finer-grained-fallbacks.pdf.rgb24.ref.png             |binary
 test/reference/finer-grained-fallbacks.ps.argb32.ref.png             |binary
 test/reference/finer-grained-fallbacks.ps.rgb24.ref.png              |binary
 test/reference/font-matrix-translation.ps.ref.png                    |binary
 test/reference/ft-show-glyphs-positioning.pdf.ref.png                |binary
 test/reference/ft-show-glyphs-positioning.ps.ref.png                 |binary
 test/reference/ft-show-glyphs-table.ps.ref.png                       |binary
 test/reference/ft-text-vertical-layout-type3.pdf.ref.png             |binary
 test/reference/ft-text-vertical-layout-type3.ps.ref.png              |binary
 test/reference/ft-text-vertical-layout-type3.ref.png                 |binary
 test/reference/glyph-cache-pressure.ps.ref.png                       |binary
 test/reference/gradient-alpha.pdf.argb32.ref.png                     |binary
 test/reference/gradient-alpha.pdf.rgb24.ref.png                      |binary
 test/reference/gradient-constant-alpha.pdf.argb32.ref.png            |binary
 test/reference/gradient-constant-alpha.pdf.rgb24.ref.png             |binary
 test/reference/gradient-zero-stops-mask.ps.rgb24.ref.png             |binary
 test/reference/gradient-zero-stops.ps.rgb24.png                      |binary
 test/reference/group-unaligned.ps.ref.png                            |binary
 test/reference/halo-transform.ps.ref.png                             |binary
 test/reference/halo.ps.ref.png                                       |binary
 test/reference/huge-linear.pdf.ref.png                               |binary
 test/reference/huge-radial.pdf.ref.png                               |binary
 test/reference/huge-radial.ref.png                                   |binary
 test/reference/image-surface-source.ps.argb32.ref.png                |binary
 test/reference/image-surface-source.ps.rgb24.ref.png                 |binary
 test/reference/infinite-join.pdf.ref.png                             |binary
 test/reference/inverse-text.ps.ref.png                               |binary
 test/reference/joins-loop.ps.ref.png                                 |binary
 test/reference/joins-star.ps.ref.png                                 |binary
 test/reference/joins.pdf.argb32.ref.png                              |binary
 test/reference/joins.pdf.rgb24.ref.png                               |binary
 test/reference/large-font.ps.ref.png                                 |binary
 test/reference/leaky-dashed-stroke.pdf.ref.png                       |binary
 test/reference/leaky-polygon.pdf.ref.png                             |binary
 test/reference/line-width-large-overlap-offset.ps.ref.png            |binary
 test/reference/line-width-large-overlap-rotated.ps.ref.png           |binary
 test/reference/line-width-overlap-offset.ps.ref.png                  |binary
 test/reference/line-width-overlap-rotated.ps.ref.png                 |binary
 test/reference/line-width-scale.pdf.ref.png                          |binary
 test/reference/line-width-tolerance.pdf.ref.png                      |binary
 test/reference/line-width-tolerance.ps.ref.png                       |binary
 test/reference/line-width.pdf.ref.png                                |binary
 test/reference/linear-gradient-extend.pdf.ref.png                    |binary
 test/reference/linear-gradient-large.pdf.ref.png                     |binary
 test/reference/linear-gradient-large.ps.ref.png                      |binary
 test/reference/linear-gradient-one-stop.ps.rgb24.ref.png             |binary
 test/reference/linear-gradient-subset.pdf.ref.png                    |binary
 test/reference/linear-gradient-subset.ref.png                        |binary
 test/reference/linear-gradient.pdf.ref.png                           |binary
 test/reference/linear-gradient.ps3.ref.png                           |binary
 test/reference/linear-gradient.ref.png                               |binary
 test/reference/linear-uniform.ps.ref.png                             |binary
 test/reference/long-dashed-lines.pdf.ref.png                         |binary
 test/reference/mask-ctm.ps.rgb24.ref.png                             |binary
 test/reference/mask-surface-ctm.ps.rgb24.ref.png                     |binary
 test/reference/mask-transformed-image.pdf.ref.png                    |binary
 test/reference/mask-transformed-image.ps.ref.png                     |binary
 test/reference/mask-transformed-similar.pdf.ref.png                  |binary
 test/reference/mask-transformed-similar.ps.ref.png                   |binary
 test/reference/mask.argb32.ref.png                                   |binary
 test/reference/mask.pdf.argb32.ref.png                               |binary
 test/reference/mask.pdf.rgb24.ref.png                                |binary
 test/reference/mask.rgb24.ref.png                                    |binary
 test/reference/mesh-pattern-conical.pdf.ref.png                      |binary
 test/reference/mesh-pattern-conical.ps.ref.png                       |binary
 test/reference/mesh-pattern-control-points.pdf.ref.png               |binary
 test/reference/mesh-pattern-control-points.ps.ref.png                |binary
 test/reference/mesh-pattern-fold.pdf.ref.png                         |binary
 test/reference/mesh-pattern-fold.ps.ref.png                          |binary
 test/reference/mesh-pattern-overlap.pdf.ref.png                      |binary
 test/reference/mesh-pattern-overlap.ps.ref.png                       |binary
 test/reference/mesh-pattern-transformed.pdf.ref.png                  |binary
 test/reference/mesh-pattern-transformed.ps.ref.png                   |binary
 test/reference/mesh-pattern.pdf.ref.png                              |binary
 test/reference/mesh-pattern.ps.ref.png                               |binary
 test/reference/new-sub-path.pdf.argb32.ref.png                       |binary
 test/reference/new-sub-path.pdf.rgb24.ref.png                        |binary
 test/reference/nil-surface.ps.rgb24.ref.png                          |binary
 test/reference/operator-alpha-alpha.pdf.ref.png                      |binary
 test/reference/operator-alpha-alpha.ps.ref.png                       |binary
 test/reference/operator-clear.pdf.argb32.ref.png                     |binary
 test/reference/operator-clear.rgb24.ref.png                          |binary
 test/reference/operator-source.argb32.ref.png                        |binary
 test/reference/operator-source.rgb24.ref.png                         |binary
 test/reference/over-above-source.ps3.argb32.ref.png                  |binary
 test/reference/over-around-source.ps3.argb32.ref.png                 |binary
 test/reference/over-between-source.ps3.argb32.ref.png                |binary
 test/reference/overlapping-boxes.ps.argb32.ref.png                   |binary
 test/reference/overlapping-boxes.ps.rgb24.ref.png                    |binary
 test/reference/overlapping-glyphs.pdf.argb32.ref.png                 |binary
 test/reference/overlapping-glyphs.pdf.rgb24.ref.png                  |binary
 test/reference/overlapping-glyphs.ps.rgb24.ref.png                   |binary
 test/reference/paint-source-alpha.pdf.ref.png                        |binary
 test/reference/paint-with-alpha-clip-mask.pdf.ref.png                |binary
 test/reference/paint-with-alpha-clip.pdf.ref.png                     |binary
 test/reference/paint-with-alpha-solid-clip.pdf.ref.png               |binary
 test/reference/paint-with-alpha.pdf.ref.png                          |binary
 test/reference/partial-clip-text-bottom.ps.ref.png                   |binary
 test/reference/partial-clip-text-left.ps.ref.png                     |binary
 test/reference/partial-clip-text-right.ps.ref.png                    |binary
 test/reference/partial-clip-text-top.ps.ref.png                      |binary
 test/reference/pass-through.ps.rgb24.ref.png                         |binary
 test/reference/path-stroke-twice.pdf.ref.png                         |binary
 test/reference/pdf-surface-source.ps.argb32.ref.png                  |binary
 test/reference/pdf-surface-source.ps.rgb24.ref.png                   |binary
 test/reference/pixman-downscale-best-24.pdf.ref.png                  |binary
 test/reference/pixman-downscale-best-24.ps.ref.png                   |binary
 test/reference/pixman-downscale-best-24.ref.png                      |binary
 test/reference/pixman-downscale-best-96.ps.ref.png                   |binary
 test/reference/pixman-downscale-bilinear-24.ps.ref.png               |binary
 test/reference/pixman-downscale-bilinear-96.ps.ref.png               |binary
 test/reference/pixman-downscale-good-24.ps.ref.png                   |binary
 test/reference/pixman-downscale-good-96.ps.ref.png                   |binary
 test/reference/pixman-rotate.ps.argb32.ref.png                       |binary
 test/reference/pixman-rotate.ps.rgb24.ref.png                        |binary
 test/reference/ps-surface-source.ps.argb32.ref.png                   |binary
 test/reference/ps-surface-source.ps.rgb24.ref.png                    |binary
 test/reference/pthread-show-text.pdf.ref.png                         |binary
 test/reference/pthread-show-text.ps.ref.png                          |binary
 test/reference/radial-gradient-extend.pdf.ref.png                    |binary
 test/reference/random-clip.pdf.argb32.ref.png                        |binary
 test/reference/random-clip.pdf.rgb24.ref.png                         |binary
 test/reference/random-clip.ps.argb32.ref.png                         |binary
 test/reference/random-clip.ps.rgb24.ref.png                          |binary
 test/reference/random-clip.ref.png                                   |binary
 test/reference/random-intersections-curves-eo.pdf.argb32.ref.png     |binary
 test/reference/random-intersections-curves-eo.pdf.rgb24.ref.png      |binary
 test/reference/random-intersections-curves-nz.pdf.argb32.ref.png     |binary
 test/reference/random-intersections-curves-nz.pdf.rgb24.ref.png      |binary
 test/reference/random-intersections-eo.pdf.ref.png                   |binary
 test/reference/random-intersections-eo.ref.png                       |binary
 test/reference/random-intersections-nonzero.pdf.ref.png              |binary
 test/reference/random-intersections-nonzero.ref.png                  |binary
 test/reference/record-extend-none.ps.ref.png                         |binary
 test/reference/record-extend-pad.ps.ref.png                          |binary
 test/reference/record-extend-reflect.ps.ref.png                      |binary
 test/reference/record-extend-repeat.ps.ref.png                       |binary
 test/reference/record-fill-alpha.pdf.ref.png                         |binary
 test/reference/record-fill-alpha.ref.png                             |binary
 test/reference/record-mesh.pdf.argb32.ref.png                        |binary
 test/reference/record-mesh.pdf.rgb24.ref.png                         |binary
 test/reference/record-mesh.ps.ref.png                                |binary
 test/reference/record-mesh.ref.png                                   |binary
 test/reference/record-neg-extents-bounded.pdf.argb32.ref.png         |binary
 test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png          |binary
 test/reference/record-neg-extents-bounded.ref.png                    |binary
 test/reference/record-neg-extents-unbounded.pdf.argb32.ref.png       |binary
 test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png        |binary
 test/reference/record-neg-extents-unbounded.ref.png                  |binary
 test/reference/record-paint-alpha-clip-mask.pdf.argb32.ref.png       |binary
 test/reference/record-paint-alpha-clip-mask.pdf.rgb24.ref.png        |binary
 test/reference/record-paint-alpha-clip-mask.ref.png                  |binary
 test/reference/record-paint-alpha-clip.pdf.argb32.ref.png            |binary
 test/reference/record-paint-alpha-clip.pdf.rgb24.ref.png             |binary
 test/reference/record-paint-alpha-solid-clip.pdf.ref.png             |binary
 test/reference/record-replay-extend-none.pdf.argb32.ref.png          |binary
 test/reference/record-replay-extend-none.pdf.rgb24.ref.png           |binary
 test/reference/record-replay-extend-none.ps.argb32.ref.png           |binary
 test/reference/record-replay-extend-none.ps.rgb24.ref.png            |binary
 test/reference/record-replay-extend-none.ref.png                     |binary
 test/reference/record-replay-extend-pad.pdf.argb32.ref.png           |binary
 test/reference/record-replay-extend-pad.ps.rgb24.ref.png             |binary
 test/reference/record-replay-extend-pad.ref.png                      |binary
 test/reference/record-replay-extend-reflect.pdf.argb32.ref.png       |binary
 test/reference/record-replay-extend-reflect.pdf.rgb24.ref.png        |binary
 test/reference/record-replay-extend-reflect.ps.argb32.ref.png        |binary
 test/reference/record-replay-extend-reflect.ref.png                  |binary
 test/reference/record-replay-extend-repeat.pdf.argb32.ref.png        |binary
 test/reference/record-replay-extend-repeat.pdf.rgb24.ref.png         |binary
 test/reference/record-replay-extend-repeat.ps.argb32.ref.png         |binary
 test/reference/record-replay-extend-repeat.ps.rgb24.ref.png          |binary
 test/reference/record-replay-extend-repeat.ref.png                   |binary
 test/reference/record-select-font-face.pdf.argb32.ref.png            |binary
 test/reference/record-select-font-face.pdf.rgb24.ref.png             |binary
 test/reference/record-select-font-face.ps.ref.png                    |binary
 test/reference/record-select-font-face.ref.png                       |binary
 test/reference/record-self-intersecting.pdf.rgb24.ref.png            |binary
 test/reference/record-self-intersecting.ps.ref.png                   |binary
 test/reference/record-text-transform.pdf.argb32.ref.png              |binary
 test/reference/record-text-transform.pdf.rgb24.ref.png               |binary
 test/reference/record-text-transform.ps.argb32.ref.png               |binary
 test/reference/record-text-transform.ps.rgb24.ref.png                |binary
 test/reference/record-text-transform.ref.png                         |binary
 test/reference/record1414x-fill-alpha.pdf.argb32.ref.png             |binary
 test/reference/record1414x-fill-alpha.pdf.rgb24.ref.png              |binary
 test/reference/record1414x-fill-alpha.ps.ref.png                     |binary
 test/reference/record1414x-fill-alpha.ref.png                        |binary
 test/reference/record1414x-paint-alpha-clip-mask.pdf.argb32.ref.png  |binary
 test/reference/record1414x-paint-alpha-clip-mask.pdf.rgb24.ref.png   |binary
 test/reference/record1414x-paint-alpha-clip-mask.ps.ref.png          |binary
 test/reference/record1414x-paint-alpha-clip-mask.ref.png             |binary
 test/reference/record1414x-paint-alpha-clip.pdf.argb32.ref.png       |binary
 test/reference/record1414x-paint-alpha-clip.pdf.rgb24.ref.png        |binary
 test/reference/record1414x-paint-alpha-clip.ps.ref.png               |binary
 test/reference/record1414x-paint-alpha-solid-clip.pdf.argb32.ref.png |binary
 test/reference/record1414x-paint-alpha-solid-clip.pdf.rgb24.ref.png  |binary
 test/reference/record1414x-paint-alpha-solid-clip.ps.ref.png         |binary
 test/reference/record1414x-paint-alpha.pdf.argb32.ref.png            |binary
 test/reference/record1414x-paint-alpha.pdf.rgb24.ref.png             |binary
 test/reference/record1414x-paint-alpha.ps.ref.png                    |binary
 test/reference/record1414x-select-font-face.pdf.argb32.ref.png       |binary
 test/reference/record1414x-select-font-face.pdf.rgb24.ref.png        |binary
 test/reference/record1414x-select-font-face.ps.argb32.ref.png        |binary
 test/reference/record1414x-select-font-face.ps.rgb24.ref.png         |binary
 test/reference/record1414x-select-font-face.ref.png                  |binary
 test/reference/record1414x-self-intersecting.pdf.argb32.ref.png      |binary
 test/reference/record1414x-self-intersecting.pdf.rgb24.ref.png       |binary
 test/reference/record1414x-self-intersecting.ps.argb32.ref.png       |binary
 test/reference/record1414x-self-intersecting.ps.rgb24.ref.png        |binary
 test/reference/record1414x-text-transform.pdf.argb32.ref.png         |binary
 test/reference/record1414x-text-transform.pdf.rgb24.ref.png          |binary
 test/reference/record1414x-text-transform.ps.ref.png                 |binary
 test/reference/record1414x-text-transform.ref.png                    |binary
 test/reference/record2x-fill-alpha.pdf.argb32.ref.png                |binary
 test/reference/record2x-fill-alpha.pdf.rgb24.ref.png                 |binary
 test/reference/record2x-fill-alpha.ps.ref.png                        |binary
 test/reference/record2x-fill-alpha.ref.png                           |binary
 test/reference/record2x-paint-alpha-clip-mask.pdf.argb32.ref.png     |binary
 test/reference/record2x-paint-alpha-clip-mask.pdf.rgb24.ref.png      |binary
 test/reference/record2x-paint-alpha-clip-mask.ps.ref.png             |binary
 test/reference/record2x-paint-alpha-clip-mask.ref.png                |binary
 test/reference/record2x-paint-alpha-clip.pdf.argb32.ref.png          |binary
 test/reference/record2x-paint-alpha-clip.pdf.rgb24.ref.png           |binary
 test/reference/record2x-paint-alpha-solid-clip.pdf.argb32.ref.png    |binary
 test/reference/record2x-paint-alpha-solid-clip.pdf.rgb24.ref.png     |binary
 test/reference/record2x-paint-alpha.pdf.argb32.ref.png               |binary
 test/reference/record2x-paint-alpha.pdf.rgb24.ref.png                |binary
 test/reference/record2x-select-font-face.pdf.rgb24.ref.png           |binary
 test/reference/record2x-select-font-face.ps.ref.png                  |binary
 test/reference/record2x-select-font-face.ref.png                     |binary
 test/reference/record2x-text-transform.pdf.argb32.ref.png            |binary
 test/reference/record2x-text-transform.pdf.rgb24.ref.png             |binary
 test/reference/record2x-text-transform.ps.ref.png                    |binary
 test/reference/record2x-text-transform.ref.png                       |binary
 test/reference/record90-fill-alpha.pdf.ref.png                       |binary
 test/reference/record90-fill-alpha.pdf.rgb24.ref.png                 |binary
 test/reference/record90-fill-alpha.ref.png                           |binary
 test/reference/record90-paint-alpha-clip-mask.pdf.argb32.ref.png     |binary
 test/reference/record90-paint-alpha-clip-mask.pdf.rgb24.ref.png      |binary
 test/reference/record90-paint-alpha-clip.pdf.argb32.ref.png          |binary
 test/reference/record90-paint-alpha-clip.pdf.rgb24.ref.png           |binary
 test/reference/record90-paint-alpha-clip.ref.png                     |binary
 test/reference/record90-paint-alpha-solid-clip.pdf.argb32.ref.png    |binary
 test/reference/record90-paint-alpha-solid-clip.pdf.rgb24.ref.png     |binary
 test/reference/record90-paint-alpha.ps.ref.png                       |binary
 test/reference/record90-select-font-face.pdf.rgb24.ref.png           |binary
 test/reference/record90-select-font-face.ps.ref.png                  |binary
 test/reference/record90-select-font-face.ref.png                     |binary
 test/reference/record90-self-intersecting.pdf.rgb24.ref.png          |binary
 test/reference/record90-self-intersecting.ps.ref.png                 |binary
 test/reference/record90-self-intersecting.ref.png                    |binary
 test/reference/record90-text-transform.pdf.rgb24.ref.png             |binary
 test/reference/record90-text-transform.ps.ref.png                    |binary
 test/reference/record90-text-transform.ref.png                       |binary
 test/reference/recordflip-fill-alpha.ref.png                         |binary
 test/reference/recordflip-paint-alpha-clip-mask.pdf.rgb24.ref.png    |binary
 test/reference/recordflip-paint-alpha-clip-mask.ref.png              |binary
 test/reference/recordflip-paint-alpha-clip.pdf.rgb24.ref.png         |binary
 test/reference/recordflip-select-font-face.pdf.rgb24.ref.png         |binary
 test/reference/recordflip-select-font-face.ps.argb32.ref.png         |binary
 test/reference/recordflip-select-font-face.ps.rgb24.ref.png          |binary
 test/reference/recordflip-select-font-face.ref.png                   |binary
 test/reference/recordflip-self-intersecting.pdf.rgb24.ref.png        |binary
 test/reference/recordflip-self-intersecting.ps.ref.png               |binary
 test/reference/recordflip-text-transform.pdf.rgb24.ref.png           |binary
 test/reference/recordflip-text-transform.ps.argb32.ref.png           |binary
 test/reference/recordflip-text-transform.ps.rgb24.ref.png            |binary
 test/reference/recordflip-text-transform.ref.png                     |binary
 test/reference/recordflip-whole-fill-alpha.ref.png                   |binary
 test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png        |binary
 test/reference/recordflip-whole-select-font-face.ref.png             |binary
 test/reference/recordflip-whole-text-transform.ref.png               |binary
 test/reference/recording-surface-extend-none.pdf.argb32.ref.png      |binary
 test/reference/recording-surface-extend-none.pdf.rgb24.ref.png       |binary
 test/reference/recording-surface-extend-none.ps.argb32.ref.png       |binary
 test/reference/recording-surface-extend-none.ps.rgb24.ref.png        |binary
 test/reference/recording-surface-extend-reflect.pdf.argb32.ref.png   |binary
 test/reference/recording-surface-extend-reflect.pdf.rgb24.ref.png    |binary
 test/reference/recording-surface-extend-reflect.ps.argb32.ref.png    |binary
 test/reference/recording-surface-extend-reflect.ps.rgb24.ref.png     |binary
 test/reference/recording-surface-extend-repeat.pdf.argb32.ref.png    |binary
 test/reference/recording-surface-extend-repeat.pdf.rgb24.ref.png     |binary
 test/reference/recording-surface-extend-repeat.ps.argb32.ref.png     |binary
 test/reference/recording-surface-extend-repeat.ps.rgb24.ref.png      |binary
 test/reference/recording-surface-over.pdf.argb32.ref.png             |binary
 test/reference/recording-surface-over.pdf.rgb24.ref.png              |binary
 test/reference/recording-surface-over.ps.argb32.ref.png              |binary
 test/reference/recording-surface-over.ps.rgb24.ref.png               |binary
 test/reference/recording-surface-source.pdf.argb32.ref.png           |binary
 test/reference/recording-surface-source.pdf.rgb24.ref.png            |binary
 test/reference/recording-surface-source.ps.argb32.ref.png            |binary
 test/reference/recording-surface-source.ps.rgb24.ref.png             |binary
 test/reference/rectilinear-dash-scale-unaligned.pdf.ref.png          |binary
 test/reference/rectilinear-dash-scale-unaligned.ps.ref.png           |binary
 test/reference/reflected-stroke.pdf.ref.png                          |binary
 test/reference/rotate-clip-image-surface-paint.pdf.argb32.png        |binary
 test/reference/rotate-clip-image-surface-paint.pdf.rgb24.png         |binary
 test/reference/rotate-clip-image-surface-paint.ps.argb32.png         |binary
 test/reference/rotated-clip.pdf.ref.png                              |binary
 test/reference/rotated-clip.ps.argb32.png                            |binary
 test/reference/rotated-clip.ps.argb32.ref.png                        |binary
 test/reference/rotated-clip.ps.rgb24.ref.png                         |binary
 test/reference/scale-offset-image.pdf.ref.png                        |binary
 test/reference/scale-offset-image.ref.png                            |binary
 test/reference/scale-offset-similar.pdf.ref.png                      |binary
 test/reference/scale-offset-similar.ref.png                          |binary
 test/reference/shape-sierpinski.pdf.ref.png                          |binary
 test/reference/simple-edge.ref.png                                   |binary
 test/reference/smask-fill.pdf.ref.png                                |binary
 test/reference/smask-image-mask.pdf.ref.png                          |binary
 test/reference/smask-mask.pdf.ref.png                                |binary
 test/reference/smask-paint.pdf.ref.png                               |binary
 test/reference/smask-stroke.pdf.ref.png                              |binary
 test/reference/smask-text.pdf.ref.png                                |binary
 test/reference/smask-text.ps.ref.png                                 |binary
 test/reference/smask.pdf.ref.png                                     |binary
 test/reference/smask.ps3.ref.png                                     |binary
 test/reference/spline-decomposition.pdf.ref.png                      |binary
 test/reference/spline-decomposition.ps.ref.png                       |binary
 test/reference/stroke-clipped.ps.ref.png                             |binary
 test/reference/stroke-ctm-caps.pdf.ref.png                           |binary
 test/reference/stroke-image.pdf.ref.png                              |binary
 test/reference/stroke-image.ps.ref.png                               |binary
 test/reference/stroke-pattern.pdf.argb32.ref.png                     |binary
 test/reference/stroke-pattern.pdf.rgb24.ref.png                      |binary
 test/reference/surface-pattern-big-scale-down.ps.ref.png             |binary
 test/reference/surface-pattern-scale-down-extend-none.ps.ref.png     |binary
 test/reference/surface-pattern-scale-down.pdf.ref.png                |binary
 test/reference/surface-pattern-scale-down.ps.ref.png                 |binary
 test/reference/surface-pattern-scale-down.ref.png                    |binary
 test/reference/surface-pattern-scale-up.pdf.ref.png                  |binary
 test/reference/surface-pattern-scale-up.ps.ref.png                   |binary
 test/reference/surface-pattern.pdf.ref.png                           |binary
 test/reference/surface-pattern.ps.ref.png                            |binary
 test/reference/svg-surface-source.ps.rgb24.ref.png                   |binary
 test/reference/text-glyph-range.pdf.ref.png                          |binary
 test/reference/text-glyph-range.ps.ref.png                           |binary
 test/reference/text-pattern.pdf.argb32.ref.png                       |binary
 test/reference/text-pattern.pdf.rgb24.ref.png                        |binary
 test/reference/text-pattern.ps3.argb32.ref.png                       |binary
 test/reference/text-pattern.ps3.rgb24.ref.png                        |binary
 test/reference/text-rotate.pdf.ref.png                               |binary
 test/reference/text-rotate.ps.ref.png                                |binary
 test/reference/text-rotate.ref.png                                   |binary
 test/reference/text-transform.pdf.argb32.ref.png                     |binary
 test/reference/text-transform.pdf.rgb24.ref.png                      |binary
 test/reference/text-transform.ps.ref.png                             |binary
 test/reference/tiger.pdf.ref.png                                     |binary
 test/reference/tiger.ps.ref.png                                      |binary
 test/reference/tiger.ref.png                                         |binary
 test/reference/tighten-bounds.pdf.ref.png                            |binary
 test/reference/tighten-bounds.ps.ref.png                             |binary
 test/reference/transforms.pdf.ref.png                                |binary
 test/reference/trap-clip.argb32.ref.png                              |binary
 test/reference/trap-clip.pdf.argb32.ref.png                          |binary
 test/reference/trap-clip.pdf.rgb24.ref.png                           |binary
 test/reference/trap-clip.rgb24.ref.png                               |binary
 test/reference/twin.pdf.argb32.ref.png                               |binary
 test/reference/twin.pdf.rgb24.ref.png                                |binary
 test/reference/twin.ps.ref.png                                       |binary
 test/reference/unbounded-operator.pdf.argb32.ref.png                 |binary
 test/reference/unbounded-operator.pdf.rgb24.ref.png                  |binary
 test/reference/unbounded-operator.rgb24.ref.png                      |binary
 test/reference/unclosed-strokes.pdf.ref.png                          |binary
 test/reference/unclosed-strokes.ps.ref.png                           |binary
 test/reference/user-font-proxy.pdf.argb32.ref.png                    |binary
 test/reference/user-font-proxy.ps.ref.png                            |binary
 test/reference/user-font-rescale.pdf.rgb24.ref.png                   |binary
 test/reference/user-font-rescale.ps.ref.png                          |binary
 test/reference/user-font.pdf.ref.png                                 |binary
 test/reference/user-font.ps.ref.png                                  |binary
 test/reference/world-map-fill.pdf.argb32.ref.png                     |binary
 test/reference/world-map-fill.pdf.rgb24.ref.png                      |binary
 test/reference/world-map-fill.ps.argb32.ref.png                      |binary
 test/reference/world-map-fill.ps.rgb24.ref.png                       |binary
 test/reference/world-map-stroke.pdf.argb32.ref.png                   |binary
 test/reference/world-map-stroke.pdf.rgb24.ref.png                    |binary
 test/reference/world-map-stroke.ps.argb32.ref.png                    |binary
 test/reference/world-map-stroke.ps.rgb24.ref.png                     |binary
 test/reference/world-map.pdf.argb32.ref.png                          |binary
 test/reference/world-map.pdf.rgb24.ref.png                           |binary
 test/reference/world-map.ps.argb32.ref.png                           |binary
 test/reference/world-map.ps.rgb24.ref.png                            |binary
 516 files changed, 1512 insertions(+), 607 deletions(-)

New commits:
commit 113ba5f3fa48f9f826b86ff9198ce0d35144eea4
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Jun 5 20:34:44 2016 +0930

    Update ref images
    
    ref images were creating using Debian Jessie 64-bit and latest poppler.

diff --git a/test/README b/test/README
index f143394..8cf3ddb 100644
--- a/test/README
+++ b/test/README
@@ -109,10 +109,10 @@ Here are some of the relevant details:
 
   * Your system must have a copy of the DejaVu font, the sha1sum of
     the version used are listed in [...].  These are
-      "DejaVu Sans" (DejaVuSans.ttf) [1cd336329f45f241002ded61893d91e3acd04436];
-      "DejaVu Sans Mono" (DejaVuSansMono.ttf) [0458c0f0fb57f3eb8ced62f26fe7c5ed4e6a9a68];
-      "DejaVu Serif" (DejaVuSerif.ttf) [93502d0d0445d1fe1c9f51e51b3e0169266346ce];
-      [the DejaVu fonts can be installed from the ttf-dejavu 2.33-2 Debian package]
+      "DejaVu Sans" (DejaVuSans.ttf) [e9831ee4fd2e1d0ac54508a548c6a449545eba3f];
+      "DejaVu Sans Mono" (DejaVuSansMono.ttf) [25d854fbd0450a372615a26a8ef9a1024bd3efc6];
+      "DejaVu Serif" (DejaVuSerif.ttf) [78a81850dc7883969042cf3d6dfd18eea7e43e2f];
+      [the DejaVu fonts can be installed from the fonts-dejavu-core 2.34-1 Debian package]
     and also
       "Nimbus Sans L" (n019003l.pfb)
       [which can be found in the gsfonts Debian package].
@@ -130,7 +130,7 @@ Here are some of the relevant details:
     the fixes you will need to avoid false negatives from the test
     suite.
 
-  * To test the ps backend, you will need ghostscript version 9.04.
+  * To test the ps backend, you will need ghostscript version 9.06.
 
   * Testing the xlib backend is problematic since many X server
     drivers have bugs that are exercised by the test suite. (Or, if
diff --git a/test/reference/arc-direction.pdf.ref.png b/test/reference/arc-direction.pdf.ref.png
new file mode 100644
index 0000000..7b14d71
Binary files /dev/null and b/test/reference/arc-direction.pdf.ref.png differ
diff --git a/test/reference/arc-direction.ref.png b/test/reference/arc-direction.ref.png
index 05ff410..7b14d71 100644
Binary files a/test/reference/arc-direction.ref.png and b/test/reference/arc-direction.ref.png differ
diff --git a/test/reference/arc-looping-dash.pdf.ref.png b/test/reference/arc-looping-dash.pdf.ref.png
new file mode 100644
index 0000000..5195b07
Binary files /dev/null and b/test/reference/arc-looping-dash.pdf.ref.png differ
diff --git a/test/reference/big-empty-box.ps.rgb24.ref.png b/test/reference/big-empty-box.ps.rgb24.ref.png
new file mode 100644
index 0000000..6c2ca32
Binary files /dev/null and b/test/reference/big-empty-box.ps.rgb24.ref.png differ
diff --git a/test/reference/big-empty-triangle.ps.rgb24.ref.png b/test/reference/big-empty-triangle.ps.rgb24.ref.png
new file mode 100644
index 0000000..6c2ca32
Binary files /dev/null and b/test/reference/big-empty-triangle.ps.rgb24.ref.png differ
diff --git a/test/reference/big-little-box.ps.rgb24.ref.png b/test/reference/big-little-box.ps.rgb24.ref.png
new file mode 100644
index 0000000..c069d6f
Binary files /dev/null and b/test/reference/big-little-box.ps.rgb24.ref.png differ
diff --git a/test/reference/bitmap-font.ps.rgb24.ref.png b/test/reference/bitmap-font.ps.rgb24.ref.png
new file mode 100644
index 0000000..285d742
Binary files /dev/null and b/test/reference/bitmap-font.ps.rgb24.ref.png differ
diff --git a/test/reference/bug-51910.pdf.ref.png b/test/reference/bug-51910.pdf.ref.png
new file mode 100644
index 0000000..df26fe2
Binary files /dev/null and b/test/reference/bug-51910.pdf.ref.png differ
diff --git a/test/reference/bug-51910.ps.ref.png b/test/reference/bug-51910.ps.ref.png
new file mode 100644
index 0000000..dcac03f
Binary files /dev/null and b/test/reference/bug-51910.ps.ref.png differ
diff --git a/test/reference/bug-84115.pdf.ref.png b/test/reference/bug-84115.pdf.ref.png
new file mode 100644
index 0000000..95b5058
Binary files /dev/null and b/test/reference/bug-84115.pdf.ref.png differ
diff --git a/test/reference/bug-84115.ps.arg32.ref.png b/test/reference/bug-84115.ps.arg32.ref.png
new file mode 100644
index 0000000..2c2b918
Binary files /dev/null and b/test/reference/bug-84115.ps.arg32.ref.png differ
diff --git a/test/reference/bug-84115.ps.argb32.ref.png b/test/reference/bug-84115.ps.argb32.ref.png
new file mode 100644
index 0000000..2c2b918
Binary files /dev/null and b/test/reference/bug-84115.ps.argb32.ref.png differ
diff --git a/test/reference/bug-84115.ps.rgb24.ref.png b/test/reference/bug-84115.ps.rgb24.ref.png
new file mode 100644
index 0000000..2c2b918
Binary files /dev/null and b/test/reference/bug-84115.ps.rgb24.ref.png differ
diff --git a/test/reference/bug-bo-ricotz.argb32.ref.png b/test/reference/bug-bo-ricotz.argb32.ref.png
new file mode 100644
index 0000000..1f73469
Binary files /dev/null and b/test/reference/bug-bo-ricotz.argb32.ref.png differ
diff --git a/test/reference/bug-bo-ricotz.pdf.rgb24.ref.png b/test/reference/bug-bo-ricotz.pdf.rgb24.ref.png
new file mode 100644
index 0000000..1f73469
Binary files /dev/null and b/test/reference/bug-bo-ricotz.pdf.rgb24.ref.png differ
diff --git a/test/reference/bug-bo-ricotz.ps.ref.png b/test/reference/bug-bo-ricotz.ps.ref.png
new file mode 100644
index 0000000..ce308e2
Binary files /dev/null and b/test/reference/bug-bo-ricotz.ps.ref.png differ
diff --git a/test/reference/bug-extents.pdf.ref.png b/test/reference/bug-extents.pdf.ref.png
new file mode 100644
index 0000000..c3d02d7
Binary files /dev/null and b/test/reference/bug-extents.pdf.ref.png differ
diff --git a/test/reference/bug-source-cu.pdf.argb32.ref.png b/test/reference/bug-source-cu.pdf.argb32.ref.png
new file mode 100644
index 0000000..084d197
Binary files /dev/null and b/test/reference/bug-source-cu.pdf.argb32.ref.png differ
diff --git a/test/reference/bug-source-cu.pdf.rgb24.ref.png b/test/reference/bug-source-cu.pdf.rgb24.ref.png
new file mode 100644
index 0000000..0b11626
Binary files /dev/null and b/test/reference/bug-source-cu.pdf.rgb24.ref.png differ
diff --git a/test/reference/bug-source-cu.ps.argb32.ref.png b/test/reference/bug-source-cu.ps.argb32.ref.png
new file mode 100644
index 0000000..678a17d
Binary files /dev/null and b/test/reference/bug-source-cu.ps.argb32.ref.png differ
diff --git a/test/reference/bug-source-cu.ps.rgb24.ref.png b/test/reference/bug-source-cu.ps.rgb24.ref.png
new file mode 100644
index 0000000..678a17d
Binary files /dev/null and b/test/reference/bug-source-cu.ps.rgb24.ref.png differ
diff --git a/test/reference/bug-spline.ps.ref.png b/test/reference/bug-spline.ps.ref.png
new file mode 100644
index 0000000..5eb7886
Binary files /dev/null and b/test/reference/bug-spline.ps.ref.png differ
diff --git a/test/reference/caps-05.pdf.ref.png b/test/reference/caps-05.pdf.ref.png
new file mode 100644
index 0000000..cec500a
Binary files /dev/null and b/test/reference/caps-05.pdf.ref.png differ
diff --git a/test/reference/caps-05.ps.ref.png b/test/reference/caps-05.ps.ref.png
new file mode 100644
index 0000000..48f84ae
Binary files /dev/null and b/test/reference/caps-05.ps.ref.png differ
diff --git a/test/reference/caps-1.pdf.ref.png b/test/reference/caps-1.pdf.ref.png
new file mode 100644
index 0000000..cec500a
Binary files /dev/null and b/test/reference/caps-1.pdf.ref.png differ
diff --git a/test/reference/caps-1.ps.ref.png b/test/reference/caps-1.ps.ref.png
new file mode 100644
index 0000000..9fce748
Binary files /dev/null and b/test/reference/caps-1.ps.ref.png differ
diff --git a/test/reference/caps-2.pdf.ref.png b/test/reference/caps-2.pdf.ref.png
new file mode 100644
index 0000000..43821fe
Binary files /dev/null and b/test/reference/caps-2.pdf.ref.png differ
diff --git a/test/reference/caps-2.ps.ref.png b/test/reference/caps-2.ps.ref.png
new file mode 100644
index 0000000..2bda07b
Binary files /dev/null and b/test/reference/caps-2.ps.ref.png differ
diff --git a/test/reference/caps-joins-05.pdf.ref.png b/test/reference/caps-joins-05.pdf.ref.png
new file mode 100644
index 0000000..fbe8391
Binary files /dev/null and b/test/reference/caps-joins-05.pdf.ref.png differ
diff --git a/test/reference/caps-joins-05.ps.ref.png b/test/reference/caps-joins-05.ps.ref.png
new file mode 100644
index 0000000..e767c40
Binary files /dev/null and b/test/reference/caps-joins-05.ps.ref.png differ
diff --git a/test/reference/caps-joins-1.pdf.ref.png b/test/reference/caps-joins-1.pdf.ref.png
new file mode 100644
index 0000000..fbe8391
Binary files /dev/null and b/test/reference/caps-joins-1.pdf.ref.png differ
diff --git a/test/reference/caps-joins-1.ps.ref.png b/test/reference/caps-joins-1.ps.ref.png
new file mode 100644
index 0000000..ef5ed37
Binary files /dev/null and b/test/reference/caps-joins-1.ps.ref.png differ
diff --git a/test/reference/caps-joins-2.pdf.ref.png b/test/reference/caps-joins-2.pdf.ref.png
new file mode 100644
index 0000000..70faca9
Binary files /dev/null and b/test/reference/caps-joins-2.pdf.ref.png differ
diff --git a/test/reference/caps-joins-2.ps.ref.png b/test/reference/caps-joins-2.ps.ref.png
new file mode 100644
index 0000000..da7e3ee
Binary files /dev/null and b/test/reference/caps-joins-2.ps.ref.png differ
diff --git a/test/reference/caps-joins-curve.pdf.ref.png b/test/reference/caps-joins-curve.pdf.ref.png
new file mode 100644
index 0000000..17d6b45
Binary files /dev/null and b/test/reference/caps-joins-curve.pdf.ref.png differ
diff --git a/test/reference/caps-joins.pdf.ref.png b/test/reference/caps-joins.pdf.ref.png
new file mode 100644
index 0000000..1faf366
Binary files /dev/null and b/test/reference/caps-joins.pdf.ref.png differ
diff --git a/test/reference/caps-sub-paths.pdf.ref.png b/test/reference/caps-sub-paths.pdf.ref.png
new file mode 100644
index 0000000..8a58160
Binary files /dev/null and b/test/reference/caps-sub-paths.pdf.ref.png differ
diff --git a/test/reference/caps-tails-curve.pdf.ref.png b/test/reference/caps-tails-curve.pdf.ref.png
new file mode 100644
index 0000000..fa7e21f
Binary files /dev/null and b/test/reference/caps-tails-curve.pdf.ref.png differ
diff --git a/test/reference/caps.pdf.ref.png b/test/reference/caps.pdf.ref.png
new file mode 100644
index 0000000..8ec2503
Binary files /dev/null and b/test/reference/caps.pdf.ref.png differ
diff --git a/test/reference/checkerboard.pdf.ref.png b/test/reference/checkerboard.pdf.ref.png
new file mode 100644
index 0000000..3f0391c
Binary files /dev/null and b/test/reference/checkerboard.pdf.ref.png differ
diff --git a/test/reference/clip-complex-bug61592.pdf.ref.png b/test/reference/clip-complex-bug61592.pdf.ref.png
new file mode 100644
index 0000000..02abd0e
Binary files /dev/null and b/test/reference/clip-complex-bug61592.pdf.ref.png differ
diff --git a/test/reference/clip-complex-bug61592.ps.ref.png b/test/reference/clip-complex-bug61592.ps.ref.png
new file mode 100644
index 0000000..b86fb18
Binary files /dev/null and b/test/reference/clip-complex-bug61592.ps.ref.png differ
diff --git a/test/reference/clip-device-offset.ps.rgb24.ref.png b/test/reference/clip-device-offset.ps.rgb24.ref.png
new file mode 100644
index 0000000..2419384
Binary files /dev/null and b/test/reference/clip-device-offset.ps.rgb24.ref.png differ
diff --git a/test/reference/clip-disjoint-quad.pdf.ref.png b/test/reference/clip-disjoint-quad.pdf.ref.png
new file mode 100644
index 0000000..d24d910
Binary files /dev/null and b/test/reference/clip-disjoint-quad.pdf.ref.png differ
diff --git a/test/reference/clip-disjoint-quad.ps.ref.png b/test/reference/clip-disjoint-quad.ps.ref.png
new file mode 100644
index 0000000..5de2fcf
Binary files /dev/null and b/test/reference/clip-disjoint-quad.ps.ref.png differ
diff --git a/test/reference/clip-disjoint.ps.ref.png b/test/reference/clip-disjoint.ps.ref.png
index 5410d0a..17b867f 100644
Binary files a/test/reference/clip-disjoint.ps.ref.png and b/test/reference/clip-disjoint.ps.ref.png differ
diff --git a/test/reference/clip-fill-no-op.ps.ref.png b/test/reference/clip-fill-no-op.ps.ref.png
new file mode 100644
index 0000000..b51490d
Binary files /dev/null and b/test/reference/clip-fill-no-op.ps.ref.png differ
diff --git a/test/reference/clip-fill-rule-pixel-aligned.ps.argb32.ref.png b/test/reference/clip-fill-rule-pixel-aligned.ps.argb32.ref.png
new file mode 100644
index 0000000..9a814b5
Binary files /dev/null and b/test/reference/clip-fill-rule-pixel-aligned.ps.argb32.ref.png differ
diff --git a/test/reference/clip-fill-rule-pixel-aligned.ps.rgb24.ref.png b/test/reference/clip-fill-rule-pixel-aligned.ps.rgb24.ref.png
new file mode 100644
index 0000000..0b4f068
Binary files /dev/null and b/test/reference/clip-fill-rule-pixel-aligned.ps.rgb24.ref.png differ
diff --git a/test/reference/clip-fill-rule.pdf.argb32.ref.png b/test/reference/clip-fill-rule.pdf.argb32.ref.png
index 0d9938e..d7e2f56 100644
Binary files a/test/reference/clip-fill-rule.pdf.argb32.ref.png and b/test/reference/clip-fill-rule.pdf.argb32.ref.png differ
diff --git a/test/reference/clip-fill-rule.pdf.rgb24.ref.png b/test/reference/clip-fill-rule.pdf.rgb24.ref.png
new file mode 100644
index 0000000..a7acc4f
Binary files /dev/null and b/test/reference/clip-fill-rule.pdf.rgb24.ref.png differ
diff --git a/test/reference/clip-fill-rule.rgb24.ref.png b/test/reference/clip-fill-rule.rgb24.ref.png
index e180fcc..a7acc4f 100644
Binary files a/test/reference/clip-fill-rule.rgb24.ref.png and b/test/reference/clip-fill-rule.rgb24.ref.png differ
diff --git a/test/reference/clip-fill.ps.ref.png b/test/reference/clip-fill.ps.ref.png
new file mode 100644
index 0000000..568d2f4
Binary files /dev/null and b/test/reference/clip-fill.ps.ref.png differ
diff --git a/test/reference/clip-fill.ps.xfail.png b/test/reference/clip-fill.ps.xfail.png
deleted file mode 100644
index d0aeaf1..0000000
Binary files a/test/reference/clip-fill.ps.xfail.png and /dev/null differ
diff --git a/test/reference/clip-image.pdf.ref.png b/test/reference/clip-image.pdf.ref.png
new file mode 100644
index 0000000..8893e0f
Binary files /dev/null and b/test/reference/clip-image.pdf.ref.png differ
diff --git a/test/reference/clip-intersect.ps.ref.png b/test/reference/clip-intersect.ps.ref.png
new file mode 100644
index 0000000..d4df386
Binary files /dev/null and b/test/reference/clip-intersect.ps.ref.png differ
diff --git a/test/reference/clip-operator.pdf.argb32.ref.png b/test/reference/clip-operator.pdf.argb32.ref.png
index 7f8c93e..48554f8 100644
Binary files a/test/reference/clip-operator.pdf.argb32.ref.png and b/test/reference/clip-operator.pdf.argb32.ref.png differ
diff --git a/test/reference/clip-operator.pdf.rgb24.ref.png b/test/reference/clip-operator.pdf.rgb24.ref.png
deleted file mode 100644
index fc4f431..0000000
Binary files a/test/reference/clip-operator.pdf.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/clip-operator.rgb24.ref.png b/test/reference/clip-operator.rgb24.ref.png
index 7e3a640..c369072 100644
Binary files a/test/reference/clip-operator.rgb24.ref.png and b/test/reference/clip-operator.rgb24.ref.png differ
diff --git a/test/reference/clip-push-group.pdf.ref.png b/test/reference/clip-push-group.pdf.ref.png
index 37b58c5..d6640fe 100644
Binary files a/test/reference/clip-push-group.pdf.ref.png and b/test/reference/clip-push-group.pdf.ref.png differ
diff --git a/test/reference/clip-rectilinear.ps.ref.png b/test/reference/clip-rectilinear.ps.ref.png
new file mode 100644
index 0000000..9478f86
Binary files /dev/null and b/test/reference/clip-rectilinear.ps.ref.png differ
diff --git a/test/reference/clip-rotate-image-surface-paint.pdf.argb32.ref.png b/test/reference/clip-rotate-image-surface-paint.pdf.argb32.ref.png
new file mode 100644
index 0000000..764a475
Binary files /dev/null and b/test/reference/clip-rotate-image-surface-paint.pdf.argb32.ref.png differ
diff --git a/test/reference/clip-rotate-image-surface-paint.pdf.rgb24.ref.png b/test/reference/clip-rotate-image-surface-paint.pdf.rgb24.ref.png
new file mode 100644
index 0000000..764a475
Binary files /dev/null and b/test/reference/clip-rotate-image-surface-paint.pdf.rgb24.ref.png differ
diff --git a/test/reference/clip-rotate-image-surface-paint.ps.ref.png b/test/reference/clip-rotate-image-surface-paint.ps.ref.png
new file mode 100644
index 0000000..7a52887
Binary files /dev/null and b/test/reference/clip-rotate-image-surface-paint.ps.ref.png differ
diff --git a/test/reference/clip-stroke-no-op.ps.ref.png b/test/reference/clip-stroke-no-op.ps.ref.png
new file mode 100644
index 0000000..b51490d
Binary files /dev/null and b/test/reference/clip-stroke-no-op.ps.ref.png differ
diff --git a/test/reference/clip-stroke-unbounded.argb32.ref.png b/test/reference/clip-stroke-unbounded.argb32.ref.png
index 7f603b7..51bc7c4 100644
Binary files a/test/reference/clip-stroke-unbounded.argb32.ref.png and b/test/reference/clip-stroke-unbounded.argb32.ref.png differ
diff --git a/test/reference/clip-stroke-unbounded.rgb24.ref.png b/test/reference/clip-stroke-unbounded.rgb24.ref.png
index 4a06c4b..c75ccbe 100644
Binary files a/test/reference/clip-stroke-unbounded.rgb24.ref.png and b/test/reference/clip-stroke-unbounded.rgb24.ref.png differ
diff --git a/test/reference/clip-stroke.ps.ref.png b/test/reference/clip-stroke.ps.ref.png
new file mode 100644
index 0000000..c08f333
Binary files /dev/null and b/test/reference/clip-stroke.ps.ref.png differ
diff --git a/test/reference/clip-stroke.ps.xfail.png b/test/reference/clip-stroke.ps.xfail.png
deleted file mode 100644
index cc67b08..0000000
Binary files a/test/reference/clip-stroke.ps.xfail.png and /dev/null differ
diff --git a/test/reference/clip-text.ps.ref.png b/test/reference/clip-text.ps.ref.png
new file mode 100644
index 0000000..86c6769
Binary files /dev/null and b/test/reference/clip-text.ps.ref.png differ
diff --git a/test/reference/clip-text.ps.xfail.png b/test/reference/clip-text.ps.xfail.png
deleted file mode 100644
index b50217d..0000000
Binary files a/test/reference/clip-text.ps.xfail.png and /dev/null differ
diff --git a/test/reference/clipped-group.pdf.ref.png b/test/reference/clipped-group.pdf.ref.png
index 23db5a4..55217ca 100644
Binary files a/test/reference/clipped-group.pdf.ref.png and b/test/reference/clipped-group.pdf.ref.png differ
diff --git a/test/reference/close-path-current-point.pdf.ref.png b/test/reference/close-path-current-point.pdf.ref.png
new file mode 100644
index 0000000..a162638
Binary files /dev/null and b/test/reference/close-path-current-point.pdf.ref.png differ
diff --git a/test/reference/close-path.pdf.argb32.ref.png b/test/reference/close-path.pdf.argb32.ref.png
new file mode 100644
index 0000000..e57654d
Binary files /dev/null and b/test/reference/close-path.pdf.argb32.ref.png differ
diff --git a/test/reference/close-path.pdf.rgb24.ref.png b/test/reference/close-path.pdf.rgb24.ref.png
new file mode 100644
index 0000000..e57654d
Binary files /dev/null and b/test/reference/close-path.pdf.rgb24.ref.png differ
diff --git a/test/reference/copy-path.pdf.ref.png b/test/reference/copy-path.pdf.ref.png
new file mode 100644
index 0000000..01673ee
Binary files /dev/null and b/test/reference/copy-path.pdf.ref.png differ
diff --git a/test/reference/culled-glyphs.ps.ref.png b/test/reference/culled-glyphs.ps.ref.png
index f34fb95..85daafa 100644
Binary files a/test/reference/culled-glyphs.ps.ref.png and b/test/reference/culled-glyphs.ps.ref.png differ
diff --git a/test/reference/dash-caps-joins.pdf.ref.png b/test/reference/dash-caps-joins.pdf.ref.png
new file mode 100644
index 0000000..55a8c87
Binary files /dev/null and b/test/reference/dash-caps-joins.pdf.ref.png differ
diff --git a/test/reference/dash-caps-joins.ps.ref.png b/test/reference/dash-caps-joins.ps.ref.png
index 466bc62..9cfdb19 100644
Binary files a/test/reference/dash-caps-joins.ps.ref.png and b/test/reference/dash-caps-joins.ps.ref.png differ
diff --git a/test/reference/dash-curve.pdf.ref.png b/test/reference/dash-curve.pdf.ref.png
new file mode 100644
index 0000000..ef4e76b
Binary files /dev/null and b/test/reference/dash-curve.pdf.ref.png differ
diff --git a/test/reference/dash-curve.ps.ref.png b/test/reference/dash-curve.ps.ref.png
new file mode 100644
index 0000000..b4e6d1c
Binary files /dev/null and b/test/reference/dash-curve.ps.ref.png differ
diff --git a/test/reference/dash-curve.ps2.ref.png b/test/reference/dash-curve.ps2.ref.png
deleted file mode 100644
index ffb402f..0000000
Binary files a/test/reference/dash-curve.ps2.ref.png and /dev/null differ
diff --git a/test/reference/dash-curve.ps3.ref.png b/test/reference/dash-curve.ps3.ref.png
deleted file mode 100644
index ffb402f..0000000
Binary files a/test/reference/dash-curve.ps3.ref.png and /dev/null differ
diff --git a/test/reference/dash-infinite-loop.pdf.ref.png b/test/reference/dash-infinite-loop.pdf.ref.png
new file mode 100644
index 0000000..e329b68
Binary files /dev/null and b/test/reference/dash-infinite-loop.pdf.ref.png differ
diff --git a/test/reference/dash-scale.pdf.ref.png b/test/reference/dash-scale.pdf.ref.png
new file mode 100644
index 0000000..335551f
Binary files /dev/null and b/test/reference/dash-scale.pdf.ref.png differ
diff --git a/test/reference/dash-state.pdf.ref.png b/test/reference/dash-state.pdf.ref.png
new file mode 100644
index 0000000..42db6e4
Binary files /dev/null and b/test/reference/dash-state.pdf.ref.png differ
diff --git a/test/reference/dash-zero-length.pdf.argb32.ref.png b/test/reference/dash-zero-length.pdf.argb32.ref.png
new file mode 100644
index 0000000..082eb00
Binary files /dev/null and b/test/reference/dash-zero-length.pdf.argb32.ref.png differ
diff --git a/test/reference/dash-zero-length.pdf.rgb24.ref.png b/test/reference/dash-zero-length.pdf.rgb24.ref.png
new file mode 100644
index 0000000..8dcfa54
Binary files /dev/null and b/test/reference/dash-zero-length.pdf.rgb24.ref.png differ
diff --git a/test/reference/degenerate-curve-to.pdf.ref.png b/test/reference/degenerate-curve-to.pdf.ref.png
new file mode 100644
index 0000000..1a1b7e4
Binary files /dev/null and b/test/reference/degenerate-curve-to.pdf.ref.png differ
diff --git a/test/reference/degenerate-linear-gradient.pdf.ref.png b/test/reference/degenerate-linear-gradient.pdf.ref.png
new file mode 100644
index 0000000..faeff6c
Binary files /dev/null and b/test/reference/degenerate-linear-gradient.pdf.ref.png differ
diff --git a/test/reference/degenerate-path.pdf.argb32.ref.png b/test/reference/degenerate-path.pdf.argb32.ref.png
new file mode 100644
index 0000000..c9dd809
Binary files /dev/null and b/test/reference/degenerate-path.pdf.argb32.ref.png differ
diff --git a/test/reference/degenerate-path.pdf.rgb24.ref.png b/test/reference/degenerate-path.pdf.rgb24.ref.png
new file mode 100644
index 0000000..65d5a53
Binary files /dev/null and b/test/reference/degenerate-path.pdf.rgb24.ref.png differ
diff --git a/test/reference/degenerate-pen.pdf.argb32.ref.png b/test/reference/degenerate-pen.pdf.argb32.ref.png
new file mode 100644
index 0000000..24e9a4f
Binary files /dev/null and b/test/reference/degenerate-pen.pdf.argb32.ref.png differ
diff --git a/test/reference/degenerate-pen.pdf.rgb24.ref.png b/test/reference/degenerate-pen.pdf.rgb24.ref.png
new file mode 100644
index 0000000..24e9a4f
Binary files /dev/null and b/test/reference/degenerate-pen.pdf.rgb24.ref.png differ
diff --git a/test/reference/degenerate-radial-gradient.pdf.ref.png b/test/reference/degenerate-radial-gradient.pdf.ref.png
new file mode 100644
index 0000000..ba47eb1
Binary files /dev/null and b/test/reference/degenerate-radial-gradient.pdf.ref.png differ
diff --git a/test/reference/degenerate-rel-curve-to.pdf.ref.png b/test/reference/degenerate-rel-curve-to.pdf.ref.png
new file mode 100644
index 0000000..5b3ef49
Binary files /dev/null and b/test/reference/degenerate-rel-curve-to.pdf.ref.png differ
diff --git a/test/reference/device-offset-fractional.pdf.ref.png b/test/reference/device-offset-fractional.pdf.ref.png
new file mode 100644
index 0000000..7c07093
Binary files /dev/null and b/test/reference/device-offset-fractional.pdf.ref.png differ
diff --git a/test/reference/device-offset-positive.ps.rgb24.ref.png b/test/reference/device-offset-positive.ps.rgb24.ref.png
new file mode 100644
index 0000000..dcdd332
Binary files /dev/null and b/test/reference/device-offset-positive.ps.rgb24.ref.png differ
diff --git a/test/reference/device-offset.ps.rgb24.ref.png b/test/reference/device-offset.ps.rgb24.ref.png
new file mode 100644
index 0000000..f19acba
Binary files /dev/null and b/test/reference/device-offset.ps.rgb24.ref.png differ
diff --git a/test/reference/extend-pad-border.pdf.ref.png b/test/reference/extend-pad-border.pdf.ref.png
index f4fc524..c22743e 100644
Binary files a/test/reference/extend-pad-border.pdf.ref.png and b/test/reference/extend-pad-border.pdf.ref.png differ
diff --git a/test/reference/fallback.pdf.ref.png b/test/reference/fallback.pdf.ref.png
new file mode 100644
index 0000000..2e4a457
Binary files /dev/null and b/test/reference/fallback.pdf.ref.png differ
diff --git a/test/reference/fallback.ps.ref.png b/test/reference/fallback.ps.ref.png
new file mode 100644
index 0000000..99c83e3
Binary files /dev/null and b/test/reference/fallback.ps.ref.png differ
diff --git a/test/reference/fill-alpha.ps.argb32.ref.png b/test/reference/fill-alpha.ps.argb32.ref.png
index 8d70d53..24bd3b1 100644
Binary files a/test/reference/fill-alpha.ps.argb32.ref.png and b/test/reference/fill-alpha.ps.argb32.ref.png differ
diff --git a/test/reference/fill-and-stroke-alpha-add.pdf.ref.png b/test/reference/fill-and-stroke-alpha-add.pdf.ref.png
new file mode 100644
index 0000000..609ed1f
Binary files /dev/null and b/test/reference/fill-and-stroke-alpha-add.pdf.ref.png differ
diff --git a/test/reference/fill-and-stroke-alpha.pdf.ref.png b/test/reference/fill-and-stroke-alpha.pdf.ref.png
new file mode 100644
index 0000000..e1746d5
Binary files /dev/null and b/test/reference/fill-and-stroke-alpha.pdf.ref.png differ
diff --git a/test/reference/fill-and-stroke.pdf.argb32.ref.png b/test/reference/fill-and-stroke.pdf.argb32.ref.png
new file mode 100644
index 0000000..81ec2f8
Binary files /dev/null and b/test/reference/fill-and-stroke.pdf.argb32.ref.png differ
diff --git a/test/reference/fill-and-stroke.pdf.rgb24.ref.png b/test/reference/fill-and-stroke.pdf.rgb24.ref.png
new file mode 100644
index 0000000..f0b2be5
Binary files /dev/null and b/test/reference/fill-and-stroke.pdf.rgb24.ref.png differ
diff --git a/test/reference/fill-degenerate-sort-order.argb32.ref.png b/test/reference/fill-degenerate-sort-order.argb32.ref.png
index bed9b5c..c43bcd5 100644
Binary files a/test/reference/fill-degenerate-sort-order.argb32.ref.png and b/test/reference/fill-degenerate-sort-order.argb32.ref.png differ
diff --git a/test/reference/fill-degenerate-sort-order.pdf.ref.png b/test/reference/fill-degenerate-sort-order.pdf.ref.png
new file mode 100644
index 0000000..20ce4b8
Binary files /dev/null and b/test/reference/fill-degenerate-sort-order.pdf.ref.png differ
diff --git a/test/reference/fill-degenerate-sort-order.rgb24.ref.png b/test/reference/fill-degenerate-sort-order.rgb24.ref.png
index 3f26e30..35ebdbd 100644
Binary files a/test/reference/fill-degenerate-sort-order.rgb24.ref.png and b/test/reference/fill-degenerate-sort-order.rgb24.ref.png differ
diff --git a/test/reference/fill-empty.ps.rgb24.ref.png b/test/reference/fill-empty.ps.rgb24.ref.png
new file mode 100644
index 0000000..dc7a8a0
Binary files /dev/null and b/test/reference/fill-empty.ps.rgb24.ref.png differ
diff --git a/test/reference/fill-image.ps.ref.png b/test/reference/fill-image.ps.ref.png
index 9713701..1b845bc 100644
Binary files a/test/reference/fill-image.ps.ref.png and b/test/reference/fill-image.ps.ref.png differ
diff --git a/test/reference/fill-missed-stop.pdf.argb32.ref.png b/test/reference/fill-missed-stop.pdf.argb32.ref.png
index 7d56e3e..8251b29 100644
Binary files a/test/reference/fill-missed-stop.pdf.argb32.ref.png and b/test/reference/fill-missed-stop.pdf.argb32.ref.png differ
diff --git a/test/reference/fill-missed-stop.pdf.rgb24.ref.png b/test/reference/fill-missed-stop.pdf.rgb24.ref.png
new file mode 100644
index 0000000..e992166
Binary files /dev/null and b/test/reference/fill-missed-stop.pdf.rgb24.ref.png differ
diff --git a/test/reference/fill-rule.pdf.ref.png b/test/reference/fill-rule.pdf.ref.png
new file mode 100644
index 0000000..67af051
Binary files /dev/null and b/test/reference/fill-rule.pdf.ref.png differ
diff --git a/test/reference/fill-rule.rgb24.ref.png b/test/reference/fill-rule.rgb24.ref.png
index 25023a2..70bde2d 100644
Binary files a/test/reference/fill-rule.rgb24.ref.png and b/test/reference/fill-rule.rgb24.ref.png differ
diff --git a/test/reference/finer-grained-fallbacks.pdf.argb32.ref.png b/test/reference/finer-grained-fallbacks.pdf.argb32.ref.png
new file mode 100644
index 0000000..f5edc14
Binary files /dev/null and b/test/reference/finer-grained-fallbacks.pdf.argb32.ref.png differ
diff --git a/test/reference/finer-grained-fallbacks.pdf.rgb24.ref.png b/test/reference/finer-grained-fallbacks.pdf.rgb24.ref.png
new file mode 100644
index 0000000..8ee9a5e
Binary files /dev/null and b/test/reference/finer-grained-fallbacks.pdf.rgb24.ref.png differ
diff --git a/test/reference/finer-grained-fallbacks.ps.argb32.ref.png b/test/reference/finer-grained-fallbacks.ps.argb32.ref.png
new file mode 100644
index 0000000..261c460
Binary files /dev/null and b/test/reference/finer-grained-fallbacks.ps.argb32.ref.png differ
diff --git a/test/reference/finer-grained-fallbacks.ps.rgb24.ref.png b/test/reference/finer-grained-fallbacks.ps.rgb24.ref.png
new file mode 100644
index 0000000..8ee9a5e
Binary files /dev/null and b/test/reference/finer-grained-fallbacks.ps.rgb24.ref.png differ
diff --git a/test/reference/finer-grained-fallbacks.ps2.argb32.ref.png b/test/reference/finer-grained-fallbacks.ps2.argb32.ref.png
deleted file mode 100644
index 19c132f..0000000
Binary files a/test/reference/finer-grained-fallbacks.ps2.argb32.ref.png and /dev/null differ
diff --git a/test/reference/finer-grained-fallbacks.ps2.ref.png b/test/reference/finer-grained-fallbacks.ps2.ref.png
deleted file mode 100644
index 1744100..0000000
Binary files a/test/reference/finer-grained-fallbacks.ps2.ref.png and /dev/null differ
diff --git a/test/reference/finer-grained-fallbacks.ps2.rgb24.ref.png b/test/reference/finer-grained-fallbacks.ps2.rgb24.ref.png
deleted file mode 100644
index 3f94a3a..0000000
Binary files a/test/reference/finer-grained-fallbacks.ps2.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/finer-grained-fallbacks.ps3.argb32.ref.png b/test/reference/finer-grained-fallbacks.ps3.argb32.ref.png
deleted file mode 100644
index 19c132f..0000000
Binary files a/test/reference/finer-grained-fallbacks.ps3.argb32.ref.png and /dev/null differ
diff --git a/test/reference/finer-grained-fallbacks.ps3.ref.png b/test/reference/finer-grained-fallbacks.ps3.ref.png
deleted file mode 100644
index 1744100..0000000
Binary files a/test/reference/finer-grained-fallbacks.ps3.ref.png and /dev/null differ
diff --git a/test/reference/finer-grained-fallbacks.ps3.rgb24.ref.png b/test/reference/finer-grained-fallbacks.ps3.rgb24.ref.png
deleted file mode 100644
index 3f94a3a..0000000
Binary files a/test/reference/finer-grained-fallbacks.ps3.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/font-matrix-translation.ps.ref.png b/test/reference/font-matrix-translation.ps.ref.png
new file mode 100644
index 0000000..472e60f
Binary files /dev/null and b/test/reference/font-matrix-translation.ps.ref.png differ
diff --git a/test/reference/font-matrix-translation.ps2.argb32.ref.png b/test/reference/font-matrix-translation.ps2.argb32.ref.png
deleted file mode 100644
index 41d05a0..0000000
Binary files a/test/reference/font-matrix-translation.ps2.argb32.ref.png and /dev/null differ
diff --git a/test/reference/font-matrix-translation.ps2.rgb24.ref.png b/test/reference/font-matrix-translation.ps2.rgb24.ref.png
deleted file mode 100644
index 41d05a0..0000000
Binary files a/test/reference/font-matrix-translation.ps2.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/font-matrix-translation.ps3.argb32.ref.png b/test/reference/font-matrix-translation.ps3.argb32.ref.png
deleted file mode 100644
index 41d05a0..0000000
Binary files a/test/reference/font-matrix-translation.ps3.argb32.ref.png and /dev/null differ
diff --git a/test/reference/font-matrix-translation.ps3.rgb24.ref.png b/test/reference/font-matrix-translation.ps3.rgb24.ref.png
deleted file mode 100644
index 41d05a0..0000000
Binary files a/test/reference/font-matrix-translation.ps3.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/ft-show-glyphs-positioning.pdf.ref.png b/test/reference/ft-show-glyphs-positioning.pdf.ref.png
index 0d62fd3..4f8d9f7 100644
Binary files a/test/reference/ft-show-glyphs-positioning.pdf.ref.png and b/test/reference/ft-show-glyphs-positioning.pdf.ref.png differ
diff --git a/test/reference/ft-show-glyphs-positioning.ps.ref.png b/test/reference/ft-show-glyphs-positioning.ps.ref.png
new file mode 100644
index 0000000..f4e5720
Binary files /dev/null and b/test/reference/ft-show-glyphs-positioning.ps.ref.png differ
diff --git a/test/reference/ft-show-glyphs-positioning.ps2.ref.png b/test/reference/ft-show-glyphs-positioning.ps2.ref.png
deleted file mode 100644
index c5fbf30..0000000
Binary files a/test/reference/ft-show-glyphs-positioning.ps2.ref.png and /dev/null differ
diff --git a/test/reference/ft-show-glyphs-positioning.ps3.ref.png b/test/reference/ft-show-glyphs-positioning.ps3.ref.png
deleted file mode 100644
index c5fbf30..0000000
Binary files a/test/reference/ft-show-glyphs-positioning.ps3.ref.png and /dev/null differ
diff --git a/test/reference/ft-show-glyphs-table.ps.ref.png b/test/reference/ft-show-glyphs-table.ps.ref.png
new file mode 100644
index 0000000..35a9986
Binary files /dev/null and b/test/reference/ft-show-glyphs-table.ps.ref.png differ
diff --git a/test/reference/ft-show-glyphs-table.ps2.ref.png b/test/reference/ft-show-glyphs-table.ps2.ref.png
deleted file mode 100644
index 5143663..0000000
Binary files a/test/reference/ft-show-glyphs-table.ps2.ref.png and /dev/null differ
diff --git a/test/reference/ft-show-glyphs-table.ps3.ref.png b/test/reference/ft-show-glyphs-table.ps3.ref.png
deleted file mode 100644
index 5143663..0000000
Binary files a/test/reference/ft-show-glyphs-table.ps3.ref.png and /dev/null differ
diff --git a/test/reference/ft-text-vertical-layout-type3.pdf.ref.png b/test/reference/ft-text-vertical-layout-type3.pdf.ref.png
index a05ec1d..cec2547 100644
Binary files a/test/reference/ft-text-vertical-layout-type3.pdf.ref.png and b/test/reference/ft-text-vertical-layout-type3.pdf.ref.png differ
diff --git a/test/reference/ft-text-vertical-layout-type3.ps.ref.png b/test/reference/ft-text-vertical-layout-type3.ps.ref.png
index f8aafa2..11aed7d 100644
Binary files a/test/reference/ft-text-vertical-layout-type3.ps.ref.png and b/test/reference/ft-text-vertical-layout-type3.ps.ref.png differ
diff --git a/test/reference/ft-text-vertical-layout-type3.ref.png b/test/reference/ft-text-vertical-layout-type3.ref.png
index 5f64d88..0db1c0c 100644
Binary files a/test/reference/ft-text-vertical-layout-type3.ref.png and b/test/reference/ft-text-vertical-layout-type3.ref.png differ
diff --git a/test/reference/glyph-cache-pressure.ps.ref.png b/test/reference/glyph-cache-pressure.ps.ref.png
new file mode 100644
index 0000000..e537bc5
Binary files /dev/null and b/test/reference/glyph-cache-pressure.ps.ref.png differ
diff --git a/test/reference/glyph-cache-pressure.ps2.ref.png b/test/reference/glyph-cache-pressure.ps2.ref.png
deleted file mode 100644
index 88fa447..0000000
Binary files a/test/reference/glyph-cache-pressure.ps2.ref.png and /dev/null differ
diff --git a/test/reference/glyph-cache-pressure.ps3.ref.png b/test/reference/glyph-cache-pressure.ps3.ref.png
deleted file mode 100644
index 88fa447..0000000
Binary files a/test/reference/glyph-cache-pressure.ps3.ref.png and /dev/null differ
diff --git a/test/reference/gradient-alpha.pdf.argb32.ref.png b/test/reference/gradient-alpha.pdf.argb32.ref.png
new file mode 100644
index 0000000..48ab382
Binary files /dev/null and b/test/reference/gradient-alpha.pdf.argb32.ref.png differ
diff --git a/test/reference/gradient-alpha.pdf.rgb24.ref.png b/test/reference/gradient-alpha.pdf.rgb24.ref.png
new file mode 100644
index 0000000..27b9d20
Binary files /dev/null and b/test/reference/gradient-alpha.pdf.rgb24.ref.png differ
diff --git a/test/reference/gradient-constant-alpha.pdf.argb32.ref.png b/test/reference/gradient-constant-alpha.pdf.argb32.ref.png
new file mode 100644
index 0000000..ad2fbda
Binary files /dev/null and b/test/reference/gradient-constant-alpha.pdf.argb32.ref.png differ
diff --git a/test/reference/gradient-constant-alpha.pdf.rgb24.ref.png b/test/reference/gradient-constant-alpha.pdf.rgb24.ref.png
new file mode 100644
index 0000000..b1cae2d
Binary files /dev/null and b/test/reference/gradient-constant-alpha.pdf.rgb24.ref.png differ
diff --git a/test/reference/gradient-zero-stops-mask.ps.rgb24.ref.png b/test/reference/gradient-zero-stops-mask.ps.rgb24.ref.png
new file mode 100644
index 0000000..21465ce
Binary files /dev/null and b/test/reference/gradient-zero-stops-mask.ps.rgb24.ref.png differ
diff --git a/test/reference/gradient-zero-stops.ps.rgb24.png b/test/reference/gradient-zero-stops.ps.rgb24.png
new file mode 100644
index 0000000..21465ce
Binary files /dev/null and b/test/reference/gradient-zero-stops.ps.rgb24.png differ
diff --git a/test/reference/group-unaligned.ps.ref.png b/test/reference/group-unaligned.ps.ref.png
index f108998..2cd04f4 100644
Binary files a/test/reference/group-unaligned.ps.ref.png and b/test/reference/group-unaligned.ps.ref.png differ
diff --git a/test/reference/halo-transform.ps.ref.png b/test/reference/halo-transform.ps.ref.png
index 89e1f76..f1d2e2b 100644
Binary files a/test/reference/halo-transform.ps.ref.png and b/test/reference/halo-transform.ps.ref.png differ
diff --git a/test/reference/halo.ps.ref.png b/test/reference/halo.ps.ref.png
index 1426d2e..f8d025f 100644
Binary files a/test/reference/halo.ps.ref.png and b/test/reference/halo.ps.ref.png differ
diff --git a/test/reference/huge-linear.pdf.ref.png b/test/reference/huge-linear.pdf.ref.png
index 8313470..cdafafa 100644
Binary files a/test/reference/huge-linear.pdf.ref.png and b/test/reference/huge-linear.pdf.ref.png differ
diff --git a/test/reference/huge-radial.pdf.ref.png b/test/reference/huge-radial.pdf.ref.png
new file mode 100644
index 0000000..8aa088b
Binary files /dev/null and b/test/reference/huge-radial.pdf.ref.png differ
diff --git a/test/reference/huge-radial.ref.png b/test/reference/huge-radial.ref.png
index 541bb30..8246fff 100644
Binary files a/test/reference/huge-radial.ref.png and b/test/reference/huge-radial.ref.png differ
diff --git a/test/reference/image-surface-source.ps.argb32.ref.png b/test/reference/image-surface-source.ps.argb32.ref.png
new file mode 100644
index 0000000..b69f5bb
Binary files /dev/null and b/test/reference/image-surface-source.ps.argb32.ref.png differ
diff --git a/test/reference/image-surface-source.ps.rgb24.ref.png b/test/reference/image-surface-source.ps.rgb24.ref.png
new file mode 100644
index 0000000..d9af4f8
Binary files /dev/null and b/test/reference/image-surface-source.ps.rgb24.ref.png differ
diff --git a/test/reference/image-surface-source.ps2.ref.png b/test/reference/image-surface-source.ps2.ref.png
deleted file mode 100644
index 1023158..0000000
Binary files a/test/reference/image-surface-source.ps2.ref.png and /dev/null differ
diff --git a/test/reference/image-surface-source.ps3.ref.png b/test/reference/image-surface-source.ps3.ref.png
deleted file mode 100644
index 1023158..0000000
Binary files a/test/reference/image-surface-source.ps3.ref.png and /dev/null differ
diff --git a/test/reference/infinite-join.pdf.ref.png b/test/reference/infinite-join.pdf.ref.png
new file mode 100644
index 0000000..f40b4a4
Binary files /dev/null and b/test/reference/infinite-join.pdf.ref.png differ
diff --git a/test/reference/inverse-text.ps.ref.png b/test/reference/inverse-text.ps.ref.png
new file mode 100644
index 0000000..0707174
Binary files /dev/null and b/test/reference/inverse-text.ps.ref.png differ
diff --git a/test/reference/joins-loop.ps.ref.png b/test/reference/joins-loop.ps.ref.png
new file mode 100644
index 0000000..37b833a
Binary files /dev/null and b/test/reference/joins-loop.ps.ref.png differ
diff --git a/test/reference/joins-star.ps.ref.png b/test/reference/joins-star.ps.ref.png
new file mode 100644
index 0000000..44ad65a
Binary files /dev/null and b/test/reference/joins-star.ps.ref.png differ
diff --git a/test/reference/joins.pdf.argb32.ref.png b/test/reference/joins.pdf.argb32.ref.png
new file mode 100644
index 0000000..7ad9fb9
Binary files /dev/null and b/test/reference/joins.pdf.argb32.ref.png differ
diff --git a/test/reference/joins.pdf.rgb24.ref.png b/test/reference/joins.pdf.rgb24.ref.png
new file mode 100644
index 0000000..7ad9fb9
Binary files /dev/null and b/test/reference/joins.pdf.rgb24.ref.png differ
diff --git a/test/reference/large-font.ps.ref.png b/test/reference/large-font.ps.ref.png
new file mode 100644
index 0000000..b4fba17
Binary files /dev/null and b/test/reference/large-font.ps.ref.png differ
diff --git a/test/reference/leaky-dashed-stroke.pdf.ref.png b/test/reference/leaky-dashed-stroke.pdf.ref.png
new file mode 100644
index 0000000..6d3d981
Binary files /dev/null and b/test/reference/leaky-dashed-stroke.pdf.ref.png differ
diff --git a/test/reference/leaky-polygon.pdf.ref.png b/test/reference/leaky-polygon.pdf.ref.png
new file mode 100644
index 0000000..db32c0c
Binary files /dev/null and b/test/reference/leaky-polygon.pdf.ref.png differ
diff --git a/test/reference/line-width-large-overlap-offset.ps.ref.png b/test/reference/line-width-large-overlap-offset.ps.ref.png
new file mode 100644
index 0000000..3c3464b
Binary files /dev/null and b/test/reference/line-width-large-overlap-offset.ps.ref.png differ
diff --git a/test/reference/line-width-large-overlap-rotated.ps.ref.png b/test/reference/line-width-large-overlap-rotated.ps.ref.png
new file mode 100644
index 0000000..35f3847
Binary files /dev/null and b/test/reference/line-width-large-overlap-rotated.ps.ref.png differ
diff --git a/test/reference/line-width-overlap-offset.ps.ref.png b/test/reference/line-width-overlap-offset.ps.ref.png
new file mode 100644
index 0000000..f869ca2
Binary files /dev/null and b/test/reference/line-width-overlap-offset.ps.ref.png differ
diff --git a/test/reference/line-width-overlap-rotated.ps.ref.png b/test/reference/line-width-overlap-rotated.ps.ref.png
new file mode 100644
index 0000000..b63bfd4
Binary files /dev/null and b/test/reference/line-width-overlap-rotated.ps.ref.png differ
diff --git a/test/reference/line-width-scale.pdf.ref.png b/test/reference/line-width-scale.pdf.ref.png
new file mode 100644
index 0000000..9aa8b1a
Binary files /dev/null and b/test/reference/line-width-scale.pdf.ref.png differ
diff --git a/test/reference/line-width-tolerance.pdf.ref.png b/test/reference/line-width-tolerance.pdf.ref.png
new file mode 100644
index 0000000..f890a52
Binary files /dev/null and b/test/reference/line-width-tolerance.pdf.ref.png differ
diff --git a/test/reference/line-width-tolerance.ps.ref.png b/test/reference/line-width-tolerance.ps.ref.png
new file mode 100644
index 0000000..34a2d97
Binary files /dev/null and b/test/reference/line-width-tolerance.ps.ref.png differ
diff --git a/test/reference/line-width.pdf.ref.png b/test/reference/line-width.pdf.ref.png
new file mode 100644
index 0000000..3575652
Binary files /dev/null and b/test/reference/line-width.pdf.ref.png differ
diff --git a/test/reference/linear-gradient-extend.pdf.ref.png b/test/reference/linear-gradient-extend.pdf.ref.png
new file mode 100644
index 0000000..4c3764c
Binary files /dev/null and b/test/reference/linear-gradient-extend.pdf.ref.png differ
diff --git a/test/reference/linear-gradient-large.pdf.ref.png b/test/reference/linear-gradient-large.pdf.ref.png
new file mode 100644
index 0000000..ae995a9
Binary files /dev/null and b/test/reference/linear-gradient-large.pdf.ref.png differ
diff --git a/test/reference/linear-gradient-large.ps.ref.png b/test/reference/linear-gradient-large.ps.ref.png
new file mode 100644
index 0000000..038df5d
Binary files /dev/null and b/test/reference/linear-gradient-large.ps.ref.png differ
diff --git a/test/reference/linear-gradient-one-stop.ps.rgb24.ref.png b/test/reference/linear-gradient-one-stop.ps.rgb24.ref.png
new file mode 100644
index 0000000..efc12ee
Binary files /dev/null and b/test/reference/linear-gradient-one-stop.ps.rgb24.ref.png differ
diff --git a/test/reference/linear-gradient-subset.pdf.ref.png b/test/reference/linear-gradient-subset.pdf.ref.png
new file mode 100644
index 0000000..eaf8d29
Binary files /dev/null and b/test/reference/linear-gradient-subset.pdf.ref.png differ
diff --git a/test/reference/linear-gradient-subset.ref.png b/test/reference/linear-gradient-subset.ref.png
index 8e95d10..fa0f62d 100644
Binary files a/test/reference/linear-gradient-subset.ref.png and b/test/reference/linear-gradient-subset.ref.png differ
diff --git a/test/reference/linear-gradient.pdf.ref.png b/test/reference/linear-gradient.pdf.ref.png
new file mode 100644
index 0000000..62f74dd
Binary files /dev/null and b/test/reference/linear-gradient.pdf.ref.png differ
diff --git a/test/reference/linear-gradient.ps3.ref.png b/test/reference/linear-gradient.ps3.ref.png
index c2fa71b..fb83dba 100644
Binary files a/test/reference/linear-gradient.ps3.ref.png and b/test/reference/linear-gradient.ps3.ref.png differ
diff --git a/test/reference/linear-gradient.ref.png b/test/reference/linear-gradient.ref.png
index 32c99a4..ad6d890 100644
Binary files a/test/reference/linear-gradient.ref.png and b/test/reference/linear-gradient.ref.png differ
diff --git a/test/reference/linear-uniform.ps.ref.png b/test/reference/linear-uniform.ps.ref.png
new file mode 100644
index 0000000..0faced8
Binary files /dev/null and b/test/reference/linear-uniform.ps.ref.png differ
diff --git a/test/reference/long-dashed-lines.pdf.ref.png b/test/reference/long-dashed-lines.pdf.ref.png
new file mode 100644
index 0000000..8c203a4
Binary files /dev/null and b/test/reference/long-dashed-lines.pdf.ref.png differ
diff --git a/test/reference/mask-ctm.ps.rgb24.ref.png b/test/reference/mask-ctm.ps.rgb24.ref.png
new file mode 100644
index 0000000..de3fa09
Binary files /dev/null and b/test/reference/mask-ctm.ps.rgb24.ref.png differ
diff --git a/test/reference/mask-surface-ctm.ps.rgb24.ref.png b/test/reference/mask-surface-ctm.ps.rgb24.ref.png
new file mode 100644
index 0000000..de3fa09
Binary files /dev/null and b/test/reference/mask-surface-ctm.ps.rgb24.ref.png differ
diff --git a/test/reference/mask-transformed-image.pdf.ref.png b/test/reference/mask-transformed-image.pdf.ref.png
index 33ec279..49c6be0 100644
Binary files a/test/reference/mask-transformed-image.pdf.ref.png and b/test/reference/mask-transformed-image.pdf.ref.png differ
diff --git a/test/reference/mask-transformed-image.ps.ref.png b/test/reference/mask-transformed-image.ps.ref.png
new file mode 100644
index 0000000..fa8482a
Binary files /dev/null and b/test/reference/mask-transformed-image.ps.ref.png differ
diff --git a/test/reference/mask-transformed-similar.pdf.ref.png b/test/reference/mask-transformed-similar.pdf.ref.png
index e8d3879..339c71e 100644
Binary files a/test/reference/mask-transformed-similar.pdf.ref.png and b/test/reference/mask-transformed-similar.pdf.ref.png differ
diff --git a/test/reference/mask-transformed-similar.ps.ref.png b/test/reference/mask-transformed-similar.ps.ref.png
new file mode 100644
index 0000000..f0e7a24
Binary files /dev/null and b/test/reference/mask-transformed-similar.ps.ref.png differ
diff --git a/test/reference/mask.argb32.ref.png b/test/reference/mask.argb32.ref.png
index a4c683c..bc142c2 100644
Binary files a/test/reference/mask.argb32.ref.png and b/test/reference/mask.argb32.ref.png differ
diff --git a/test/reference/mask.pdf.argb32.ref.png b/test/reference/mask.pdf.argb32.ref.png
index 33769ee..80fd759 100644
Binary files a/test/reference/mask.pdf.argb32.ref.png and b/test/reference/mask.pdf.argb32.ref.png differ
diff --git a/test/reference/mask.pdf.rgb24.ref.png b/test/reference/mask.pdf.rgb24.ref.png
index dbd49a8..6b95459 100644
Binary files a/test/reference/mask.pdf.rgb24.ref.png and b/test/reference/mask.pdf.rgb24.ref.png differ
diff --git a/test/reference/mask.rgb24.ref.png b/test/reference/mask.rgb24.ref.png
index 1bd1833..c7962a3 100644
Binary files a/test/reference/mask.rgb24.ref.png and b/test/reference/mask.rgb24.ref.png differ
diff --git a/test/reference/mesh-pattern-conical.pdf.ref.png b/test/reference/mesh-pattern-conical.pdf.ref.png
new file mode 100644
index 0000000..4c830b1
Binary files /dev/null and b/test/reference/mesh-pattern-conical.pdf.ref.png differ
diff --git a/test/reference/mesh-pattern-conical.ps.ref.png b/test/reference/mesh-pattern-conical.ps.ref.png
new file mode 100644
index 0000000..426428a
Binary files /dev/null and b/test/reference/mesh-pattern-conical.ps.ref.png differ
diff --git a/test/reference/mesh-pattern-control-points.pdf.ref.png b/test/reference/mesh-pattern-control-points.pdf.ref.png
new file mode 100644
index 0000000..f614a2c
Binary files /dev/null and b/test/reference/mesh-pattern-control-points.pdf.ref.png differ
diff --git a/test/reference/mesh-pattern-control-points.ps.ref.png b/test/reference/mesh-pattern-control-points.ps.ref.png
new file mode 100644
index 0000000..f37184a
Binary files /dev/null and b/test/reference/mesh-pattern-control-points.ps.ref.png differ
diff --git a/test/reference/mesh-pattern-fold.pdf.ref.png b/test/reference/mesh-pattern-fold.pdf.ref.png
new file mode 100644
index 0000000..8cf5eb4
Binary files /dev/null and b/test/reference/mesh-pattern-fold.pdf.ref.png differ
diff --git a/test/reference/mesh-pattern-fold.ps.ref.png b/test/reference/mesh-pattern-fold.ps.ref.png
new file mode 100644
index 0000000..d44404d
Binary files /dev/null and b/test/reference/mesh-pattern-fold.ps.ref.png differ
diff --git a/test/reference/mesh-pattern-overlap.pdf.ref.png b/test/reference/mesh-pattern-overlap.pdf.ref.png
new file mode 100644
index 0000000..0403b04
Binary files /dev/null and b/test/reference/mesh-pattern-overlap.pdf.ref.png differ
diff --git a/test/reference/mesh-pattern-overlap.ps.ref.png b/test/reference/mesh-pattern-overlap.ps.ref.png
new file mode 100644
index 0000000..a90e533
Binary files /dev/null and b/test/reference/mesh-pattern-overlap.ps.ref.png differ
diff --git a/test/reference/mesh-pattern-transformed.pdf.ref.png b/test/reference/mesh-pattern-transformed.pdf.ref.png
new file mode 100644
index 0000000..faf3f13
Binary files /dev/null and b/test/reference/mesh-pattern-transformed.pdf.ref.png differ
diff --git a/test/reference/mesh-pattern-transformed.ps.ref.png b/test/reference/mesh-pattern-transformed.ps.ref.png
new file mode 100644
index 0000000..d8a89b7
Binary files /dev/null and b/test/reference/mesh-pattern-transformed.ps.ref.png differ
diff --git a/test/reference/mesh-pattern.pdf.ref.png b/test/reference/mesh-pattern.pdf.ref.png
new file mode 100644
index 0000000..1050225
Binary files /dev/null and b/test/reference/mesh-pattern.pdf.ref.png differ
diff --git a/test/reference/mesh-pattern.ps.ref.png b/test/reference/mesh-pattern.ps.ref.png
new file mode 100644
index 0000000..812432c
Binary files /dev/null and b/test/reference/mesh-pattern.ps.ref.png differ
diff --git a/test/reference/new-sub-path.pdf.argb32.ref.png b/test/reference/new-sub-path.pdf.argb32.ref.png
index 41fe131..44a70eb 100644
Binary files a/test/reference/new-sub-path.pdf.argb32.ref.png and b/test/reference/new-sub-path.pdf.argb32.ref.png differ
diff --git a/test/reference/new-sub-path.pdf.rgb24.ref.png b/test/reference/new-sub-path.pdf.rgb24.ref.png
new file mode 100644
index 0000000..73f26b2
Binary files /dev/null and b/test/reference/new-sub-path.pdf.rgb24.ref.png differ
diff --git a/test/reference/nil-surface.ps.rgb24.ref.png b/test/reference/nil-surface.ps.rgb24.ref.png
new file mode 100644
index 0000000..7d5589c
Binary files /dev/null and b/test/reference/nil-surface.ps.rgb24.ref.png differ
diff --git a/test/reference/operator-alpha-alpha.pdf.ref.png b/test/reference/operator-alpha-alpha.pdf.ref.png
new file mode 100644
index 0000000..fc173cb
Binary files /dev/null and b/test/reference/operator-alpha-alpha.pdf.ref.png differ
diff --git a/test/reference/operator-alpha-alpha.ps.ref.png b/test/reference/operator-alpha-alpha.ps.ref.png
new file mode 100644
index 0000000..fd12e9c
Binary files /dev/null and b/test/reference/operator-alpha-alpha.ps.ref.png differ
diff --git a/test/reference/operator-clear.pdf.argb32.ref.png b/test/reference/operator-clear.pdf.argb32.ref.png
new file mode 100644
index 0000000..88255fe
Binary files /dev/null and b/test/reference/operator-clear.pdf.argb32.ref.png differ
diff --git a/test/reference/operator-clear.rgb24.ref.png b/test/reference/operator-clear.rgb24.ref.png
index 533b49a..1e89ccd 100644
Binary files a/test/reference/operator-clear.rgb24.ref.png and b/test/reference/operator-clear.rgb24.ref.png differ
diff --git a/test/reference/operator-source.argb32.ref.png b/test/reference/operator-source.argb32.ref.png
index 5fd5c43..49d2f27 100644
Binary files a/test/reference/operator-source.argb32.ref.png and b/test/reference/operator-source.argb32.ref.png differ
diff --git a/test/reference/operator-source.rgb24.ref.png b/test/reference/operator-source.rgb24.ref.png
index c7846e5..38472f4 100644
Binary files a/test/reference/operator-source.rgb24.ref.png and b/test/reference/operator-source.rgb24.ref.png differ
diff --git a/test/reference/over-above-source.ps3.argb32.ref.png b/test/reference/over-above-source.ps3.argb32.ref.png
index 7c90d08..2c3e9fa 100644
Binary files a/test/reference/over-above-source.ps3.argb32.ref.png and b/test/reference/over-above-source.ps3.argb32.ref.png differ
diff --git a/test/reference/over-around-source.ps3.argb32.ref.png b/test/reference/over-around-source.ps3.argb32.ref.png
index 4391759..1fe11d9 100644
Binary files a/test/reference/over-around-source.ps3.argb32.ref.png and b/test/reference/over-around-source.ps3.argb32.ref.png differ
diff --git a/test/reference/over-between-source.ps3.argb32.ref.png b/test/reference/over-between-source.ps3.argb32.ref.png
index dd95940..05dfb63 100644
Binary files a/test/reference/over-between-source.ps3.argb32.ref.png and b/test/reference/over-between-source.ps3.argb32.ref.png differ
diff --git a/test/reference/overlapping-boxes.ps.argb32.ref.png b/test/reference/overlapping-boxes.ps.argb32.ref.png
new file mode 100644
index 0000000..65cb550
Binary files /dev/null and b/test/reference/overlapping-boxes.ps.argb32.ref.png differ
diff --git a/test/reference/overlapping-boxes.ps.rgb24.ref.png b/test/reference/overlapping-boxes.ps.rgb24.ref.png
new file mode 100644
index 0000000..0edeafa
Binary files /dev/null and b/test/reference/overlapping-boxes.ps.rgb24.ref.png differ
diff --git a/test/reference/overlapping-glyphs.pdf.argb32.ref.png b/test/reference/overlapping-glyphs.pdf.argb32.ref.png
new file mode 100644
index 0000000..708d54a
Binary files /dev/null and b/test/reference/overlapping-glyphs.pdf.argb32.ref.png differ
diff --git a/test/reference/overlapping-glyphs.pdf.rgb24.ref.png b/test/reference/overlapping-glyphs.pdf.rgb24.ref.png
new file mode 100644
index 0000000..ff9e1c8
Binary files /dev/null and b/test/reference/overlapping-glyphs.pdf.rgb24.ref.png differ
diff --git a/test/reference/overlapping-glyphs.ps.rgb24.ref.png b/test/reference/overlapping-glyphs.ps.rgb24.ref.png
new file mode 100644
index 0000000..c4fd146
Binary files /dev/null and b/test/reference/overlapping-glyphs.ps.rgb24.ref.png differ
diff --git a/test/reference/paint-source-alpha.pdf.ref.png b/test/reference/paint-source-alpha.pdf.ref.png
new file mode 100644
index 0000000..487b8b6
Binary files /dev/null and b/test/reference/paint-source-alpha.pdf.ref.png differ
diff --git a/test/reference/paint-with-alpha-clip-mask.pdf.ref.png b/test/reference/paint-with-alpha-clip-mask.pdf.ref.png
new file mode 100644
index 0000000..35630c7
Binary files /dev/null and b/test/reference/paint-with-alpha-clip-mask.pdf.ref.png differ
diff --git a/test/reference/paint-with-alpha-clip.pdf.ref.png b/test/reference/paint-with-alpha-clip.pdf.ref.png
new file mode 100644
index 0000000..c3dabc5
Binary files /dev/null and b/test/reference/paint-with-alpha-clip.pdf.ref.png differ
diff --git a/test/reference/paint-with-alpha-solid-clip.pdf.ref.png b/test/reference/paint-with-alpha-solid-clip.pdf.ref.png
new file mode 100644
index 0000000..034ba6d
Binary files /dev/null and b/test/reference/paint-with-alpha-solid-clip.pdf.ref.png differ
diff --git a/test/reference/paint-with-alpha.pdf.ref.png b/test/reference/paint-with-alpha.pdf.ref.png
new file mode 100644
index 0000000..487b8b6
Binary files /dev/null and b/test/reference/paint-with-alpha.pdf.ref.png differ
diff --git a/test/reference/partial-clip-text-bottom.ps.ref.png b/test/reference/partial-clip-text-bottom.ps.ref.png
new file mode 100644
index 0000000..cda2b3d
Binary files /dev/null and b/test/reference/partial-clip-text-bottom.ps.ref.png differ
diff --git a/test/reference/partial-clip-text-left.ps.ref.png b/test/reference/partial-clip-text-left.ps.ref.png
new file mode 100644
index 0000000..a717f7b
Binary files /dev/null and b/test/reference/partial-clip-text-left.ps.ref.png differ
diff --git a/test/reference/partial-clip-text-right.ps.ref.png b/test/reference/partial-clip-text-right.ps.ref.png
new file mode 100644
index 0000000..a88ef82
Binary files /dev/null and b/test/reference/partial-clip-text-right.ps.ref.png differ
diff --git a/test/reference/partial-clip-text-top.ps.ref.png b/test/reference/partial-clip-text-top.ps.ref.png
index 049bba5..3f0ca42 100644
Binary files a/test/reference/partial-clip-text-top.ps.ref.png and b/test/reference/partial-clip-text-top.ps.ref.png differ
diff --git a/test/reference/pass-through.ps.rgb24.ref.png b/test/reference/pass-through.ps.rgb24.ref.png
new file mode 100644
index 0000000..e98cb9e
Binary files /dev/null and b/test/reference/pass-through.ps.rgb24.ref.png differ
diff --git a/test/reference/path-stroke-twice.pdf.ref.png b/test/reference/path-stroke-twice.pdf.ref.png
new file mode 100644
index 0000000..10763bf
Binary files /dev/null and b/test/reference/path-stroke-twice.pdf.ref.png differ
diff --git a/test/reference/pdf-surface-source.ps.argb32.ref.png b/test/reference/pdf-surface-source.ps.argb32.ref.png
new file mode 100644
index 0000000..8b51d9b
Binary files /dev/null and b/test/reference/pdf-surface-source.ps.argb32.ref.png differ
diff --git a/test/reference/pdf-surface-source.ps.rgb24.ref.png b/test/reference/pdf-surface-source.ps.rgb24.ref.png
new file mode 100644
index 0000000..26cbb57
Binary files /dev/null and b/test/reference/pdf-surface-source.ps.rgb24.ref.png differ
diff --git a/test/reference/pixman-downscale-best-24.pdf.ref.png b/test/reference/pixman-downscale-best-24.pdf.ref.png
new file mode 100644
index 0000000..c617804
Binary files /dev/null and b/test/reference/pixman-downscale-best-24.pdf.ref.png differ
diff --git a/test/reference/pixman-downscale-best-24.ps.ref.png b/test/reference/pixman-downscale-best-24.ps.ref.png
new file mode 100644
index 0000000..e861b90
Binary files /dev/null and b/test/reference/pixman-downscale-best-24.ps.ref.png differ
diff --git a/test/reference/pixman-downscale-best-24.ref.png b/test/reference/pixman-downscale-best-24.ref.png
index df0f9c0..184a64b 100644
Binary files a/test/reference/pixman-downscale-best-24.ref.png and b/test/reference/pixman-downscale-best-24.ref.png differ
diff --git a/test/reference/pixman-downscale-best-96.ps.ref.png b/test/reference/pixman-downscale-best-96.ps.ref.png
new file mode 100644
index 0000000..ae867d6
Binary files /dev/null and b/test/reference/pixman-downscale-best-96.ps.ref.png differ
diff --git a/test/reference/pixman-downscale-bilinear-24.ps.ref.png b/test/reference/pixman-downscale-bilinear-24.ps.ref.png
new file mode 100644
index 0000000..e861b90
Binary files /dev/null and b/test/reference/pixman-downscale-bilinear-24.ps.ref.png differ
diff --git a/test/reference/pixman-downscale-bilinear-96.ps.ref.png b/test/reference/pixman-downscale-bilinear-96.ps.ref.png
new file mode 100644
index 0000000..ae867d6
Binary files /dev/null and b/test/reference/pixman-downscale-bilinear-96.ps.ref.png differ
diff --git a/test/reference/pixman-downscale-good-24.ps.ref.png b/test/reference/pixman-downscale-good-24.ps.ref.png
new file mode 100644
index 0000000..e861b90
Binary files /dev/null and b/test/reference/pixman-downscale-good-24.ps.ref.png differ
diff --git a/test/reference/pixman-downscale-good-96.ps.ref.png b/test/reference/pixman-downscale-good-96.ps.ref.png
new file mode 100644
index 0000000..ae867d6
Binary files /dev/null and b/test/reference/pixman-downscale-good-96.ps.ref.png differ
diff --git a/test/reference/pixman-rotate.ps.argb32.ref.png b/test/reference/pixman-rotate.ps.argb32.ref.png
index 0e91688..e65385c 100644
Binary files a/test/reference/pixman-rotate.ps.argb32.ref.png and b/test/reference/pixman-rotate.ps.argb32.ref.png differ
diff --git a/test/reference/pixman-rotate.ps.rgb24.ref.png b/test/reference/pixman-rotate.ps.rgb24.ref.png
new file mode 100644
index 0000000..59a0f43
Binary files /dev/null and b/test/reference/pixman-rotate.ps.rgb24.ref.png differ
diff --git a/test/reference/ps-surface-source.ps.argb32.ref.png b/test/reference/ps-surface-source.ps.argb32.ref.png
new file mode 100644
index 0000000..8b51d9b
Binary files /dev/null and b/test/reference/ps-surface-source.ps.argb32.ref.png differ
diff --git a/test/reference/ps-surface-source.ps.rgb24.ref.png b/test/reference/ps-surface-source.ps.rgb24.ref.png
new file mode 100644
index 0000000..26cbb57
Binary files /dev/null and b/test/reference/ps-surface-source.ps.rgb24.ref.png differ
diff --git a/test/reference/pthread-show-text.pdf.ref.png b/test/reference/pthread-show-text.pdf.ref.png
index bb72fc2..9da4985 100644
Binary files a/test/reference/pthread-show-text.pdf.ref.png and b/test/reference/pthread-show-text.pdf.ref.png differ
diff --git a/test/reference/pthread-show-text.ps.ref.png b/test/reference/pthread-show-text.ps.ref.png
index 807b73f..7137e49 100644
Binary files a/test/reference/pthread-show-text.ps.ref.png and b/test/reference/pthread-show-text.ps.ref.png differ
diff --git a/test/reference/radial-gradient-extend.pdf.ref.png b/test/reference/radial-gradient-extend.pdf.ref.png
new file mode 100644
index 0000000..fb78785
Binary files /dev/null and b/test/reference/radial-gradient-extend.pdf.ref.png differ
diff --git a/test/reference/random-clip.pdf.argb32.ref.png b/test/reference/random-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..dc5c288
Binary files /dev/null and b/test/reference/random-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/random-clip.pdf.rgb24.ref.png b/test/reference/random-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..dc5c288
Binary files /dev/null and b/test/reference/random-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/random-clip.ps.argb32.ref.png b/test/reference/random-clip.ps.argb32.ref.png
new file mode 100644
index 0000000..531172f
Binary files /dev/null and b/test/reference/random-clip.ps.argb32.ref.png differ
diff --git a/test/reference/random-clip.ps.rgb24.ref.png b/test/reference/random-clip.ps.rgb24.ref.png
new file mode 100644
index 0000000..dc5c288
Binary files /dev/null and b/test/reference/random-clip.ps.rgb24.ref.png differ
diff --git a/test/reference/random-clip.ref.png b/test/reference/random-clip.ref.png
index de7a605..dc5c288 100644
Binary files a/test/reference/random-clip.ref.png and b/test/reference/random-clip.ref.png differ
diff --git a/test/reference/random-intersections-curves-eo.pdf.argb32.ref.png b/test/reference/random-intersections-curves-eo.pdf.argb32.ref.png
new file mode 100644
index 0000000..d13660f
Binary files /dev/null and b/test/reference/random-intersections-curves-eo.pdf.argb32.ref.png differ
diff --git a/test/reference/random-intersections-curves-eo.pdf.ref.png b/test/reference/random-intersections-curves-eo.pdf.ref.png
deleted file mode 100644
index befa3c8..0000000
Binary files a/test/reference/random-intersections-curves-eo.pdf.ref.png and /dev/null differ
diff --git a/test/reference/random-intersections-curves-eo.pdf.rgb24.ref.png b/test/reference/random-intersections-curves-eo.pdf.rgb24.ref.png
new file mode 100644
index 0000000..a11e712
Binary files /dev/null and b/test/reference/random-intersections-curves-eo.pdf.rgb24.ref.png differ
diff --git a/test/reference/random-intersections-curves-nz.pdf.argb32.ref.png b/test/reference/random-intersections-curves-nz.pdf.argb32.ref.png
new file mode 100644
index 0000000..ab6225c
Binary files /dev/null and b/test/reference/random-intersections-curves-nz.pdf.argb32.ref.png differ
diff --git a/test/reference/random-intersections-curves-nz.pdf.rgb24.ref.png b/test/reference/random-intersections-curves-nz.pdf.rgb24.ref.png
new file mode 100644
index 0000000..71c92e2
Binary files /dev/null and b/test/reference/random-intersections-curves-nz.pdf.rgb24.ref.png differ
diff --git a/test/reference/random-intersections-eo.pdf.ref.png b/test/reference/random-intersections-eo.pdf.ref.png
new file mode 100644
index 0000000..43e1842
Binary files /dev/null and b/test/reference/random-intersections-eo.pdf.ref.png differ
diff --git a/test/reference/random-intersections-eo.ref.png b/test/reference/random-intersections-eo.ref.png
index ccd3f80..2641c00 100644
Binary files a/test/reference/random-intersections-eo.ref.png and b/test/reference/random-intersections-eo.ref.png differ
diff --git a/test/reference/random-intersections-nonzero.pdf.ref.png b/test/reference/random-intersections-nonzero.pdf.ref.png
new file mode 100644
index 0000000..fce4909
Binary files /dev/null and b/test/reference/random-intersections-nonzero.pdf.ref.png differ
diff --git a/test/reference/random-intersections-nonzero.ref.png b/test/reference/random-intersections-nonzero.ref.png
index 6f02ea0..cc748d4 100644
Binary files a/test/reference/random-intersections-nonzero.ref.png and b/test/reference/random-intersections-nonzero.ref.png differ
diff --git a/test/reference/record-extend-none.ps.ref.png b/test/reference/record-extend-none.ps.ref.png
new file mode 100644
index 0000000..4d05beb
Binary files /dev/null and b/test/reference/record-extend-none.ps.ref.png differ
diff --git a/test/reference/record-extend-pad.ps.ref.png b/test/reference/record-extend-pad.ps.ref.png
new file mode 100644
index 0000000..0431d02
Binary files /dev/null and b/test/reference/record-extend-pad.ps.ref.png differ
diff --git a/test/reference/record-extend-reflect.ps.ref.png b/test/reference/record-extend-reflect.ps.ref.png
new file mode 100644
index 0000000..abdf27b
Binary files /dev/null and b/test/reference/record-extend-reflect.ps.ref.png differ
diff --git a/test/reference/record-extend-repeat.ps.ref.png b/test/reference/record-extend-repeat.ps.ref.png
new file mode 100644
index 0000000..1f06744
Binary files /dev/null and b/test/reference/record-extend-repeat.ps.ref.png differ
diff --git a/test/reference/record-fill-alpha.pdf.ref.png b/test/reference/record-fill-alpha.pdf.ref.png
new file mode 100644
index 0000000..8f72f68
Binary files /dev/null and b/test/reference/record-fill-alpha.pdf.ref.png differ
diff --git a/test/reference/record-fill-alpha.ref.png b/test/reference/record-fill-alpha.ref.png
index 25c1ac6..8f72f68 100644
Binary files a/test/reference/record-fill-alpha.ref.png and b/test/reference/record-fill-alpha.ref.png differ
diff --git a/test/reference/record-mesh.pdf.argb32.ref.png b/test/reference/record-mesh.pdf.argb32.ref.png
new file mode 100644
index 0000000..0155536
Binary files /dev/null and b/test/reference/record-mesh.pdf.argb32.ref.png differ
diff --git a/test/reference/record-mesh.pdf.rgb24.ref.png b/test/reference/record-mesh.pdf.rgb24.ref.png
new file mode 100644
index 0000000..f69db6e
Binary files /dev/null and b/test/reference/record-mesh.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-mesh.ps.ref.png b/test/reference/record-mesh.ps.ref.png
new file mode 100644
index 0000000..0155536
Binary files /dev/null and b/test/reference/record-mesh.ps.ref.png differ
diff --git a/test/reference/record-mesh.ref.png b/test/reference/record-mesh.ref.png
index 6e781b1..0155536 100644
Binary files a/test/reference/record-mesh.ref.png and b/test/reference/record-mesh.ref.png differ
diff --git a/test/reference/record-paint-alpha-clip-mask.pdf.argb32.ref.png b/test/reference/record-paint-alpha-clip-mask.pdf.argb32.ref.png
new file mode 100644
index 0000000..0233e44
Binary files /dev/null and b/test/reference/record-paint-alpha-clip-mask.pdf.argb32.ref.png differ
diff --git a/test/reference/record-paint-alpha-clip-mask.pdf.rgb24.ref.png b/test/reference/record-paint-alpha-clip-mask.pdf.rgb24.ref.png
new file mode 100644
index 0000000..e57369f
Binary files /dev/null and b/test/reference/record-paint-alpha-clip-mask.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-paint-alpha-clip-mask.ref.png b/test/reference/record-paint-alpha-clip-mask.ref.png
index 4ee4c41..0233e44 100644
Binary files a/test/reference/record-paint-alpha-clip-mask.ref.png and b/test/reference/record-paint-alpha-clip-mask.ref.png differ
diff --git a/test/reference/record-paint-alpha-clip.pdf.argb32.ref.png b/test/reference/record-paint-alpha-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..3303996
Binary files /dev/null and b/test/reference/record-paint-alpha-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/record-paint-alpha-clip.pdf.rgb24.ref.png b/test/reference/record-paint-alpha-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..c3dabc5
Binary files /dev/null and b/test/reference/record-paint-alpha-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-paint-alpha-solid-clip.pdf.ref.png b/test/reference/record-paint-alpha-solid-clip.pdf.ref.png
new file mode 100644
index 0000000..034ba6d
Binary files /dev/null and b/test/reference/record-paint-alpha-solid-clip.pdf.ref.png differ
diff --git a/test/reference/record-replay-extend-none.ps.argb32.ref.png b/test/reference/record-replay-extend-none.ps.argb32.ref.png
new file mode 100644
index 0000000..4b2f85f
Binary files /dev/null and b/test/reference/record-replay-extend-none.ps.argb32.ref.png differ
diff --git a/test/reference/record-replay-extend-none.ps.rgb24.ref.png b/test/reference/record-replay-extend-none.ps.rgb24.ref.png
new file mode 100644
index 0000000..a89a45f
Binary files /dev/null and b/test/reference/record-replay-extend-none.ps.rgb24.ref.png differ
diff --git a/test/reference/record-replay-extend-pad.ps.rgb24.ref.png b/test/reference/record-replay-extend-pad.ps.rgb24.ref.png
new file mode 100644
index 0000000..cd02486
Binary files /dev/null and b/test/reference/record-replay-extend-pad.ps.rgb24.ref.png differ
diff --git a/test/reference/record-replay-extend-reflect.ps.argb32.ref.png b/test/reference/record-replay-extend-reflect.ps.argb32.ref.png
new file mode 100644
index 0000000..32d26b0
Binary files /dev/null and b/test/reference/record-replay-extend-reflect.ps.argb32.ref.png differ
diff --git a/test/reference/record-replay-extend-repeat.ps.argb32.ref.png b/test/reference/record-replay-extend-repeat.ps.argb32.ref.png
new file mode 100644
index 0000000..15d3d55
Binary files /dev/null and b/test/reference/record-replay-extend-repeat.ps.argb32.ref.png differ
diff --git a/test/reference/record-replay-extend-repeat.ps.rgb24.ref.png b/test/reference/record-replay-extend-repeat.ps.rgb24.ref.png
new file mode 100644
index 0000000..fa25d48
Binary files /dev/null and b/test/reference/record-replay-extend-repeat.ps.rgb24.ref.png differ
diff --git a/test/reference/record-select-font-face.pdf.argb32.ref.png b/test/reference/record-select-font-face.pdf.argb32.ref.png
new file mode 100644
index 0000000..63c7cca
Binary files /dev/null and b/test/reference/record-select-font-face.pdf.argb32.ref.png differ
diff --git a/test/reference/record-select-font-face.pdf.rgb24.ref.png b/test/reference/record-select-font-face.pdf.rgb24.ref.png
new file mode 100644
index 0000000..bb2f69f
Binary files /dev/null and b/test/reference/record-select-font-face.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-select-font-face.ps.ref.png b/test/reference/record-select-font-face.ps.ref.png
new file mode 100644
index 0000000..ab63c85
Binary files /dev/null and b/test/reference/record-select-font-face.ps.ref.png differ
diff --git a/test/reference/record-select-font-face.ref.png b/test/reference/record-select-font-face.ref.png
index 1334a9a..63c7cca 100644
Binary files a/test/reference/record-select-font-face.ref.png and b/test/reference/record-select-font-face.ref.png differ
diff --git a/test/reference/record-self-intersecting.pdf.rgb24.ref.png b/test/reference/record-self-intersecting.pdf.rgb24.ref.png
new file mode 100644
index 0000000..83eeaad
Binary files /dev/null and b/test/reference/record-self-intersecting.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-self-intersecting.ps.ref.png b/test/reference/record-self-intersecting.ps.ref.png
new file mode 100644
index 0000000..84fde01
Binary files /dev/null and b/test/reference/record-self-intersecting.ps.ref.png differ
diff --git a/test/reference/record-text-transform.pdf.argb32.ref.png b/test/reference/record-text-transform.pdf.argb32.ref.png
new file mode 100644
index 0000000..8e74785
Binary files /dev/null and b/test/reference/record-text-transform.pdf.argb32.ref.png differ
diff --git a/test/reference/record-text-transform.pdf.rgb24.ref.png b/test/reference/record-text-transform.pdf.rgb24.ref.png
new file mode 100644
index 0000000..ffde12f
Binary files /dev/null and b/test/reference/record-text-transform.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-text-transform.ps.argb32.ref.png b/test/reference/record-text-transform.ps.argb32.ref.png
new file mode 100644
index 0000000..1aaaea5
Binary files /dev/null and b/test/reference/record-text-transform.ps.argb32.ref.png differ
diff --git a/test/reference/record-text-transform.ps.rgb24.ref.png b/test/reference/record-text-transform.ps.rgb24.ref.png
new file mode 100644
index 0000000..1aaaea5
Binary files /dev/null and b/test/reference/record-text-transform.ps.rgb24.ref.png differ
diff --git a/test/reference/record-text-transform.ref.png b/test/reference/record-text-transform.ref.png
index 4603bc5..8e74785 100644
Binary files a/test/reference/record-text-transform.ref.png and b/test/reference/record-text-transform.ref.png differ
diff --git a/test/reference/record1414x-fill-alpha.pdf.argb32.ref.png b/test/reference/record1414x-fill-alpha.pdf.argb32.ref.png
new file mode 100644
index 0000000..8d892d0
Binary files /dev/null and b/test/reference/record1414x-fill-alpha.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-fill-alpha.pdf.rgb24.ref.png b/test/reference/record1414x-fill-alpha.pdf.rgb24.ref.png
new file mode 100644
index 0000000..c38e243
Binary files /dev/null and b/test/reference/record1414x-fill-alpha.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-fill-alpha.ps.ref.png b/test/reference/record1414x-fill-alpha.ps.ref.png
new file mode 100644
index 0000000..444f353
Binary files /dev/null and b/test/reference/record1414x-fill-alpha.ps.ref.png differ
diff --git a/test/reference/record1414x-fill-alpha.ref.png b/test/reference/record1414x-fill-alpha.ref.png
index 8e9f322..fb0b320 100644
Binary files a/test/reference/record1414x-fill-alpha.ref.png and b/test/reference/record1414x-fill-alpha.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-clip-mask.pdf.argb32.ref.png b/test/reference/record1414x-paint-alpha-clip-mask.pdf.argb32.ref.png
new file mode 100644
index 0000000..5bb4bbd
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-clip-mask.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-clip-mask.pdf.rgb24.ref.png b/test/reference/record1414x-paint-alpha-clip-mask.pdf.rgb24.ref.png
new file mode 100644
index 0000000..b50b992
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-clip-mask.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-clip-mask.ps.ref.png b/test/reference/record1414x-paint-alpha-clip-mask.ps.ref.png
new file mode 100644
index 0000000..835bf04
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-clip-mask.ps.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-clip-mask.ref.png b/test/reference/record1414x-paint-alpha-clip-mask.ref.png
index e381b73..78442bd 100644
Binary files a/test/reference/record1414x-paint-alpha-clip-mask.ref.png and b/test/reference/record1414x-paint-alpha-clip-mask.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-clip.pdf.argb32.ref.png b/test/reference/record1414x-paint-alpha-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..31a2143
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-clip.pdf.rgb24.ref.png b/test/reference/record1414x-paint-alpha-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..1e6e1f6
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-clip.ps.ref.png b/test/reference/record1414x-paint-alpha-clip.ps.ref.png
new file mode 100644
index 0000000..13b1163
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-clip.ps.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-solid-clip.pdf.argb32.ref.png b/test/reference/record1414x-paint-alpha-solid-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..21b02b8
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-solid-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-solid-clip.pdf.rgb24.ref.png b/test/reference/record1414x-paint-alpha-solid-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..d3f7e57
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-solid-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha-solid-clip.ps.ref.png b/test/reference/record1414x-paint-alpha-solid-clip.ps.ref.png
new file mode 100644
index 0000000..811c8aa
Binary files /dev/null and b/test/reference/record1414x-paint-alpha-solid-clip.ps.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha.pdf.argb32.ref.png b/test/reference/record1414x-paint-alpha.pdf.argb32.ref.png
new file mode 100644
index 0000000..5d5d797
Binary files /dev/null and b/test/reference/record1414x-paint-alpha.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha.pdf.rgb24.ref.png b/test/reference/record1414x-paint-alpha.pdf.rgb24.ref.png
new file mode 100644
index 0000000..6a80a83
Binary files /dev/null and b/test/reference/record1414x-paint-alpha.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-paint-alpha.ps.ref.png b/test/reference/record1414x-paint-alpha.ps.ref.png
new file mode 100644
index 0000000..7460886
Binary files /dev/null and b/test/reference/record1414x-paint-alpha.ps.ref.png differ
diff --git a/test/reference/record1414x-select-font-face.pdf.argb32.ref.png b/test/reference/record1414x-select-font-face.pdf.argb32.ref.png
new file mode 100644
index 0000000..ac30b23
Binary files /dev/null and b/test/reference/record1414x-select-font-face.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-select-font-face.pdf.rgb24.ref.png b/test/reference/record1414x-select-font-face.pdf.rgb24.ref.png
new file mode 100644
index 0000000..cdc3ce8
Binary files /dev/null and b/test/reference/record1414x-select-font-face.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-select-font-face.ps.argb32.ref.png b/test/reference/record1414x-select-font-face.ps.argb32.ref.png
new file mode 100644
index 0000000..37da5e1
Binary files /dev/null and b/test/reference/record1414x-select-font-face.ps.argb32.ref.png differ
diff --git a/test/reference/record1414x-select-font-face.ps.rgb24.ref.png b/test/reference/record1414x-select-font-face.ps.rgb24.ref.png
new file mode 100644
index 0000000..97b19be
Binary files /dev/null and b/test/reference/record1414x-select-font-face.ps.rgb24.ref.png differ
diff --git a/test/reference/record1414x-select-font-face.ref.png b/test/reference/record1414x-select-font-face.ref.png
index 6c52067..ac30b23 100644
Binary files a/test/reference/record1414x-select-font-face.ref.png and b/test/reference/record1414x-select-font-face.ref.png differ
diff --git a/test/reference/record1414x-self-intersecting.pdf.argb32.ref.png b/test/reference/record1414x-self-intersecting.pdf.argb32.ref.png
new file mode 100644
index 0000000..62f91c9
Binary files /dev/null and b/test/reference/record1414x-self-intersecting.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-self-intersecting.pdf.rgb24.ref.png b/test/reference/record1414x-self-intersecting.pdf.rgb24.ref.png
new file mode 100644
index 0000000..5fa2deb
Binary files /dev/null and b/test/reference/record1414x-self-intersecting.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-self-intersecting.ps.argb32.ref.png b/test/reference/record1414x-self-intersecting.ps.argb32.ref.png
new file mode 100644
index 0000000..c6f483e
Binary files /dev/null and b/test/reference/record1414x-self-intersecting.ps.argb32.ref.png differ
diff --git a/test/reference/record1414x-self-intersecting.ps.rgb24.ref.png b/test/reference/record1414x-self-intersecting.ps.rgb24.ref.png
new file mode 100644
index 0000000..d7e2af5
Binary files /dev/null and b/test/reference/record1414x-self-intersecting.ps.rgb24.ref.png differ
diff --git a/test/reference/record1414x-text-transform.pdf.argb32.ref.png b/test/reference/record1414x-text-transform.pdf.argb32.ref.png
new file mode 100644
index 0000000..60de60a
Binary files /dev/null and b/test/reference/record1414x-text-transform.pdf.argb32.ref.png differ
diff --git a/test/reference/record1414x-text-transform.pdf.rgb24.ref.png b/test/reference/record1414x-text-transform.pdf.rgb24.ref.png
new file mode 100644
index 0000000..9b90c97
Binary files /dev/null and b/test/reference/record1414x-text-transform.pdf.rgb24.ref.png differ
diff --git a/test/reference/record1414x-text-transform.ps.ref.png b/test/reference/record1414x-text-transform.ps.ref.png
new file mode 100644
index 0000000..bbf4f52
Binary files /dev/null and b/test/reference/record1414x-text-transform.ps.ref.png differ
diff --git a/test/reference/record1414x-text-transform.ref.png b/test/reference/record1414x-text-transform.ref.png
index 3bb8b12..ef3c967 100644
Binary files a/test/reference/record1414x-text-transform.ref.png and b/test/reference/record1414x-text-transform.ref.png differ
diff --git a/test/reference/record2x-fill-alpha.pdf.argb32.ref.png b/test/reference/record2x-fill-alpha.pdf.argb32.ref.png
new file mode 100644
index 0000000..c4d7965
Binary files /dev/null and b/test/reference/record2x-fill-alpha.pdf.argb32.ref.png differ
diff --git a/test/reference/record2x-fill-alpha.pdf.rgb24.ref.png b/test/reference/record2x-fill-alpha.pdf.rgb24.ref.png
new file mode 100644
index 0000000..9bbe8b8
Binary files /dev/null and b/test/reference/record2x-fill-alpha.pdf.rgb24.ref.png differ
diff --git a/test/reference/record2x-fill-alpha.ps.ref.png b/test/reference/record2x-fill-alpha.ps.ref.png
new file mode 100644
index 0000000..c4d7965
Binary files /dev/null and b/test/reference/record2x-fill-alpha.ps.ref.png differ
diff --git a/test/reference/record2x-fill-alpha.ref.png b/test/reference/record2x-fill-alpha.ref.png
index 91787bd..9bbe8b8 100644
Binary files a/test/reference/record2x-fill-alpha.ref.png and b/test/reference/record2x-fill-alpha.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-clip-mask.pdf.argb32.ref.png b/test/reference/record2x-paint-alpha-clip-mask.pdf.argb32.ref.png
new file mode 100644
index 0000000..dd1ca05
Binary files /dev/null and b/test/reference/record2x-paint-alpha-clip-mask.pdf.argb32.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-clip-mask.pdf.rgb24.ref.png b/test/reference/record2x-paint-alpha-clip-mask.pdf.rgb24.ref.png
new file mode 100644
index 0000000..f7a20d3
Binary files /dev/null and b/test/reference/record2x-paint-alpha-clip-mask.pdf.rgb24.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-clip-mask.ps.ref.png b/test/reference/record2x-paint-alpha-clip-mask.ps.ref.png
new file mode 100644
index 0000000..dd1ca05
Binary files /dev/null and b/test/reference/record2x-paint-alpha-clip-mask.ps.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-clip-mask.ref.png b/test/reference/record2x-paint-alpha-clip-mask.ref.png
index dd1ca05..938440b 100644
Binary files a/test/reference/record2x-paint-alpha-clip-mask.ref.png and b/test/reference/record2x-paint-alpha-clip-mask.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-clip.pdf.argb32.ref.png b/test/reference/record2x-paint-alpha-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..56dcc79
Binary files /dev/null and b/test/reference/record2x-paint-alpha-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-clip.pdf.rgb24.ref.png b/test/reference/record2x-paint-alpha-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..2dc5ee4
Binary files /dev/null and b/test/reference/record2x-paint-alpha-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-solid-clip.pdf.argb32.ref.png b/test/reference/record2x-paint-alpha-solid-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..449bc5a
Binary files /dev/null and b/test/reference/record2x-paint-alpha-solid-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/record2x-paint-alpha-solid-clip.pdf.rgb24.ref.png b/test/reference/record2x-paint-alpha-solid-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..b22ac6d
Binary files /dev/null and b/test/reference/record2x-paint-alpha-solid-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/record2x-paint-alpha.pdf.argb32.ref.png b/test/reference/record2x-paint-alpha.pdf.argb32.ref.png
new file mode 100644
index 0000000..f53c7f9
Binary files /dev/null and b/test/reference/record2x-paint-alpha.pdf.argb32.ref.png differ
diff --git a/test/reference/record2x-paint-alpha.pdf.rgb24.ref.png b/test/reference/record2x-paint-alpha.pdf.rgb24.ref.png
new file mode 100644
index 0000000..41b8cf1
Binary files /dev/null and b/test/reference/record2x-paint-alpha.pdf.rgb24.ref.png differ
diff --git a/test/reference/record2x-select-font-face.pdf.rgb24.ref.png b/test/reference/record2x-select-font-face.pdf.rgb24.ref.png
new file mode 100644
index 0000000..ed64d7c
Binary files /dev/null and b/test/reference/record2x-select-font-face.pdf.rgb24.ref.png differ
diff --git a/test/reference/record2x-select-font-face.ps.ref.png b/test/reference/record2x-select-font-face.ps.ref.png
new file mode 100644
index 0000000..71eee7c
Binary files /dev/null and b/test/reference/record2x-select-font-face.ps.ref.png differ
diff --git a/test/reference/record2x-select-font-face.ref.png b/test/reference/record2x-select-font-face.ref.png
index 7a99795..32c1367 100644
Binary files a/test/reference/record2x-select-font-face.ref.png and b/test/reference/record2x-select-font-face.ref.png differ
diff --git a/test/reference/record2x-text-transform.pdf.argb32.ref.png b/test/reference/record2x-text-transform.pdf.argb32.ref.png
new file mode 100644
index 0000000..9811c1b
Binary files /dev/null and b/test/reference/record2x-text-transform.pdf.argb32.ref.png differ
diff --git a/test/reference/record2x-text-transform.pdf.rgb24.ref.png b/test/reference/record2x-text-transform.pdf.rgb24.ref.png
new file mode 100644
index 0000000..35b5ce9
Binary files /dev/null and b/test/reference/record2x-text-transform.pdf.rgb24.ref.png differ
diff --git a/test/reference/record2x-text-transform.ps.ref.png b/test/reference/record2x-text-transform.ps.ref.png
new file mode 100644
index 0000000..f562802
Binary files /dev/null and b/test/reference/record2x-text-transform.ps.ref.png differ
diff --git a/test/reference/record2x-text-transform.ref.png b/test/reference/record2x-text-transform.ref.png
index 6c21785..ff521ab 100644
Binary files a/test/reference/record2x-text-transform.ref.png and b/test/reference/record2x-text-transform.ref.png differ
diff --git a/test/reference/record90-fill-alpha.pdf.ref.png b/test/reference/record90-fill-alpha.pdf.ref.png
new file mode 100644
index 0000000..167d7be
Binary files /dev/null and b/test/reference/record90-fill-alpha.pdf.ref.png differ
diff --git a/test/reference/record90-fill-alpha.pdf.rgb24.ref.png b/test/reference/record90-fill-alpha.pdf.rgb24.ref.png
new file mode 100644
index 0000000..ee01f5f
Binary files /dev/null and b/test/reference/record90-fill-alpha.pdf.rgb24.ref.png differ
diff --git a/test/reference/record90-fill-alpha.ref.png b/test/reference/record90-fill-alpha.ref.png
index bf3b260..167d7be 100644
Binary files a/test/reference/record90-fill-alpha.ref.png and b/test/reference/record90-fill-alpha.ref.png differ
diff --git a/test/reference/record90-paint-alpha-clip-mask.pdf.argb32.ref.png b/test/reference/record90-paint-alpha-clip-mask.pdf.argb32.ref.png
new file mode 100644
index 0000000..3ddf95c
Binary files /dev/null and b/test/reference/record90-paint-alpha-clip-mask.pdf.argb32.ref.png differ
diff --git a/test/reference/record90-paint-alpha-clip-mask.pdf.rgb24.ref.png b/test/reference/record90-paint-alpha-clip-mask.pdf.rgb24.ref.png
new file mode 100644
index 0000000..e6bc208
Binary files /dev/null and b/test/reference/record90-paint-alpha-clip-mask.pdf.rgb24.ref.png differ
diff --git a/test/reference/record90-paint-alpha-clip.pdf.argb32.ref.png b/test/reference/record90-paint-alpha-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..b7703d4
Binary files /dev/null and b/test/reference/record90-paint-alpha-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/record90-paint-alpha-clip.pdf.rgb24.ref.png b/test/reference/record90-paint-alpha-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..aac3c29
Binary files /dev/null and b/test/reference/record90-paint-alpha-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/record90-paint-alpha-clip.ref.png b/test/reference/record90-paint-alpha-clip.ref.png
index 3fae802..b7703d4 100644
Binary files a/test/reference/record90-paint-alpha-clip.ref.png and b/test/reference/record90-paint-alpha-clip.ref.png differ
diff --git a/test/reference/record90-paint-alpha-solid-clip.pdf.argb32.ref.png b/test/reference/record90-paint-alpha-solid-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..17bff57
Binary files /dev/null and b/test/reference/record90-paint-alpha-solid-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/record90-paint-alpha-solid-clip.pdf.rgb24.ref.png b/test/reference/record90-paint-alpha-solid-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..260be21
Binary files /dev/null and b/test/reference/record90-paint-alpha-solid-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/record90-paint-alpha.ps.ref.png b/test/reference/record90-paint-alpha.ps.ref.png
new file mode 100644
index 0000000..7b7998e
Binary files /dev/null and b/test/reference/record90-paint-alpha.ps.ref.png differ
diff --git a/test/reference/record90-select-font-face.pdf.rgb24.ref.png b/test/reference/record90-select-font-face.pdf.rgb24.ref.png
new file mode 100644
index 0000000..463875d
Binary files /dev/null and b/test/reference/record90-select-font-face.pdf.rgb24.ref.png differ
diff --git a/test/reference/record90-select-font-face.ps.ref.png b/test/reference/record90-select-font-face.ps.ref.png
new file mode 100644
index 0000000..58e6625
Binary files /dev/null and b/test/reference/record90-select-font-face.ps.ref.png differ
diff --git a/test/reference/record90-select-font-face.ref.png b/test/reference/record90-select-font-face.ref.png
index 189a315..13ed998 100644
Binary files a/test/reference/record90-select-font-face.ref.png and b/test/reference/record90-select-font-face.ref.png differ
diff --git a/test/reference/record90-self-intersecting.pdf.rgb24.ref.png b/test/reference/record90-self-intersecting.pdf.rgb24.ref.png
new file mode 100644
index 0000000..3a960c7
Binary files /dev/null and b/test/reference/record90-self-intersecting.pdf.rgb24.ref.png differ
diff --git a/test/reference/record90-self-intersecting.ps.ref.png b/test/reference/record90-self-intersecting.ps.ref.png
new file mode 100644
index 0000000..3bcc7fb
Binary files /dev/null and b/test/reference/record90-self-intersecting.ps.ref.png differ
diff --git a/test/reference/record90-self-intersecting.ref.png b/test/reference/record90-self-intersecting.ref.png
index 15ce4c0..f4f34ce 100644
Binary files a/test/reference/record90-self-intersecting.ref.png and b/test/reference/record90-self-intersecting.ref.png differ
diff --git a/test/reference/record90-text-transform.pdf.rgb24.ref.png b/test/reference/record90-text-transform.pdf.rgb24.ref.png
new file mode 100644
index 0000000..96ff2c4
Binary files /dev/null and b/test/reference/record90-text-transform.pdf.rgb24.ref.png differ
diff --git a/test/reference/record90-text-transform.ps.ref.png b/test/reference/record90-text-transform.ps.ref.png
new file mode 100644
index 0000000..2e0bbfb
Binary files /dev/null and b/test/reference/record90-text-transform.ps.ref.png differ
diff --git a/test/reference/record90-text-transform.ref.png b/test/reference/record90-text-transform.ref.png
index 22f6c1f..e8fa722 100644
Binary files a/test/reference/record90-text-transform.ref.png and b/test/reference/record90-text-transform.ref.png differ
diff --git a/test/reference/recordflip-fill-alpha.ref.png b/test/reference/recordflip-fill-alpha.ref.png
index 289a915..c80c351 100644
Binary files a/test/reference/recordflip-fill-alpha.ref.png and b/test/reference/recordflip-fill-alpha.ref.png differ
diff --git a/test/reference/recordflip-paint-alpha-clip-mask.pdf.rgb24.ref.png b/test/reference/recordflip-paint-alpha-clip-mask.pdf.rgb24.ref.png
new file mode 100644
index 0000000..c9eaf2d
Binary files /dev/null and b/test/reference/recordflip-paint-alpha-clip-mask.pdf.rgb24.ref.png differ
diff --git a/test/reference/recordflip-paint-alpha-clip-mask.ref.png b/test/reference/recordflip-paint-alpha-clip-mask.ref.png
index 842fa35..b824723 100644
Binary files a/test/reference/recordflip-paint-alpha-clip-mask.ref.png and b/test/reference/recordflip-paint-alpha-clip-mask.ref.png differ
diff --git a/test/reference/recordflip-paint-alpha-clip.pdf.rgb24.ref.png b/test/reference/recordflip-paint-alpha-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..22f7dfe
Binary files /dev/null and b/test/reference/recordflip-paint-alpha-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/recordflip-select-font-face.pdf.rgb24.ref.png b/test/reference/recordflip-select-font-face.pdf.rgb24.ref.png
new file mode 100644
index 0000000..3660617
Binary files /dev/null and b/test/reference/recordflip-select-font-face.pdf.rgb24.ref.png differ
diff --git a/test/reference/recordflip-select-font-face.ps.argb32.ref.png b/test/reference/recordflip-select-font-face.ps.argb32.ref.png
new file mode 100644
index 0000000..086e5e9
Binary files /dev/null and b/test/reference/recordflip-select-font-face.ps.argb32.ref.png differ
diff --git a/test/reference/recordflip-select-font-face.ps.rgb24.ref.png b/test/reference/recordflip-select-font-face.ps.rgb24.ref.png
new file mode 100644
index 0000000..086e5e9
Binary files /dev/null and b/test/reference/recordflip-select-font-face.ps.rgb24.ref.png differ
diff --git a/test/reference/recordflip-select-font-face.ref.png b/test/reference/recordflip-select-font-face.ref.png
index eb71085..bedb1ca 100644
Binary files a/test/reference/recordflip-select-font-face.ref.png and b/test/reference/recordflip-select-font-face.ref.png differ
diff --git a/test/reference/recordflip-self-intersecting.pdf.rgb24.ref.png b/test/reference/recordflip-self-intersecting.pdf.rgb24.ref.png
new file mode 100644
index 0000000..05eb9f6
Binary files /dev/null and b/test/reference/recordflip-self-intersecting.pdf.rgb24.ref.png differ
diff --git a/test/reference/recordflip-self-intersecting.ps.ref.png b/test/reference/recordflip-self-intersecting.ps.ref.png
new file mode 100644
index 0000000..84fde01
Binary files /dev/null and b/test/reference/recordflip-self-intersecting.ps.ref.png differ
diff --git a/test/reference/recordflip-text-transform.pdf.rgb24.ref.png b/test/reference/recordflip-text-transform.pdf.rgb24.ref.png
new file mode 100644
index 0000000..a5826a1
Binary files /dev/null and b/test/reference/recordflip-text-transform.pdf.rgb24.ref.png differ
diff --git a/test/reference/recordflip-text-transform.ps.argb32.ref.png b/test/reference/recordflip-text-transform.ps.argb32.ref.png
new file mode 100644
index 0000000..beed4bf
Binary files /dev/null and b/test/reference/recordflip-text-transform.ps.argb32.ref.png differ
diff --git a/test/reference/recordflip-text-transform.ps.rgb24.ref.png b/test/reference/recordflip-text-transform.ps.rgb24.ref.png
new file mode 100644
index 0000000..beed4bf
Binary files /dev/null and b/test/reference/recordflip-text-transform.ps.rgb24.ref.png differ
diff --git a/test/reference/recordflip-text-transform.ref.png b/test/reference/recordflip-text-transform.ref.png
index 31784d7..ccf5e33 100644
Binary files a/test/reference/recordflip-text-transform.ref.png and b/test/reference/recordflip-text-transform.ref.png differ
diff --git a/test/reference/recordflip-whole-fill-alpha.ref.png b/test/reference/recordflip-whole-fill-alpha.ref.png
index 289a915..69035ef 100644
Binary files a/test/reference/recordflip-whole-fill-alpha.ref.png and b/test/reference/recordflip-whole-fill-alpha.ref.png differ
diff --git a/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png b/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png
index 842fa35..6f14ad3 100644
Binary files a/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png and b/test/reference/recordflip-whole-paint-alpha-clip-mask.ref.png differ
diff --git a/test/reference/recordflip-whole-select-font-face.ref.png b/test/reference/recordflip-whole-select-font-face.ref.png
index eb71085..bedb1ca 100644
Binary files a/test/reference/recordflip-whole-select-font-face.ref.png and b/test/reference/recordflip-whole-select-font-face.ref.png differ
diff --git a/test/reference/recordflip-whole-text-transform.ref.png b/test/reference/recordflip-whole-text-transform.ref.png
index 31784d7..ccf5e33 100644
Binary files a/test/reference/recordflip-whole-text-transform.ref.png and b/test/reference/recordflip-whole-text-transform.ref.png differ
diff --git a/test/reference/recording-surface-extend-none.pdf.argb32.ref.png b/test/reference/recording-surface-extend-none.pdf.argb32.ref.png
new file mode 100644
index 0000000..812f9ee
Binary files /dev/null and b/test/reference/recording-surface-extend-none.pdf.argb32.ref.png differ
diff --git a/test/reference/recording-surface-extend-none.pdf.rgb24.ref.png b/test/reference/recording-surface-extend-none.pdf.rgb24.ref.png
new file mode 100644
index 0000000..d7bf21b
Binary files /dev/null and b/test/reference/recording-surface-extend-none.pdf.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-extend-none.ps.argb32.ref.png b/test/reference/recording-surface-extend-none.ps.argb32.ref.png
new file mode 100644
index 0000000..d2db401
Binary files /dev/null and b/test/reference/recording-surface-extend-none.ps.argb32.ref.png differ
diff --git a/test/reference/recording-surface-extend-none.ps.rgb24.ref.png b/test/reference/recording-surface-extend-none.ps.rgb24.ref.png
new file mode 100644
index 0000000..1a5b908
Binary files /dev/null and b/test/reference/recording-surface-extend-none.ps.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-extend-reflect.pdf.argb32.ref.png b/test/reference/recording-surface-extend-reflect.pdf.argb32.ref.png
new file mode 100644
index 0000000..a980fd5
Binary files /dev/null and b/test/reference/recording-surface-extend-reflect.pdf.argb32.ref.png differ
diff --git a/test/reference/recording-surface-extend-reflect.pdf.rgb24.ref.png b/test/reference/recording-surface-extend-reflect.pdf.rgb24.ref.png
new file mode 100644
index 0000000..45ca3c6
Binary files /dev/null and b/test/reference/recording-surface-extend-reflect.pdf.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-extend-reflect.ps.argb32.ref.png b/test/reference/recording-surface-extend-reflect.ps.argb32.ref.png
new file mode 100644
index 0000000..d9f3573
Binary files /dev/null and b/test/reference/recording-surface-extend-reflect.ps.argb32.ref.png differ
diff --git a/test/reference/recording-surface-extend-reflect.ps.rgb24.ref.png b/test/reference/recording-surface-extend-reflect.ps.rgb24.ref.png
new file mode 100644
index 0000000..9e43713
Binary files /dev/null and b/test/reference/recording-surface-extend-reflect.ps.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-extend-repeat.pdf.argb32.ref.png b/test/reference/recording-surface-extend-repeat.pdf.argb32.ref.png
new file mode 100644
index 0000000..8ff6587
Binary files /dev/null and b/test/reference/recording-surface-extend-repeat.pdf.argb32.ref.png differ
diff --git a/test/reference/recording-surface-extend-repeat.pdf.rgb24.ref.png b/test/reference/recording-surface-extend-repeat.pdf.rgb24.ref.png
new file mode 100644
index 0000000..e1dccd9
Binary files /dev/null and b/test/reference/recording-surface-extend-repeat.pdf.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-extend-repeat.ps.argb32.ref.png b/test/reference/recording-surface-extend-repeat.ps.argb32.ref.png
new file mode 100644
index 0000000..b12aa17
Binary files /dev/null and b/test/reference/recording-surface-extend-repeat.ps.argb32.ref.png differ
diff --git a/test/reference/recording-surface-extend-repeat.ps.rgb24.ref.png b/test/reference/recording-surface-extend-repeat.ps.rgb24.ref.png
new file mode 100644
index 0000000..870027b
Binary files /dev/null and b/test/reference/recording-surface-extend-repeat.ps.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-over.pdf.argb32.ref.png b/test/reference/recording-surface-over.pdf.argb32.ref.png
index a06386b..812f9ee 100644
Binary files a/test/reference/recording-surface-over.pdf.argb32.ref.png and b/test/reference/recording-surface-over.pdf.argb32.ref.png differ
diff --git a/test/reference/recording-surface-over.pdf.rgb24.ref.png b/test/reference/recording-surface-over.pdf.rgb24.ref.png
index bf69f9e..d7bf21b 100644
Binary files a/test/reference/recording-surface-over.pdf.rgb24.ref.png and b/test/reference/recording-surface-over.pdf.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-over.ps.argb32.ref.png b/test/reference/recording-surface-over.ps.argb32.ref.png
index ac66323..d2db401 100644
Binary files a/test/reference/recording-surface-over.ps.argb32.ref.png and b/test/reference/recording-surface-over.ps.argb32.ref.png differ
diff --git a/test/reference/recording-surface-over.ps.rgb24.ref.png b/test/reference/recording-surface-over.ps.rgb24.ref.png
index fab3382..1a5b908 100644
Binary files a/test/reference/recording-surface-over.ps.rgb24.ref.png and b/test/reference/recording-surface-over.ps.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-source.pdf.argb32.ref.png b/test/reference/recording-surface-source.pdf.argb32.ref.png
new file mode 100644
index 0000000..d2db401
Binary files /dev/null and b/test/reference/recording-surface-source.pdf.argb32.ref.png differ
diff --git a/test/reference/recording-surface-source.pdf.rgb24.ref.png b/test/reference/recording-surface-source.pdf.rgb24.ref.png
new file mode 100644
index 0000000..1a5b908
Binary files /dev/null and b/test/reference/recording-surface-source.pdf.rgb24.ref.png differ
diff --git a/test/reference/recording-surface-source.ps.argb32.ref.png b/test/reference/recording-surface-source.ps.argb32.ref.png
new file mode 100644
index 0000000..d2db401
Binary files /dev/null and b/test/reference/recording-surface-source.ps.argb32.ref.png differ
diff --git a/test/reference/recording-surface-source.ps.rgb24.ref.png b/test/reference/recording-surface-source.ps.rgb24.ref.png
new file mode 100644
index 0000000..1a5b908
Binary files /dev/null and b/test/reference/recording-surface-source.ps.rgb24.ref.png differ
diff --git a/test/reference/rectilinear-dash-scale-unaligned.pdf.ref.png b/test/reference/rectilinear-dash-scale-unaligned.pdf.ref.png
new file mode 100644
index 0000000..b05e293
Binary files /dev/null and b/test/reference/rectilinear-dash-scale-unaligned.pdf.ref.png differ
diff --git a/test/reference/rectilinear-dash-scale-unaligned.ps.ref.png b/test/reference/rectilinear-dash-scale-unaligned.ps.ref.png
new file mode 100644
index 0000000..b55a18d
Binary files /dev/null and b/test/reference/rectilinear-dash-scale-unaligned.ps.ref.png differ
diff --git a/test/reference/reflected-stroke.pdf.ref.png b/test/reference/reflected-stroke.pdf.ref.png
new file mode 100644
index 0000000..efae740
Binary files /dev/null and b/test/reference/reflected-stroke.pdf.ref.png differ
diff --git a/test/reference/rotate-clip-image-surface-paint.pdf.argb32.png b/test/reference/rotate-clip-image-surface-paint.pdf.argb32.png
new file mode 100644
index 0000000..591e9a0
Binary files /dev/null and b/test/reference/rotate-clip-image-surface-paint.pdf.argb32.png differ
diff --git a/test/reference/rotate-clip-image-surface-paint.pdf.rgb24.png b/test/reference/rotate-clip-image-surface-paint.pdf.rgb24.png
new file mode 100644
index 0000000..c1e357e
Binary files /dev/null and b/test/reference/rotate-clip-image-surface-paint.pdf.rgb24.png differ
diff --git a/test/reference/rotate-clip-image-surface-paint.ps.argb32.png b/test/reference/rotate-clip-image-surface-paint.ps.argb32.png
new file mode 100644
index 0000000..159a515
Binary files /dev/null and b/test/reference/rotate-clip-image-surface-paint.ps.argb32.png differ
diff --git a/test/reference/rotated-clip.pdf.ref.png b/test/reference/rotated-clip.pdf.ref.png
new file mode 100644
index 0000000..fd8707a
Binary files /dev/null and b/test/reference/rotated-clip.pdf.ref.png differ
diff --git a/test/reference/rotated-clip.ps.argb32.png b/test/reference/rotated-clip.ps.argb32.png
new file mode 100644
index 0000000..e26d118
Binary files /dev/null and b/test/reference/rotated-clip.ps.argb32.png differ
diff --git a/test/reference/rotated-clip.ps.argb32.ref.png b/test/reference/rotated-clip.ps.argb32.ref.png
new file mode 100644
index 0000000..e26d118
Binary files /dev/null and b/test/reference/rotated-clip.ps.argb32.ref.png differ
diff --git a/test/reference/rotated-clip.ps.ref.png b/test/reference/rotated-clip.ps.ref.png
deleted file mode 100644
index a2a0ace..0000000
Binary files a/test/reference/rotated-clip.ps.ref.png and /dev/null differ
diff --git a/test/reference/rotated-clip.ps.rgb24.ref.png b/test/reference/rotated-clip.ps.rgb24.ref.png
new file mode 100644
index 0000000..f5468c7
Binary files /dev/null and b/test/reference/rotated-clip.ps.rgb24.ref.png differ
diff --git a/test/reference/scale-offset-image.pdf.argb32.ref.png b/test/reference/scale-offset-image.pdf.argb32.ref.png
deleted file mode 100644
index 74abfae..0000000
Binary files a/test/reference/scale-offset-image.pdf.argb32.ref.png and /dev/null differ
diff --git a/test/reference/scale-offset-image.pdf.ref.png b/test/reference/scale-offset-image.pdf.ref.png
new file mode 100644
index 0000000..588c961
Binary files /dev/null and b/test/reference/scale-offset-image.pdf.ref.png differ
diff --git a/test/reference/scale-offset-image.pdf.rgb24.ref.png b/test/reference/scale-offset-image.pdf.rgb24.ref.png
deleted file mode 100644
index 74abfae..0000000
Binary files a/test/reference/scale-offset-image.pdf.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/scale-offset-image.ref.png b/test/reference/scale-offset-image.ref.png
index ab1ced8..085029f 100644
Binary files a/test/reference/scale-offset-image.ref.png and b/test/reference/scale-offset-image.ref.png differ
diff --git a/test/reference/scale-offset-similar.pdf.argb32.ref.png b/test/reference/scale-offset-similar.pdf.argb32.ref.png
deleted file mode 100644
index c1e2765..0000000
Binary files a/test/reference/scale-offset-similar.pdf.argb32.ref.png and /dev/null differ
diff --git a/test/reference/scale-offset-similar.pdf.ref.png b/test/reference/scale-offset-similar.pdf.ref.png
new file mode 100644
index 0000000..f2af6ad
Binary files /dev/null and b/test/reference/scale-offset-similar.pdf.ref.png differ
diff --git a/test/reference/scale-offset-similar.pdf.rgb24.ref.png b/test/reference/scale-offset-similar.pdf.rgb24.ref.png
deleted file mode 100644
index c1e2765..0000000
Binary files a/test/reference/scale-offset-similar.pdf.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/scale-offset-similar.ref.png b/test/reference/scale-offset-similar.ref.png
index 8b3649a..085029f 100644
Binary files a/test/reference/scale-offset-similar.ref.png and b/test/reference/scale-offset-similar.ref.png differ
diff --git a/test/reference/self-intersecting.ref.png b/test/reference/self-intersecting.ref.png
deleted file mode 100644
index d554d83..0000000
Binary files a/test/reference/self-intersecting.ref.png and /dev/null differ
diff --git a/test/reference/shape-sierpinski.pdf.argb32.ref.png b/test/reference/shape-sierpinski.pdf.argb32.ref.png
deleted file mode 100644
index 4e70fbd..0000000
Binary files a/test/reference/shape-sierpinski.pdf.argb32.ref.png and /dev/null differ
diff --git a/test/reference/shape-sierpinski.pdf.ref.png b/test/reference/shape-sierpinski.pdf.ref.png
new file mode 100644
index 0000000..786d8d2
Binary files /dev/null and b/test/reference/shape-sierpinski.pdf.ref.png differ
diff --git a/test/reference/shape-sierpinski.pdf.rgb24.ref.png b/test/reference/shape-sierpinski.pdf.rgb24.ref.png
deleted file mode 100644
index 4e70fbd..0000000
Binary files a/test/reference/shape-sierpinski.pdf.rgb24.ref.png and /dev/null differ
diff --git a/test/reference/simple-edge.ref.png b/test/reference/simple-edge.ref.png
index 4757b0a..8ba7dd3 100644
Binary files a/test/reference/simple-edge.ref.png and b/test/reference/simple-edge.ref.png differ
diff --git a/test/reference/smask-fill.pdf.ref.png b/test/reference/smask-fill.pdf.ref.png
index cfd40b0..420295a 100644
Binary files a/test/reference/smask-fill.pdf.ref.png and b/test/reference/smask-fill.pdf.ref.png differ
diff --git a/test/reference/smask-image-mask.pdf.ref.png b/test/reference/smask-image-mask.pdf.ref.png
index 7ac43e4..03201af 100644
Binary files a/test/reference/smask-image-mask.pdf.ref.png and b/test/reference/smask-image-mask.pdf.ref.png differ
diff --git a/test/reference/smask-mask.pdf.ref.png b/test/reference/smask-mask.pdf.ref.png
index 59c9740..4d25ac9 100644
Binary files a/test/reference/smask-mask.pdf.ref.png and b/test/reference/smask-mask.pdf.ref.png differ
diff --git a/test/reference/smask-paint.pdf.ref.png b/test/reference/smask-paint.pdf.ref.png
index 623a92d..9d4c6ce 100644
Binary files a/test/reference/smask-paint.pdf.ref.png and b/test/reference/smask-paint.pdf.ref.png differ
diff --git a/test/reference/smask-stroke.pdf.ref.png b/test/reference/smask-stroke.pdf.ref.png
new file mode 100644
index 0000000..f6ddb19
Binary files /dev/null and b/test/reference/smask-stroke.pdf.ref.png differ
diff --git a/test/reference/smask-text.pdf.ref.png b/test/reference/smask-text.pdf.ref.png
index fa49056..6b94f4a 100644
Binary files a/test/reference/smask-text.pdf.ref.png and b/test/reference/smask-text.pdf.ref.png differ
diff --git a/test/reference/smask-text.ps.ref.png b/test/reference/smask-text.ps.ref.png
new file mode 100644
index 0000000..4e00665
Binary files /dev/null and b/test/reference/smask-text.ps.ref.png differ
diff --git a/test/reference/smask-text.ps2.ref.png b/test/reference/smask-text.ps2.ref.png
deleted file mode 100644
index ae61325..0000000
Binary files a/test/reference/smask-text.ps2.ref.png and /dev/null differ
diff --git a/test/reference/smask-text.ps3.ref.png b/test/reference/smask-text.ps3.ref.png
deleted file mode 100644
index ae61325..0000000
Binary files a/test/reference/smask-text.ps3.ref.png and /dev/null differ
diff --git a/test/reference/smask.pdf.ref.png b/test/reference/smask.pdf.ref.png
new file mode 100644
index 0000000..2bc721c
Binary files /dev/null and b/test/reference/smask.pdf.ref.png differ
diff --git a/test/reference/smask.ps3.ref.png b/test/reference/smask.ps3.ref.png
new file mode 100644
index 0000000..fb1d74e
Binary files /dev/null and b/test/reference/smask.ps3.ref.png differ
diff --git a/test/reference/spline-decomposition.pdf.ref.png b/test/reference/spline-decomposition.pdf.ref.png
index 5afa094..99fd1d6 100644
Binary files a/test/reference/spline-decomposition.pdf.ref.png and b/test/reference/spline-decomposition.pdf.ref.png differ
diff --git a/test/reference/spline-decomposition.ps.ref.png b/test/reference/spline-decomposition.ps.ref.png
index 51e2938..7f3a8e6 100644
Binary files a/test/reference/spline-decomposition.ps.ref.png and b/test/reference/spline-decomposition.ps.ref.png differ
diff --git a/test/reference/stroke-clipped.ps.ref.png b/test/reference/stroke-clipped.ps.ref.png
new file mode 100644
index 0000000..a4b2aa6
Binary files /dev/null and b/test/reference/stroke-clipped.ps.ref.png differ
diff --git a/test/reference/stroke-ctm-caps.pdf.ref.png b/test/reference/stroke-ctm-caps.pdf.ref.png
new file mode 100644
index 0000000..dbc6415
Binary files /dev/null and b/test/reference/stroke-ctm-caps.pdf.ref.png differ
diff --git a/test/reference/stroke-image.pdf.ref.png b/test/reference/stroke-image.pdf.ref.png
index 790369c..e0babce 100644
Binary files a/test/reference/stroke-image.pdf.ref.png and b/test/reference/stroke-image.pdf.ref.png differ
diff --git a/test/reference/stroke-image.ps.ref.png b/test/reference/stroke-image.ps.ref.png
index 71889ac..8f0a522 100644
Binary files a/test/reference/stroke-image.ps.ref.png and b/test/reference/stroke-image.ps.ref.png differ
diff --git a/test/reference/stroke-pattern.pdf.argb32.ref.png b/test/reference/stroke-pattern.pdf.argb32.ref.png
new file mode 100644
index 0000000..788e1fc
Binary files /dev/null and b/test/reference/stroke-pattern.pdf.argb32.ref.png differ
diff --git a/test/reference/stroke-pattern.pdf.rgb24.ref.png b/test/reference/stroke-pattern.pdf.rgb24.ref.png
new file mode 100644
index 0000000..788e1fc
Binary files /dev/null and b/test/reference/stroke-pattern.pdf.rgb24.ref.png differ
diff --git a/test/reference/surface-pattern-big-scale-down.ps.ref.png b/test/reference/surface-pattern-big-scale-down.ps.ref.png
index 13fb093..b9a5463 100644
Binary files a/test/reference/surface-pattern-big-scale-down.ps.ref.png and b/test/reference/surface-pattern-big-scale-down.ps.ref.png differ
diff --git a/test/reference/surface-pattern-scale-down-extend-none.ps.ref.png b/test/reference/surface-pattern-scale-down-extend-none.ps.ref.png
new file mode 100644
index 0000000..d3f90ab
Binary files /dev/null and b/test/reference/surface-pattern-scale-down-extend-none.ps.ref.png differ
diff --git a/test/reference/surface-pattern-scale-down.pdf.ref.png b/test/reference/surface-pattern-scale-down.pdf.ref.png
index 1e32a44..c574f30 100644
Binary files a/test/reference/surface-pattern-scale-down.pdf.ref.png and b/test/reference/surface-pattern-scale-down.pdf.ref.png differ
diff --git a/test/reference/surface-pattern-scale-down.ps.ref.png b/test/reference/surface-pattern-scale-down.ps.ref.png
new file mode 100644
index 0000000..419f5f8
Binary files /dev/null and b/test/reference/surface-pattern-scale-down.ps.ref.png differ
diff --git a/test/reference/surface-pattern-scale-down.ps2.ref.png b/test/reference/surface-pattern-scale-down.ps2.ref.png
deleted file mode 100644
index 5fb6395..0000000
Binary files a/test/reference/surface-pattern-scale-down.ps2.ref.png and /dev/null differ
diff --git a/test/reference/surface-pattern-scale-down.ps3.ref.png b/test/reference/surface-pattern-scale-down.ps3.ref.png
deleted file mode 100644
index 5fb6395..0000000
Binary files a/test/reference/surface-pattern-scale-down.ps3.ref.png and /dev/null differ
diff --git a/test/reference/surface-pattern-scale-down.ref.png b/test/reference/surface-pattern-scale-down.ref.png
index 8bb58a2..239a6fd 100644
Binary files a/test/reference/surface-pattern-scale-down.ref.png and b/test/reference/surface-pattern-scale-down.ref.png differ
diff --git a/test/reference/surface-pattern-scale-up.pdf.ref.png b/test/reference/surface-pattern-scale-up.pdf.ref.png
index 593d058..fa04bcf 100644
Binary files a/test/reference/surface-pattern-scale-up.pdf.ref.png and b/test/reference/surface-pattern-scale-up.pdf.ref.png differ
diff --git a/test/reference/surface-pattern-scale-up.ps.ref.png b/test/reference/surface-pattern-scale-up.ps.ref.png
new file mode 100644
index 0000000..b70ecb1
Binary files /dev/null and b/test/reference/surface-pattern-scale-up.ps.ref.png differ
diff --git a/test/reference/surface-pattern-scale-up.ps2.ref.png b/test/reference/surface-pattern-scale-up.ps2.ref.png
deleted file mode 100644
index f2eac7a..0000000
Binary files a/test/reference/surface-pattern-scale-up.ps2.ref.png and /dev/null differ
diff --git a/test/reference/surface-pattern-scale-up.ps3.ref.png b/test/reference/surface-pattern-scale-up.ps3.ref.png
deleted file mode 100644
index f2eac7a..0000000
Binary files a/test/reference/surface-pattern-scale-up.ps3.ref.png and /dev/null differ
diff --git a/test/reference/surface-pattern.pdf.ref.png b/test/reference/surface-pattern.pdf.ref.png
new file mode 100644
index 0000000..42c42df
Binary files /dev/null and b/test/reference/surface-pattern.pdf.ref.png differ
diff --git a/test/reference/surface-pattern.pdf.xfail.png b/test/reference/surface-pattern.pdf.xfail.png
deleted file mode 100644
index fadc2c2..0000000
Binary files a/test/reference/surface-pattern.pdf.xfail.png and /dev/null differ
diff --git a/test/reference/surface-pattern.ps.ref.png b/test/reference/surface-pattern.ps.ref.png
new file mode 100644
index 0000000..02fbde8
Binary files /dev/null and b/test/reference/surface-pattern.ps.ref.png differ
diff --git a/test/reference/surface-pattern.ps.xfail.png b/test/reference/surface-pattern.ps.xfail.png
deleted file mode 100644
index 02fbde8..0000000
Binary files a/test/reference/surface-pattern.ps.xfail.png and /dev/null differ
diff --git a/test/reference/svg-surface-source.ps.rgb24.ref.png b/test/reference/svg-surface-source.ps.rgb24.ref.png
new file mode 100644
index 0000000..26cbb57
Binary files /dev/null and b/test/reference/svg-surface-source.ps.rgb24.ref.png differ
diff --git a/test/reference/text-glyph-range.pdf.ref.png b/test/reference/text-glyph-range.pdf.ref.png
new file mode 100644
index 0000000..06588e9
Binary files /dev/null and b/test/reference/text-glyph-range.pdf.ref.png differ
diff --git a/test/reference/text-glyph-range.ps.ref.png b/test/reference/text-glyph-range.ps.ref.png
index 96bc85a..6054722 100644
Binary files a/test/reference/text-glyph-range.ps.ref.png and b/test/reference/text-glyph-range.ps.ref.png differ
diff --git a/test/reference/text-pattern.pdf.argb32.ref.png b/test/reference/text-pattern.pdf.argb32.ref.png
index 5eef739..f8abd9e 100644
Binary files a/test/reference/text-pattern.pdf.argb32.ref.png and b/test/reference/text-pattern.pdf.argb32.ref.png differ
diff --git a/test/reference/text-pattern.pdf.rgb24.ref.png b/test/reference/text-pattern.pdf.rgb24.ref.png
index 27a1195..679fbd0 100644
Binary files a/test/reference/text-pattern.pdf.rgb24.ref.png and b/test/reference/text-pattern.pdf.rgb24.ref.png differ
diff --git a/test/reference/text-pattern.ps3.argb32.ref.png b/test/reference/text-pattern.ps3.argb32.ref.png
index 411a531..98021a5 100644
Binary files a/test/reference/text-pattern.ps3.argb32.ref.png and b/test/reference/text-pattern.ps3.argb32.ref.png differ
diff --git a/test/reference/text-pattern.ps3.rgb24.ref.png b/test/reference/text-pattern.ps3.rgb24.ref.png
index f696a99..afcaba8 100644
Binary files a/test/reference/text-pattern.ps3.rgb24.ref.png and b/test/reference/text-pattern.ps3.rgb24.ref.png differ
diff --git a/test/reference/text-rotate.pdf.ref.png b/test/reference/text-rotate.pdf.ref.png
index b533075..c097386 100644
Binary files a/test/reference/text-rotate.pdf.ref.png and b/test/reference/text-rotate.pdf.ref.png differ
diff --git a/test/reference/text-rotate.ps.ref.png b/test/reference/text-rotate.ps.ref.png
index c68d02d..cc57d73 100644
Binary files a/test/reference/text-rotate.ps.ref.png and b/test/reference/text-rotate.ps.ref.png differ
diff --git a/test/reference/text-rotate.ref.png b/test/reference/text-rotate.ref.png
index 432de31..a3e3c41 100644
Binary files a/test/reference/text-rotate.ref.png and b/test/reference/text-rotate.ref.png differ
diff --git a/test/reference/text-transform.pdf.argb32.ref.png b/test/reference/text-transform.pdf.argb32.ref.png
index 7a2f3a7..441c1cd 100644
Binary files a/test/reference/text-transform.pdf.argb32.ref.png and b/test/reference/text-transform.pdf.argb32.ref.png differ
diff --git a/test/reference/text-transform.pdf.rgb24.ref.png b/test/reference/text-transform.pdf.rgb24.ref.png
index 7a2f3a7..441c1cd 100644
Binary files a/test/reference/text-transform.pdf.rgb24.ref.png and b/test/reference/text-transform.pdf.rgb24.ref.png differ
diff --git a/test/reference/text-transform.ps.ref.png b/test/reference/text-transform.ps.ref.png
new file mode 100644
index 0000000..c5fdb30
Binary files /dev/null and b/test/reference/text-transform.ps.ref.png differ
diff --git a/test/reference/text-transform.ps2.ref.png b/test/reference/text-transform.ps2.ref.png
deleted file mode 100644
index 07896b3..0000000
Binary files a/test/reference/text-transform.ps2.ref.png and /dev/null differ
diff --git a/test/reference/text-transform.ps3.ref.png b/test/reference/text-transform.ps3.ref.png
deleted file mode 100644
index 07896b3..0000000
Binary files a/test/reference/text-transform.ps3.ref.png and /dev/null differ
diff --git a/test/reference/tiger.pdf.ref.png b/test/reference/tiger.pdf.ref.png
new file mode 100644
index 0000000..cc641e2
Binary files /dev/null and b/test/reference/tiger.pdf.ref.png differ
diff --git a/test/reference/tiger.ps.ref.png b/test/reference/tiger.ps.ref.png
new file mode 100644
index 0000000..09729b2
Binary files /dev/null and b/test/reference/tiger.ps.ref.png differ
diff --git a/test/reference/tiger.ref.png b/test/reference/tiger.ref.png
index b8b2175..58e0471 100644
Binary files a/test/reference/tiger.ref.png and b/test/reference/tiger.ref.png differ
diff --git a/test/reference/tighten-bounds.pdf.ref.png b/test/reference/tighten-bounds.pdf.ref.png
new file mode 100644
index 0000000..8511cae
Binary files /dev/null and b/test/reference/tighten-bounds.pdf.ref.png differ
diff --git a/test/reference/tighten-bounds.ps.ref.png b/test/reference/tighten-bounds.ps.ref.png
new file mode 100644
index 0000000..8511cae
Binary files /dev/null and b/test/reference/tighten-bounds.ps.ref.png differ
diff --git a/test/reference/transforms.pdf.ref.png b/test/reference/transforms.pdf.ref.png
new file mode 100644
index 0000000..d6bff0a
Binary files /dev/null and b/test/reference/transforms.pdf.ref.png differ
diff --git a/test/reference/trap-clip.argb32.ref.png b/test/reference/trap-clip.argb32.ref.png
index 08e6c68..b929d94 100644
Binary files a/test/reference/trap-clip.argb32.ref.png and b/test/reference/trap-clip.argb32.ref.png differ
diff --git a/test/reference/trap-clip.pdf.argb32.ref.png b/test/reference/trap-clip.pdf.argb32.ref.png
new file mode 100644
index 0000000..fca20c4
Binary files /dev/null and b/test/reference/trap-clip.pdf.argb32.ref.png differ
diff --git a/test/reference/trap-clip.pdf.rgb24.ref.png b/test/reference/trap-clip.pdf.rgb24.ref.png
new file mode 100644
index 0000000..fca20c4
Binary files /dev/null and b/test/reference/trap-clip.pdf.rgb24.ref.png differ
diff --git a/test/reference/trap-clip.rgb24.ref.png b/test/reference/trap-clip.rgb24.ref.png
index 9c51d62..2c06d01 100644
Binary files a/test/reference/trap-clip.rgb24.ref.png and b/test/reference/trap-clip.rgb24.ref.png differ
diff --git a/test/reference/twin.pdf.argb32.ref.png b/test/reference/twin.pdf.argb32.ref.png
new file mode 100644
index 0000000..f10ad5c
Binary files /dev/null and b/test/reference/twin.pdf.argb32.ref.png differ
diff --git a/test/reference/twin.pdf.rgb24.ref.png b/test/reference/twin.pdf.rgb24.ref.png
new file mode 100644
index 0000000..0964f5c
Binary files /dev/null and b/test/reference/twin.pdf.rgb24.ref.png differ
diff --git a/test/reference/twin.ps.ref.png b/test/reference/twin.ps.ref.png
index 25c71b4..a92e4fb 100644
Binary files a/test/reference/twin.ps.ref.png and b/test/reference/twin.ps.ref.png differ
diff --git a/test/reference/unbounded-operator.pdf.argb32.ref.png b/test/reference/unbounded-operator.pdf.argb32.ref.png
index 4aa476d..6e53024 100644
Binary files a/test/reference/unbounded-operator.pdf.argb32.ref.png and b/test/reference/unbounded-operator.pdf.argb32.ref.png differ
diff --git a/test/reference/unbounded-operator.pdf.rgb24.ref.png b/test/reference/unbounded-operator.pdf.rgb24.ref.png
new file mode 100644
index 0000000..1a1f9d1
Binary files /dev/null and b/test/reference/unbounded-operator.pdf.rgb24.ref.png differ
diff --git a/test/reference/unbounded-operator.rgb24.ref.png b/test/reference/unbounded-operator.rgb24.ref.png
index c9b5b34..1a1f9d1 100644
Binary files a/test/reference/unbounded-operator.rgb24.ref.png and b/test/reference/unbounded-operator.rgb24.ref.png differ
diff --git a/test/reference/unclosed-strokes.pdf.ref.png b/test/reference/unclosed-strokes.pdf.ref.png
new file mode 100644
index 0000000..17b161f
Binary files /dev/null and b/test/reference/unclosed-strokes.pdf.ref.png differ
diff --git a/test/reference/unclosed-strokes.ps.ref.png b/test/reference/unclosed-strokes.ps.ref.png
new file mode 100644
index 0000000..ee9324b
Binary files /dev/null and b/test/reference/unclosed-strokes.ps.ref.png differ
diff --git a/test/reference/user-font-proxy.pdf.argb32.ref.png b/test/reference/user-font-proxy.pdf.argb32.ref.png
index cffa9ed..9d61720 100644
Binary files a/test/reference/user-font-proxy.pdf.argb32.ref.png and b/test/reference/user-font-proxy.pdf.argb32.ref.png differ
diff --git a/test/reference/user-font-proxy.pdf.ref.png b/test/reference/user-font-proxy.pdf.ref.png
deleted file mode 100644
index afe7cb0..0000000
Binary files a/test/reference/user-font-proxy.pdf.ref.png and /dev/null differ
diff --git a/test/reference/user-font-proxy.ps.ref.png b/test/reference/user-font-proxy.ps.ref.png
index a7b348b..76ba45b 100644
Binary files a/test/reference/user-font-proxy.ps.ref.png and b/test/reference/user-font-proxy.ps.ref.png differ
diff --git a/test/reference/user-font-rescale.pdf.rgb24.ref.png b/test/reference/user-font-rescale.pdf.rgb24.ref.png
new file mode 100644
index 0000000..542e337
Binary files /dev/null and b/test/reference/user-font-rescale.pdf.rgb24.ref.png differ
diff --git a/test/reference/user-font-rescale.ps.ref.png b/test/reference/user-font-rescale.ps.ref.png
index 1ee4b13..42e816e 100644
Binary files a/test/reference/user-font-rescale.ps.ref.png and b/test/reference/user-font-rescale.ps.ref.png differ
diff --git a/test/reference/user-font.pdf.ref.png b/test/reference/user-font.pdf.ref.png
index de86407..5dc028e 100644
Binary files a/test/reference/user-font.pdf.ref.png and b/test/reference/user-font.pdf.ref.png differ
diff --git a/test/reference/user-font.ps.ref.png b/test/reference/user-font.ps.ref.png
index 63f2896..3a674c3 100644
Binary files a/test/reference/user-font.ps.ref.png and b/test/reference/user-font.ps.ref.png differ
diff --git a/test/reference/world-map-fill.pdf.argb32.ref.png b/test/reference/world-map-fill.pdf.argb32.ref.png
new file mode 100644
index 0000000..cd828fd
Binary files /dev/null and b/test/reference/world-map-fill.pdf.argb32.ref.png differ
diff --git a/test/reference/world-map-fill.pdf.rgb24.ref.png b/test/reference/world-map-fill.pdf.rgb24.ref.png
new file mode 100644
index 0000000..cd828fd
Binary files /dev/null and b/test/reference/world-map-fill.pdf.rgb24.ref.png differ
diff --git a/test/reference/world-map-fill.ps.argb32.ref.png b/test/reference/world-map-fill.ps.argb32.ref.png
new file mode 100644
index 0000000..86f323a
Binary files /dev/null and b/test/reference/world-map-fill.ps.argb32.ref.png differ
diff --git a/test/reference/world-map-fill.ps.rgb24.ref.png b/test/reference/world-map-fill.ps.rgb24.ref.png
new file mode 100644
index 0000000..86f323a
Binary files /dev/null and b/test/reference/world-map-fill.ps.rgb24.ref.png differ
diff --git a/test/reference/world-map-stroke.pdf.argb32.ref.png b/test/reference/world-map-stroke.pdf.argb32.ref.png
new file mode 100644
index 0000000..05ac7e3
Binary files /dev/null and b/test/reference/world-map-stroke.pdf.argb32.ref.png differ
diff --git a/test/reference/world-map-stroke.pdf.rgb24.ref.png b/test/reference/world-map-stroke.pdf.rgb24.ref.png
new file mode 100644
index 0000000..05ac7e3
Binary files /dev/null and b/test/reference/world-map-stroke.pdf.rgb24.ref.png differ
diff --git a/test/reference/world-map-stroke.ps.argb32.ref.png b/test/reference/world-map-stroke.ps.argb32.ref.png
new file mode 100644
index 0000000..f846294
Binary files /dev/null and b/test/reference/world-map-stroke.ps.argb32.ref.png differ
diff --git a/test/reference/world-map-stroke.ps.rgb24.ref.png b/test/reference/world-map-stroke.ps.rgb24.ref.png
new file mode 100644
index 0000000..f846294
Binary files /dev/null and b/test/reference/world-map-stroke.ps.rgb24.ref.png differ
diff --git a/test/reference/world-map.pdf.argb32.ref.png b/test/reference/world-map.pdf.argb32.ref.png
new file mode 100644
index 0000000..3f7df8a
Binary files /dev/null and b/test/reference/world-map.pdf.argb32.ref.png differ
diff --git a/test/reference/world-map.pdf.rgb24.ref.png b/test/reference/world-map.pdf.rgb24.ref.png
new file mode 100644
index 0000000..3f7df8a
Binary files /dev/null and b/test/reference/world-map.pdf.rgb24.ref.png differ
diff --git a/test/reference/world-map.ps.argb32.ref.png b/test/reference/world-map.ps.argb32.ref.png
new file mode 100644
index 0000000..c12220d
Binary files /dev/null and b/test/reference/world-map.ps.argb32.ref.png differ
diff --git a/test/reference/world-map.ps.rgb24.ref.png b/test/reference/world-map.ps.rgb24.ref.png
new file mode 100644
index 0000000..c12220d
Binary files /dev/null and b/test/reference/world-map.ps.rgb24.ref.png differ
diff --git a/test/reference/zero-mask.ref.png b/test/reference/zero-mask.ref.png
deleted file mode 100644
index ffae8d9..0000000
Binary files a/test/reference/zero-mask.ref.png and /dev/null differ
commit 1c5ec6e3806587eff1fbb640c63838ef2768c2cb
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    Fix PS record-neg-extents test failure

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 9a922ec..80f92d7 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -139,12 +139,13 @@ detach_proxy (cairo_surface_t *proxy)
 
 static cairo_int_status_t
 _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
-				    const cairo_pattern_t    *pattern)
+				    const cairo_pattern_t    *pattern,
+				    cairo_rectangle_int_t    *extents)
 {
     const cairo_surface_pattern_t *surface_pattern;
     cairo_analysis_surface_t *tmp;
     cairo_surface_t *source, *proxy;
-    cairo_matrix_t p2d, surface_transform;
+    cairo_matrix_t p2d;
     cairo_status_t status, analysis_status;
     cairo_bool_t surface_is_unbounded;
     cairo_bool_t unused;
@@ -169,23 +170,15 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
     p2d = pattern->matrix;
     status = cairo_matrix_invert (&p2d);
     assert (status == CAIRO_STATUS_SUCCESS);
+    _cairo_analysis_surface_set_ctm (&tmp->base, &p2d);
 
-    cairo_matrix_multiply (&tmp->ctm, &p2d, &surface->ctm);
-    tmp->has_ctm = ! _cairo_matrix_is_identity (&tmp->ctm);
-
-    surface_transform = tmp->ctm;
-    status = cairo_matrix_invert (&surface_transform);
     source = _cairo_surface_get_source (source, NULL);
     surface_is_unbounded = (pattern->extend == CAIRO_EXTEND_REPEAT
 				     || pattern->extend == CAIRO_EXTEND_REFLECT);
     status = _cairo_recording_surface_replay_and_create_regions (source,
-								 &surface_transform,
+								 &pattern->matrix,
 								 &tmp->base,
 								 surface_is_unbounded);
-
-    if (!tmp->first_op)
-	_cairo_box_add_box (&surface->page_bbox, &tmp->page_bbox);
-
     if (tmp->has_supported) {
 	surface->has_supported = TRUE;
 	unused = cairo_region_union (&surface->supported_region, &tmp->supported_region);
@@ -198,6 +191,18 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
 
     analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS;
 
+    if (pattern->extend != CAIRO_EXTEND_NONE) {
+	_cairo_unbounded_rectangle_init (extents);
+    } else if (source->content & CAIRO_CONTENT_ALPHA) {
+	status = cairo_matrix_invert (&tmp->ctm);
+	_cairo_matrix_transform_bounding_box_fixed (&tmp->ctm,
+						    &tmp->page_bbox, NULL);
+	_cairo_box_round_to_rectangle (&tmp->page_bbox, extents);
+    } else {
+	/* black background fills entire extents */
+	_cairo_surface_get_extents (source, extents);
+    }
+
     detach_proxy (proxy);
     cairo_surface_destroy (&tmp->base);
 
@@ -378,7 +383,7 @@ static cairo_int_status_t
 _cairo_analysis_surface_paint (void			*abstract_surface,
 			       cairo_operator_t		op,
 			       const cairo_pattern_t	*source,
-			       const cairo_clip_t		*clip)
+			       const cairo_clip_t	*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	     backend_status;
@@ -394,12 +399,14 @@ _cairo_analysis_surface_paint (void			*abstract_surface,
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     return _add_operation (surface, &extents, backend_status);
 }
@@ -409,7 +416,7 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 			      cairo_operator_t		 op,
 			      const cairo_pattern_t	*source,
 			      const cairo_pattern_t	*mask,
-			      const cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	      backend_status;
@@ -425,18 +432,24 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 	    return backend_status;
     }
 
+    _cairo_analysis_surface_operation_extents (surface,
+					       op, source, clip,
+					       &extents);
     if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
 	cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
 	cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
+	cairo_rectangle_int_t rec_extents;
 
 	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
 	    cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface;
 	    src_surface = _cairo_surface_get_source (src_surface, NULL);
 	    if (_cairo_surface_is_recording (src_surface)) {
 		backend_source_status =
-		    _analyze_recording_surface_pattern (surface, source);
+		    _analyze_recording_surface_pattern (surface, source, &rec_extents);
 		if (_cairo_int_status_is_error (backend_source_status))
 		    return backend_source_status;
+
+		_cairo_rectangle_intersect (&extents, &rec_extents);
 	    }
 	}
 
@@ -445,9 +458,11 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 	    mask_surface = _cairo_surface_get_source (mask_surface, NULL);
 	    if (_cairo_surface_is_recording (mask_surface)) {
 		backend_mask_status =
-		    _analyze_recording_surface_pattern (surface, mask);
+		    _analyze_recording_surface_pattern (surface, mask, &rec_extents);
 		if (_cairo_int_status_is_error (backend_mask_status))
 		    return backend_mask_status;
+
+		_cairo_rectangle_intersect (&extents, &rec_extents);
 	    }
 	}
 
@@ -456,10 +471,6 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 						  backend_mask_status);
     }
 
-    _cairo_analysis_surface_operation_extents (surface,
-					       op, source, clip,
-					       &extents);
-
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
 
@@ -471,16 +482,16 @@ _cairo_analysis_surface_mask (void			*abstract_surface,
 }
 
 static cairo_int_status_t
-_cairo_analysis_surface_stroke (void			*abstract_surface,
-				cairo_operator_t	 op,
-				const cairo_pattern_t	*source,
-				const cairo_path_fixed_t	*path,
-				const cairo_stroke_style_t	*style,
-				const cairo_matrix_t		*ctm,
-				const cairo_matrix_t		*ctm_inverse,
-				double			 tolerance,
-				cairo_antialias_t	 antialias,
-				const cairo_clip_t		*clip)
+_cairo_analysis_surface_stroke (void			   *abstract_surface,
+				cairo_operator_t	    op,
+				const cairo_pattern_t	   *source,
+				const cairo_path_fixed_t   *path,
+				const cairo_stroke_style_t *style,
+				const cairo_matrix_t	   *ctm,
+				const cairo_matrix_t	   *ctm_inverse,
+				double			    tolerance,
+				cairo_antialias_t	    antialias,
+				const cairo_clip_t	   *clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	     backend_status;
@@ -499,12 +510,14 @@ _cairo_analysis_surface_stroke (void			*abstract_surface,
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
@@ -531,7 +544,7 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
 			      cairo_fill_rule_t		 fill_rule,
 			      double			 tolerance,
 			      cairo_antialias_t		 antialias,
-			      const cairo_clip_t		*clip)
+			      const cairo_clip_t	*clip)
 {
     cairo_analysis_surface_t *surface = abstract_surface;
     cairo_int_status_t	     backend_status;
@@ -549,12 +562,14 @@ _cairo_analysis_surface_fill (void			*abstract_surface,
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	cairo_rectangle_int_t mask_extents;
@@ -611,12 +626,14 @@ _cairo_analysis_surface_show_glyphs (void		  *abstract_surface,
 	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
@@ -687,12 +704,14 @@ _cairo_analysis_surface_show_text_glyphs (void			    *abstract_surface,
 	    return backend_status;
     }
 
-    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
-	backend_status = _analyze_recording_surface_pattern (surface, source);
-
     _cairo_analysis_surface_operation_extents (surface,
 					       op, source, clip,
 					       &extents);
+    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
+	cairo_rectangle_int_t rec_extents;
+	backend_status = _analyze_recording_surface_pattern (surface, source, &rec_extents);
+	_cairo_rectangle_intersect (&extents, &rec_extents);
+    }
 
     if (_cairo_operator_bounded_by_mask (op)) {
 	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
diff --git a/src/cairo-debug.c b/src/cairo-debug.c
index dbc9e2f..1f32b19 100644
--- a/src/cairo-debug.c
+++ b/src/cairo-debug.c
@@ -311,3 +311,11 @@ _cairo_debug_print_matrix (FILE *file, const cairo_matrix_t *matrix)
 	     matrix->xy, matrix->yy,
 	     matrix->x0, matrix->y0);
 }
+
+void
+_cairo_debug_print_rect (FILE *file, const cairo_rectangle_int_t *rect)
+{
+    fprintf (file, "x: %d y: %d width: %d height: %d\n",
+	     rect->x, rect->y,
+	     rect->width, rect->height);
+}
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 1dd3c55..6ac4f87 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -417,7 +417,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t	*output,
     }
 
     surface->pdf_version = CAIRO_PDF_VERSION_1_5;
-    surface->compress_content = TRUE;
+    surface->compress_content = 0;
     surface->pdf_stream.active = FALSE;
     surface->pdf_stream.old_output = NULL;
     surface->group_stream.active = FALSE;
@@ -1320,20 +1320,20 @@ _get_source_surface_extents (cairo_surface_t         *source,
 
 /**
  * _cairo_pdf_surface_add_source_surface:
- * @surface: the pdf surface
- * @source_surface: A #cairo_surface_t to use as the source surface
- * @source_pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
- * @op: the operator used to composite this source
- * @filter: filter type of the source pattern
- * @stencil_mask: if true, the surface will be written to the PDF as an /ImageMask
- * @smask: if true, only the alpha channel will be written (images only)
- * @smask_res: if not NULL, the image written will specify this resource as the smask for
-   the image (images only)
- * @extents: extents of the operation that is using this source
- * @pdf_source: return pdf_source_surface entry in hash table
- * @x_offset: if not NULL return x offset of surface
- * @y_offset: if not NULL return y offset of surface
- * @source_extents: if not NULL return operation extents in source space
+ * @surface: [in] the pdf surface
+ * @source_surface: [in] A #cairo_surface_t to use as the source surface
+ * @source_pattern: [in] A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
+ * @op: [in] the operator used to composite this source
+ * @filter: [in] filter type of the source pattern
+ * @stencil_mask: [in] if true, the surface will be written to the PDF as an /ImageMask
+ * @smask: [in] if true, only the alpha channel will be written (images only)
+ * @extents: [in] extents of the operation that is using this source
+ * @smask_res: [out] if not NULL, the image written will specify this resource as the smask for
+ * the image (images only)
+ * @pdf_source: [out] return pdf_source_surface entry in hash table
+ * @x_offset: [out] if not NULL return x offset of surface
+ * @y_offset: [out] if not NULL return y offset of surface
+ * @source_extents: [out] if not NULL return operation extents in source space
  *
  * Add surface or raster_source pattern to list of surfaces to be
  * written to the PDF file when the current page is finished. Returns
@@ -1353,8 +1353,8 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	         *surface,
 				       cairo_filter_t		          filter,
 				       cairo_bool_t                       stencil_mask,
 				       cairo_bool_t                       smask,
-				       cairo_pdf_resource_t	         *smask_res,
 				       const cairo_rectangle_int_t       *extents,
+				       cairo_pdf_resource_t	         *smask_res,
 				       cairo_pdf_source_surface_entry_t **pdf_source,
 				       double                            *x_offset,
 				       double                            *y_offset,
@@ -2291,8 +2291,8 @@ _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t          *surfa
 						    source->filter,
 						    FALSE, /* stencil mask */
 						    FALSE, /* smask */
-						    NULL, /* smask_res */
 						    extents,
+						    NULL, /* smask_res */
 						    pdf_source,
 						    x_offset,
 						    y_offset,
@@ -3192,8 +3192,8 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 							pattern->filter,
 							FALSE, /* stencil mask */
 							FALSE, /* smask */
-							NULL, /* smask_res */
 							&pdf_pattern->extents,
+							NULL, /* smask_res */
 							&pdf_source,
 							&x_offset,
 							&y_offset,
@@ -4362,8 +4362,8 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
 							source->filter,
 							stencil_mask,
 							FALSE, /* smask */
-							smask_res,
 							extents,
+							smask_res,
 							&pdf_source,
 							&x_offset,
 							&y_offset,
@@ -6904,8 +6904,8 @@ _cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t         *surface,
 							source->filter,
 							FALSE, /* stencil mask */
 							TRUE, /* smask */
-							NULL, /* smask_res */
 							extents,
+							NULL, /* smask_res */
 							&pdf_source,
 							NULL,
 							NULL,
diff --git a/src/cairo-ps-surface-private.h b/src/cairo-ps-surface-private.h
index 1d5d27d..7cd275d 100644
--- a/src/cairo-ps-surface-private.h
+++ b/src/cairo-ps-surface-private.h
@@ -66,8 +66,9 @@ typedef struct cairo_ps_surface {
     cairo_content_t content;
     double width;
     double height;
-    cairo_rectangle_int_t page_bbox;
-    int bbox_x1, bbox_y1, bbox_x2, bbox_y2;
+    cairo_point_int_t document_bbox_p1, document_bbox_p2; /* in PS coordinates */
+    cairo_rectangle_int_t surface_extents;
+    cairo_bool_t surface_bounded;
     cairo_matrix_t cairo_to_ps;
 
     cairo_bool_t use_string_datasource;
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index df5f355..7a098f6 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -84,7 +84,7 @@
 #include <zlib.h>
 #include <errno.h>
 
-#define DEBUG_PS 0
+/* #define DEBUG_PS 1 */
 
 #if DEBUG_PS
 #define DEBUG_FALLBACK(s) \
@@ -259,10 +259,10 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
     if (!has_bbox) {
 	_cairo_output_stream_printf (surface->final_stream,
 				     "%%%%BoundingBox: %d %d %d %d\n",
-				     surface->bbox_x1,
-				     surface->bbox_y1,
-				     surface->bbox_x2,
-				     surface->bbox_y2);
+				     surface->document_bbox_p1.x,
+				     surface->document_bbox_p1.y,
+				     surface->document_bbox_p2.x,
+				     surface->document_bbox_p2.y);
     }
 
     _cairo_output_stream_printf (surface->final_stream,
@@ -879,11 +879,11 @@ _path_covers_bbox (cairo_ps_surface_t *surface,
 	_cairo_box_round_to_rectangle (&box, &rect);
 
 	/* skip trivial whole-page clips */
-	if (_cairo_rectangle_intersect (&rect, &surface->page_bbox)) {
-	    if (rect.x == surface->page_bbox.x &&
-		rect.width == surface->page_bbox.width &&
-		rect.y == surface->page_bbox.y &&
-		rect.height == surface->page_bbox.height)
+	if (_cairo_rectangle_intersect (&rect, &surface->surface_extents)) {
+	    if (rect.x == surface->surface_extents.x &&
+		rect.width == surface->surface_extents.width &&
+		rect.y == surface->surface_extents.y &&
+		rect.height == surface->surface_extents.height)
 	    {
 		return TRUE;
 	    }
@@ -1054,16 +1054,20 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
     surface->width  = width;
     surface->height = height;
     cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
+    surface->surface_extents.x = 0;
+    surface->surface_extents.y = 0;
+    surface->surface_extents.width  = ceil (surface->width);
+    surface->surface_extents.height = ceil (surface->height);
+    surface->surface_bounded = TRUE;
     surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
     surface->force_fallbacks = FALSE;
     surface->content = CAIRO_CONTENT_COLOR_ALPHA;
     surface->use_string_datasource = FALSE;
     surface->current_pattern_is_solid_color = FALSE;
-
-    surface->page_bbox.x = 0;
-    surface->page_bbox.y = 0;
-    surface->page_bbox.width  = width;
-    surface->page_bbox.height = height;
+    surface->document_bbox_p1.x = 0;
+    surface->document_bbox_p1.y = 0;
+    surface->document_bbox_p2.x = 0;
+    surface->document_bbox_p2.y = 0;
 
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_ps_surface_clipper_intersect_clip_path);
@@ -1402,6 +1406,10 @@ cairo_ps_surface_set_size (cairo_surface_t	*surface,
     ps_surface->width = width_in_points;
     ps_surface->height = height_in_points;
     cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
+    ps_surface->surface_extents.x = 0;
+    ps_surface->surface_extents.y = 0;
+    ps_surface->surface_extents.width  = ceil (ps_surface->width);
+    ps_surface->surface_extents.height = ceil (ps_surface->height);
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&ps_surface->pdf_operators,
 						  &ps_surface->cairo_to_ps);
     status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface,
@@ -1713,15 +1721,16 @@ color_is_gray (double red, double green, double blue)
 
 /**
  * _cairo_ps_surface_acquire_source_surface_from_pattern:
- * @surface: the ps surface
- * @pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
- * @extents: extents of the operation that is using this source
- * @width: returns width of surface
- * @height: returns height of surface
- * @x_offset: returns x offset of surface
- * @y_offset: returns y offset of surface
- * @surface: returns surface of type image surface or recording surface
- * @image_extra: returns image extra for image type surface
+ * @surface: [in] the ps surface
+ * @pattern: [in] A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
+ * @extents: [in] extents of the operation that is using this source
+ * @src_surface_extents: [out] return source surface extents
+ * @src_surface_bounded: [out] return TRUE if source surface is bounded
+ * @src_op_extents: [out] return operation extents in source space
+ * @source_surface: [out] returns surface of type image surface or recording surface
+ * @x_offset: [out] return x offset of surface
+ * @y_offset: [out] return y offset of surface
+ * @image_extra: [out] returns image extra for image type surface
  *
  * Acquire source surface or raster source pattern.
  **/
@@ -1729,20 +1738,24 @@ static cairo_status_t
 _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t           *surface,
 						       const cairo_pattern_t        *pattern,
 						       const cairo_rectangle_int_t  *extents,
-						       int                          *width,
-						       int                          *height,
+						       cairo_rectangle_int_t        *src_surface_extents,
+						       cairo_bool_t                 *src_surface_bounded,
+						       cairo_rectangle_int_t        *src_op_extents,
+						       cairo_surface_t             **source_surface,
 						       double                       *x_offset,
 						       double                       *y_offset,
-						       cairo_surface_t             **source_surface,
 						       void                        **image_extra)
 {
     cairo_status_t          status;
     cairo_image_surface_t  *image;
 
-    *x_offset = *y_offset = 0;
+    *x_offset = 0;
+    *y_offset = 0;
     *image_extra = NULL;
     switch (pattern->type) {
     case CAIRO_PATTERN_TYPE_SURFACE: {
+	cairo_box_t bbox;
+	//cairo_rectangle_int_t rect;
 	cairo_surface_t *surf = ((cairo_surface_pattern_t *) pattern)->surface;
 
 	if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) {
@@ -1753,27 +1766,48 @@ _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t
 	    if (surf->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
 		cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) surf;
 
-		*width  = sub->extents.width;
-		*height = sub->extents.height;
+		*src_surface_extents = sub->extents;
+		*src_surface_bounded = TRUE;
+		*x_offset = -sub->extents.x;
+		*y_offset = -sub->extents.y;
 	    } else {
-		cairo_recording_surface_t *recording_surface;
-		cairo_box_t bbox;
-		cairo_rectangle_int_t extents;
+		//cairo_recording_surface_t *recording_surface;
 
-		recording_surface = (cairo_recording_surface_t *) surf;
+		*src_surface_bounded = _cairo_surface_get_extents (surf, src_surface_extents);
 
+/*		recording_surface = (cairo_recording_surface_t *) surf;
 		status = _cairo_recording_surface_get_bbox (recording_surface, &bbox, NULL);
 		if (unlikely (status)) {
 		    cairo_surface_destroy (*image_extra);
 		    return status;
 		}
 
-		_cairo_box_round_to_rectangle (&bbox, &extents);
-		*width  = extents.width;
-		*height = extents.height;
+		_cairo_box_round_to_rectangle (&bbox, src_extents);
+		*x_offset = src_extents->x;
+		*y_offset = src_extents->y; */
 	    }
 	    *source_surface = surf;
 
+//*	    if (pattern->extend == CAIRO_EXTEND_NONE || pattern->extend == CAIRO_EXTEND_PAD) {
+		/* Clip the source extents to the operation extents (transformed to pattern space) */
+/*		cairo_rectangle_int_t old_src_extents = *src_extents;
+
+		_cairo_box_from_rectangle (&bbox, extents);
+		_cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &bbox, NULL);
+		_cairo_box_round_to_rectangle (&bbox, &rect);
+		if (surf->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
+		    rect.x += src_extents->x;
+		    rect.y += src_extents->y;
+		}
+		_cairo_rectangle_intersect (src_extents, &rect);
+		*x_offset += (src_extents->x - old_src_extents.x);
+		*y_offset += (src_extents->y - old_src_extents.y);
+	    }*/
+
+	    _cairo_box_from_rectangle (&bbox, extents);
+	    _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &bbox, NULL);
+	    _cairo_box_round_to_rectangle (&bbox, src_op_extents);
+
 	    return CAIRO_STATUS_SUCCESS;
 	} else {
 	    status =  _cairo_surface_acquire_source_image (surf, &image, image_extra);
@@ -1781,7 +1815,7 @@ _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t
 		cairo_surface_destroy (*image_extra);
 		return status;
 	    }
-	}
+    }
     } break;
 
     case CAIRO_PATTERN_TYPE_RASTER_SOURCE: {
@@ -1810,8 +1844,11 @@ _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t
 	break;
     }
 
-    *width = image->width;
-    *height = image->height;
+    src_surface_extents->x = 0;
+    src_surface_extents->y = 0;
+    src_surface_extents->width = image->width;
+    src_surface_extents->height = image->height;
+    *src_surface_bounded = TRUE;
     *source_surface = &image->base;
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1819,7 +1856,7 @@ _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t
 static void
 _cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t           *surface,
 						       const cairo_pattern_t        *pattern,
-						       cairo_surface_t              *source,
+						       cairo_surface_t              *source_surface,
 						       void                         *image_extra)
 {
     switch (pattern->type) {
@@ -1828,13 +1865,13 @@ _cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t
 	if (surf_pat->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
 	    cairo_surface_destroy (image_extra);
 	} else {
-	    cairo_image_surface_t *image  = (cairo_image_surface_t *) source;
+	    cairo_image_surface_t *image  = (cairo_image_surface_t *) source_surface;
 	    _cairo_surface_release_source_image (surf_pat->surface, image, image_extra);
 	}
     } break;
 
     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
-	_cairo_raster_source_pattern_release (pattern, source);
+	_cairo_raster_source_pattern_release (pattern, source_surface);
 	break;
 
     case CAIRO_PATTERN_TYPE_SOLID:
@@ -1853,11 +1890,8 @@ _cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t
  * @surface: the ps surface
  * @source: The source image
  * @extents: extents of the operation that is using this source
- * @width: returns width of padded image
- * @height: returns height of padded image
- * @x_offset: returns x offset of padded image
- * @y_offset: returns y offset of padded image
  * @image: returns the padded image or NULL if padding not required to fill @extents
+ * @image_extents: returns extents of padded image. These extents in are in source image space.
  *
  * Creates a padded image if the source image does not fill the extents.
  **/
@@ -1866,11 +1900,8 @@ _cairo_ps_surface_create_padded_image_from_image (cairo_ps_surface_t           *
 						  cairo_image_surface_t        *source,
 						  const cairo_matrix_t         *source_matrix,
 						  const cairo_rectangle_int_t  *extents,
-						  int                          *width,
-						  int                          *height,
-						  double                       *x_offset,
-						  double                       *y_offset,
-						  cairo_image_surface_t       **image)
+						  cairo_image_surface_t       **image,
+						  cairo_rectangle_int_t        *image_extents)
 {
     cairo_box_t box;
     cairo_rectangle_int_t rect;
@@ -1909,10 +1940,10 @@ _cairo_ps_surface_create_padded_image_from_image (cairo_ps_surface_t           *
 				       NULL);
 	_cairo_pattern_fini (&pad_pattern.base);
 	*image = (cairo_image_surface_t *) pad_image;
-	*width = rect.width;
-	*height = rect.height;
-	*x_offset = rect.x;
-	*y_offset = rect.y;
+	image_extents->x = rect.x;
+	image_extents->y = rect.y;
+	image_extents->width = rect.width;
+	image_extents->height = rect.height;
     } else {
 	*image = NULL;
 	status = CAIRO_STATUS_SUCCESS;
@@ -1926,27 +1957,31 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t
 							const cairo_pattern_t         *pattern,
 							const cairo_rectangle_int_t   *extents)
 {
-    int width, height;
+    cairo_rectangle_int_t src_surface_extents;
+    cairo_bool_t src_surface_bounded;
+    cairo_rectangle_int_t src_op_extents;
+    cairo_surface_t *source_surface;
     double x_offset, y_offset;
-    cairo_surface_t *source;
-    cairo_image_surface_t *image;
     void *image_extra;
-    cairo_int_status_t      status;
+    cairo_image_surface_t *image;
+    cairo_int_status_t status;
     cairo_image_transparency_t transparency;
 
     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
 								    pattern,
 								    extents,
-								    &width,
-								    &height,
+								    &src_surface_extents,
+								    &src_surface_bounded,
+								    &src_op_extents,
+								    &source_surface,
 								    &x_offset,
 								    &y_offset,
-								    &source,
 								    &image_extra);
     if (unlikely (status))
 	return status;
 
-    image = (cairo_image_surface_t *) source;
+    assert (_cairo_surface_is_image (source_surface));
+    image = (cairo_image_surface_t *) source_surface;
     if (image->base.status)
 	return image->base.status;
 
@@ -1973,7 +2008,7 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t
 	ASSERT_NOT_REACHED;
     }
 
-    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
+    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface, image_extra);
 
     return status;
 }
@@ -2923,61 +2958,39 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t    *surface,
 static cairo_status_t
 _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t          *surface,
 					  cairo_surface_t             *recording_surface,
-					  cairo_bool_t                 subsurface,
-					  const cairo_rectangle_int_t *extents)
+					  const cairo_rectangle_int_t *recording_extents,
+					  cairo_bool_t                 subsurface)
 {
     double old_width, old_height;
+    cairo_rectangle_int_t old_surface_extents;
+    cairo_bool_t old_surface_bounded;
     cairo_matrix_t old_cairo_to_ps;
     cairo_content_t old_content;
-    cairo_rectangle_int_t old_page_bbox;
     cairo_surface_clipper_t old_clipper;
-    cairo_box_t bbox;
     cairo_int_status_t status;
 
     old_content = surface->content;
     old_width = surface->width;
     old_height = surface->height;
-    old_page_bbox = surface->page_bbox;
+    old_surface_extents = surface->surface_extents;
+    old_surface_bounded = surface->surface_bounded;
     old_cairo_to_ps = surface->cairo_to_ps;
     old_clipper = surface->clipper;
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_ps_surface_clipper_intersect_clip_path);
 
-    if (subsurface) {
-	surface->page_bbox.x = surface->page_bbox.y = 0;
-	surface->page_bbox.width = surface->width  = extents->width;
-	surface->page_bbox.height = surface->height = extents->height;
-
-#if DEBUG_PS
-	_cairo_output_stream_printf (surface->stream,
-				     "%% _cairo_ps_surface_emit_recording_subsurface"
-				     " (%d, %d), (%d, %d)\n",
-				     extents->x, extents->y,
-				     extents->width, extents->height);
-#endif
-
-    } else {
-	status =
-	    _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface,
-					       &bbox,
-					       NULL);
-	if (unlikely (status))
-	    return status;
-
-	surface->width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x);
-	surface->height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
-	_cairo_box_round_to_rectangle (&bbox, &surface->page_bbox);
-
 #if DEBUG_PS
     _cairo_output_stream_printf (surface->stream,
-				 "%% _cairo_ps_surface_emit_recording_surface (%f, %f), (%f, %f)\n",
-				 _cairo_fixed_to_double (bbox.p1.x),
-				 _cairo_fixed_to_double (bbox.p1.y),
-				 _cairo_fixed_to_double (bbox.p2.x),
-				 _cairo_fixed_to_double (bbox.p2.y));
+				 "%% _cairo_ps_surface_emit_recording_surface"
+				 " x: %d, y: %d, w: %d, h: %d subsurface: %d\n",
+				 recording_extents->x, recording_extents->y,
+				 recording_extents->width, recording_extents->height,
+				 subsurface);
 #endif
-    }
 
+    surface->width = recording_extents->width;
+    surface->height = recording_extents->height;
+    surface->surface_extents = *recording_extents;
     surface->current_pattern_is_solid_color = FALSE;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
     cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
@@ -2989,14 +3002,14 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t          *surface,
 	surface->content = CAIRO_CONTENT_COLOR;
 	_cairo_output_stream_printf (surface->stream,
 				     "  0 g %d %d %d %d rectfill\n",
-				     surface->page_bbox.x,
-				     surface->page_bbox.y,
-				     surface->page_bbox.width,
-				     surface->page_bbox.height);
+				     recording_extents->x,
+				     recording_extents->y,
+				     recording_extents->width,
+				     recording_extents->height);
     }
 
     status = _cairo_recording_surface_replay_region (recording_surface,
-						     subsurface ? extents : NULL,
+						     subsurface ? recording_extents : NULL,
 						     &surface->base,
 						     CAIRO_RECORDING_REGION_NATIVE);
     assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
@@ -3014,7 +3027,8 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t          *surface,
     surface->content = old_content;
     surface->width = old_width;
     surface->height = old_height;
-    surface->page_bbox = old_page_bbox;
+    surface->surface_extents = old_surface_extents;
+    surface->surface_bounded = old_surface_bounded;
     surface->current_pattern_is_solid_color = FALSE;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
     surface->cairo_to_ps = old_cairo_to_ps;
@@ -3068,22 +3082,23 @@ _cairo_ps_surface_emit_solid_pattern (cairo_ps_surface_t    *surface,
 }
 
 static cairo_status_t
-_cairo_ps_surface_emit_surface (cairo_ps_surface_t      *surface,
-				cairo_pattern_t         *source_pattern,
-				cairo_surface_t         *source_surface,
-				cairo_operator_t	 op,
-				int                      width,
-				int                      height,
-				cairo_bool_t             stencil_mask)
+_cairo_ps_surface_emit_surface (cairo_ps_surface_t          *surface,
+				const cairo_pattern_t       *source_pattern,
+				cairo_surface_t             *source_surface,
+				cairo_operator_t	     op,
+				const cairo_rectangle_int_t *src_surface_extents,
+				cairo_bool_t                 src_surface_bounded,
+				const cairo_rectangle_int_t *src_op_extents,
+				cairo_bool_t                 stencil_mask)
 {
     cairo_int_status_t status;
 
     if (source_pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	source_pattern->extend != CAIRO_EXTEND_PAD)
+	source_pattern->extend != CAIRO_EXTEND_PAD && src_surface_bounded)
     {
 	cairo_surface_t *surf = ((cairo_surface_pattern_t *) source_pattern)->surface;
 
-	status = _cairo_ps_surface_emit_jpeg_image (surface, surf, width, height);
+	status = _cairo_ps_surface_emit_jpeg_image (surface, surf, src_surface_extents->width, src_surface_extents->height);
 	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	    return status;
     }
@@ -3091,9 +3106,9 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t      *surface,
     if (source_surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
 	if (source_surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
 	    cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source_surface;
-	    status = _cairo_ps_surface_emit_recording_surface (surface, sub->target, TRUE, &sub->extents);
+	    status = _cairo_ps_surface_emit_recording_surface (surface, sub->target, &sub->extents, TRUE);
 	} else {
-	    status = _cairo_ps_surface_emit_recording_surface (surface, source_surface, FALSE, NULL);
+	    status = _cairo_ps_surface_emit_recording_surface (surface, source_surface, src_op_extents, FALSE);
 	}
     } else {
 	cairo_image_surface_t *image = (cairo_image_surface_t *) source_surface;
@@ -3137,19 +3152,21 @@ _path_fixed_init_rectangle (cairo_path_fixed_t *path,
 
 static cairo_status_t
 _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
-				 cairo_pattern_t        *pattern,
+				 const cairo_pattern_t  *pattern,
 				 cairo_rectangle_int_t  *extents,
 				 cairo_operator_t	 op,
 				 cairo_bool_t            stencil_mask)
 {
+    cairo_rectangle_int_t src_surface_extents;
+    cairo_bool_t src_surface_bounded;
+    cairo_rectangle_int_t src_op_extents;
+    cairo_surface_t *source_surface;
+    double x_offset, y_offset;
+    void *image_extra;
     cairo_status_t status;
-    int width, height;
     cairo_matrix_t cairo_p2d, ps_p2d;
     cairo_path_fixed_t path;
-    double x_offset, y_offset;
-    cairo_surface_t *source;
     cairo_image_surface_t *image = NULL;
-    void *image_extra;
 
     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
     if (unlikely (status))
@@ -3158,9 +3175,12 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
 								    pattern,
 								    extents,
-								    &width, &height,
-								    &x_offset, &y_offset,
-								    &source,
+								    &src_surface_extents,
+								    &src_surface_bounded,
+								    &src_op_extents,
+								    &source_surface,
+								    &x_offset,
+								    &y_offset,
 								    &image_extra);
     if (unlikely (status))
 	return status;
@@ -3170,16 +3190,18 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
 	((cairo_surface_pattern_t *)pattern)->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
 	cairo_image_surface_t *img;
 
-	img = (cairo_image_surface_t *) source;
+	img = (cairo_image_surface_t *) source_surface;
 	status = _cairo_ps_surface_create_padded_image_from_image (surface,
 								   img,
 								   &pattern->matrix,
 								   extents,
-								   &width, &height,
-								   &x_offset, &y_offset,
-								   &image);
+								   &image,
+								   &src_surface_extents);
 	if (unlikely (status))
 	    goto release_source;
+
+	x_offset = src_surface_extents.x;
+	y_offset = src_surface_extents.y;
     }
 
     _path_fixed_init_rectangle (&path, extents);
@@ -3200,8 +3222,8 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
 				     "%% Fallback Image: x=%f y=%f w=%d h=%d ",
 				     -cairo_p2d.x0/x_scale,
 				     -cairo_p2d.y0/y_scale,
-				     (int)(width/x_scale),
-				     (int)(height/y_scale));
+				     (int)(src_surface_extents.width/x_scale),
+				     (int)(src_surface_extents.height/y_scale));
 	if (x_scale == y_scale) {
 	    _cairo_output_stream_printf (surface->stream,
 					 "res=%fppi ",
@@ -3214,14 +3236,16 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
 	}
 	_cairo_output_stream_printf (surface->stream,
 				     "size=%ld\n",
-				     (long)width*height*3);
+				     (long)src_surface_extents.width * src_surface_extents.height * 3);
     } else {
 	if (op == CAIRO_OPERATOR_SOURCE) {
 	    _cairo_output_stream_printf (surface->stream,
-					 "%d g 0 0 %f %f rectfill\n",
+					 "%d g %d %d %d %d rectfill\n",
 					 surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
-					 surface->width,
-					 surface->height);
+					 surface->surface_extents.x,
+					 surface->surface_extents.y,
+					 surface->surface_extents.width,
+					 surface->surface_extents.height);
 	}
     }
 
@@ -3235,7 +3259,7 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
     if (!(pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
           ((cairo_surface_pattern_t *)pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING))
     {
-	cairo_matrix_translate (&ps_p2d, 0.0, height);
+	cairo_matrix_translate (&ps_p2d, 0.0, src_surface_extents.height);
 	cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
     }
 
@@ -3247,16 +3271,18 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
 
     status = _cairo_ps_surface_emit_surface (surface,
 					     pattern,
-					     image ? &image->base : source,
+					     image ? &image->base : source_surface,
 					     op,
-					     width, height,
+					     &src_surface_extents,
+					     image ? TRUE : src_surface_bounded,
+					     &src_op_extents,
 					     stencil_mask);
 
   release_source:
     if (image)
 	cairo_surface_destroy (&image->base);
 
-    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
+    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface, image_extra);
 
     return status;
 }
@@ -3268,15 +3294,17 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
 					cairo_operator_t	 op)
 {
     cairo_status_t status;
-    int pattern_width = 0; /* squelch bogus compiler warning */
-    int pattern_height = 0; /* squelch bogus compiler warning */
     double xstep, ystep;
+    cairo_rectangle_int_t pattern_extents;
+    cairo_bool_t bounded;
     cairo_matrix_t cairo_p2d, ps_p2d;
     cairo_bool_t old_use_string_datasource;
     double x_offset, y_offset;
-    cairo_surface_t *source;
+    cairo_surface_t *source_surface;
     cairo_image_surface_t *image = NULL;
     void *image_extra;
+    cairo_rectangle_int_t src_op_extents;
+    cairo_extend_t extend = cairo_pattern_get_extend (pattern);
 
     cairo_p2d = pattern->matrix;
     status = cairo_matrix_invert (&cairo_p2d);
@@ -3286,32 +3314,39 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
 								    pattern,
 								    extents,
-								    &pattern_width, &pattern_height,
+								    &pattern_extents,
+								    &bounded,
+								    &src_op_extents,
+								    &source_surface,
 								    &x_offset, &y_offset,
-								    &source,
 								    &image_extra);
     if (unlikely (status))
 	return status;
 
-    if (pattern->extend == CAIRO_EXTEND_PAD) {
+    if (extend == CAIRO_EXTEND_PAD) {
 	cairo_image_surface_t *img;
 
-	assert (source->type == CAIRO_SURFACE_TYPE_IMAGE);
-	img = (cairo_image_surface_t *) source;
+	assert (source_surface->type == CAIRO_SURFACE_TYPE_IMAGE);
+	img = (cairo_image_surface_t *) source_surface;
 	status = _cairo_ps_surface_create_padded_image_from_image (surface,
 								   img,
 								   &pattern->matrix,
 								   extents,
-								   &pattern_width, &pattern_height,
-								   &x_offset, &y_offset,
-								   &image);
+								   &image,
+								   &pattern_extents);
 	if (unlikely (status))
 	    goto release_source;
     }
     if (unlikely (status))
 	goto release_source;
 
-    switch (pattern->extend) {
+    if (!bounded)
+    {
+	extend = CAIRO_EXTEND_NONE;
+	_cairo_rectangle_intersect (&pattern_extents, &src_op_extents);
+    }
+
+    switch (extend) {
     case CAIRO_EXTEND_PAD:
     case CAIRO_EXTEND_NONE:
     {
@@ -3328,7 +3363,8 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
 	 * repeat visibly.
 	 */
 	double x1 = 0.0, y1 = 0.0;
-	double x2 = surface->width, y2 = surface->height;
+	double x2 = surface->surface_extents.width;
+	double y2 = surface->surface_extents.height;
 	_cairo_matrix_transform_bounding_box (&pattern->matrix,
 					      &x1, &y1, &x2, &y2,
 					      NULL);
@@ -3338,16 +3374,16 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
 	 * required an answer that's large enough, we don't really
 	 * care if it's not as tight as possible.*/
 	xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
-			      pattern_width + pattern_height);
+			      pattern_extents.width + pattern_extents.height);
 	break;
     }
     case CAIRO_EXTEND_REPEAT:
-	xstep = pattern_width;
-	ystep = pattern_height;
+	xstep = pattern_extents.width;
+	ystep = pattern_extents.height;
 	break;
     case CAIRO_EXTEND_REFLECT:
-	xstep = pattern_width*2;
-	ystep = pattern_height*2;
+	xstep = pattern_extents.width*2;
+	ystep = pattern_extents.height*2;
 	break;
 	/* All the rest (if any) should have been analyzed away, so these
 	 * cases should be unreachable. */
@@ -3358,27 +3394,38 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
     }
 
     _cairo_output_stream_printf (surface->stream,
-				 "/CairoPattern {\n");
+				 "/CairoPattern {\n"
+				 "q %d %d %d %d rectclip\n",
+				 pattern_extents.x, pattern_extents.y,
+				 pattern_extents.width, pattern_extents.height);
 
     old_use_string_datasource = surface->use_string_datasource;
     surface->use_string_datasource = TRUE;
     if (op == CAIRO_OPERATOR_SOURCE) {
 	_cairo_output_stream_printf (surface->stream,
-				     "%d g 0 0 %f %f rectfill\n",
+				     "%d g %d %d %f %f rectfill\n",
 				     surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
+				     pattern_extents.x, pattern_extents.y,
 				     xstep, ystep);
     }
+
+    if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT)
+	src_op_extents = pattern_extents;
+
     status = _cairo_ps_surface_emit_surface (surface,
 					     pattern,
-					     image ? &image->base : source,
+					     image ? &image->base : source_surface,
 					     op,
-					     pattern_width, pattern_height, FALSE);
+					     &pattern_extents,
+					     bounded,
+					     &src_op_extents,
+					     FALSE);
     if (unlikely (status))
 	goto release_source;
 
     surface->use_string_datasource = old_use_string_datasource;
     _cairo_output_stream_printf (surface->stream,
-				 "} bind def\n");
+				 " Q } bind def\n");
 
     _cairo_output_stream_printf (surface->stream,
 				 "<< /PatternType 1\n"
@@ -3388,20 +3435,43 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
 				 "   /XStep %f /YStep %f\n",
 				 xstep, ystep);
 
-    if (pattern->extend == CAIRO_EXTEND_REFLECT) {
+    if (extend == CAIRO_EXTEND_REFLECT) {
+	cairo_matrix_t mat;
+
 	_cairo_output_stream_printf (surface->stream,
-				     "   /BBox [0 0 %d %d]\n"
+				     "   /BBox [%d %d %d %d]\n"
 				     "   /PaintProc {\n"
-				     "      pop CairoPattern\n"
-				     "      [-1 0 0  1 %d 0] concat CairoPattern\n"
-				     "      [ 1 0 0 -1 0 %d] concat CairoPattern\n"
-				     "      [-1 0 0  1 %d 0] concat CairoPattern\n"
-				     "      CairoPattern\n"
-				     "   } bind\n",
-				     pattern_width*2, pattern_height*2,
-				     pattern_width*2,
-				     pattern_height*2,
-				     pattern_width*2);
+				     "      pop CairoPattern\n",
+				     pattern_extents.x,
+				     pattern_extents.y,
+				     pattern_extents.x + pattern_extents.width*2,
+				     pattern_extents.y + pattern_extents.height*2);
+
+	cairo_matrix_init_translate (&mat, pattern_extents.x, pattern_extents.y);
+	cairo_matrix_scale (&mat, -1, 1);
+	cairo_matrix_translate (&mat, -2*pattern_extents.width, 0);
+	cairo_matrix_translate (&mat, -pattern_extents.x, -pattern_extents.y);
+	_cairo_output_stream_printf (surface->stream, "      q [");
+	_cairo_output_stream_print_matrix (surface->stream, &mat);
+	_cairo_output_stream_printf (surface->stream, "] concat CairoPattern Q\n");
+
+	cairo_matrix_init_translate (&mat, pattern_extents.x, pattern_extents.y);
+	cairo_matrix_scale (&mat, 1, -1);
+	cairo_matrix_translate (&mat, 0, -2*pattern_extents.height);
+	cairo_matrix_translate (&mat, -pattern_extents.x, -pattern_extents.y);
+	_cairo_output_stream_printf (surface->stream, "      q [");
+	_cairo_output_stream_print_matrix (surface->stream, &mat);
+	_cairo_output_stream_printf (surface->stream, "] concat CairoPattern Q\n");
+
+	cairo_matrix_init_translate (&mat, pattern_extents.x, pattern_extents.y);
+	cairo_matrix_scale (&mat, -1, -1);
+	cairo_matrix_translate (&mat, -2*pattern_extents.width, -2*pattern_extents.height);
+	cairo_matrix_translate (&mat, -pattern_extents.x, -pattern_extents.y);
+	_cairo_output_stream_printf (surface->stream, "      q [");
+	_cairo_output_stream_print_matrix (surface->stream, &mat);
+	_cairo_output_stream_printf (surface->stream, "] concat CairoPattern Q\n");
+
+	_cairo_output_stream_printf (surface->stream, "   } bind\n");
     } else {
 	if (op == CAIRO_OPERATOR_SOURCE) {
 	    _cairo_output_stream_printf (surface->stream,
@@ -3409,8 +3479,11 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
 					 xstep, ystep);
 	} else {
 	    _cairo_output_stream_printf (surface->stream,
-					 "   /BBox [0 0 %d %d]\n",
-					 pattern_width, pattern_height);
+					 "   /BBox [%d %d %d %d]\n",
+					 pattern_extents.x,
+					 pattern_extents.y,
+					 pattern_extents.x + pattern_extents.width,
+					 pattern_extents.y + pattern_extents.height);
 	}
 	_cairo_output_stream_printf (surface->stream,
 				     "   /PaintProc { pop CairoPattern }\n");
@@ -3426,10 +3499,10 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
 
     cairo_matrix_init_identity (&ps_p2d);
     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
-
+    cairo_matrix_translate (&ps_p2d, x_offset, y_offset);
     if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
     {
-	cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
+	cairo_matrix_translate (&ps_p2d, 0.0, pattern_extents.height);
 	cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
     }
 
@@ -3443,7 +3516,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
     if (image)
 	cairo_surface_destroy (&image->base);
 
-    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
+    _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source_surface, image_extra);
 
     return status;
 }
@@ -4026,7 +4099,7 @@ _cairo_ps_surface_paint_pattern (cairo_ps_surface_t           *surface,
     case CAIRO_PATTERN_TYPE_SURFACE:
     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
        return _cairo_ps_surface_paint_surface (surface,
-                                               (cairo_pattern_t *)source,
+                                               source,
                                                extents,
                                                op,
 					       stencil_mask);
@@ -4035,8 +4108,8 @@ _cairo_ps_surface_paint_pattern (cairo_ps_surface_t           *surface,
     case CAIRO_PATTERN_TYPE_RADIAL:
     case CAIRO_PATTERN_TYPE_MESH:
 	return _cairo_ps_surface_paint_gradient (surface,
-						  source,
-						  extents);
+						 source,
+						 extents);
 
     case CAIRO_PATTERN_TYPE_SOLID:
     default:
@@ -4074,17 +4147,10 @@ _cairo_ps_surface_get_extents (void		       *abstract_surface,
 {
     cairo_ps_surface_t *surface = abstract_surface;
 
-    rectangle->x = 0;
-    rectangle->y = 0;
-
-    /* XXX: The conversion to integers here is pretty bogus, (not to
-     * mention the aribitray limitation of width to a short(!). We
-     * may need to come up with a better interface for get_extents.
-     */
-    rectangle->width  = ceil (surface->width);
-    rectangle->height = ceil (surface->height);
+    if (surface->surface_bounded)
+	*rectangle = surface->surface_extents;
 
-    return TRUE;
+    return surface->surface_bounded;
 }
 
 static void
@@ -4168,8 +4234,11 @@ _cairo_ps_surface_paint (void			*abstract_surface,
 	if (unlikely (status))
 	    goto cleanup_composite;
 
-	_cairo_output_stream_printf (stream, "0 0 %f %f rectfill\n",
-				     surface->width, surface->height);
+	_cairo_output_stream_printf (stream, "%d %d %d %d rectfill\n",
+				     surface->surface_extents.x,
+				     surface->surface_extents.y,
+				     surface->surface_extents.width,
+				     surface->surface_extents.height);
     }
 
 cleanup_composite:
@@ -4473,34 +4542,55 @@ _cairo_ps_surface_set_paginated_mode (void			*abstract_surface,
 
     surface->paginated_mode = paginated_mode;
 
-    if (surface->clipper.clip != NULL) {
-	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+    if (paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	surface->surface_extents.x = 0;
+	surface->surface_extents.y = 0;
+	surface->surface_extents.width  = ceil (surface->width);
+	surface->surface_extents.height = ceil (surface->height);
 
-	_cairo_output_stream_printf (surface->stream, "Q q\n");
-	_cairo_surface_clipper_reset (&surface->clipper);
+	if (surface->clipper.clip != NULL)
+	{
+	    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
+
+	    _cairo_output_stream_printf (surface->stream, "Q q\n");
+	    _cairo_surface_clipper_reset (&surface->clipper);
+	}
     }
 }
 
 static cairo_int_status_t
 _cairo_ps_surface_set_bounding_box (void		*abstract_surface,
-				    cairo_box_t		*bbox)
+				    cairo_box_t		*analysis_bbox)
 {
     cairo_ps_surface_t *surface = abstract_surface;
     int i, num_comments;
     char **comments;
-    int x1, y1, x2, y2;
     cairo_bool_t has_page_media, has_page_bbox;
     const char *page_media;
+    cairo_rectangle_int_t page_bbox;
+    cairo_point_int_t bbox_p1, bbox_p2; /* in PS coordinates */
 
-    x1 = floor (_cairo_fixed_to_double (bbox->p1.x));
-    y1 = floor (surface->height - _cairo_fixed_to_double (bbox->p2.y));
-    x2 = ceil (_cairo_fixed_to_double (bbox->p2.x));
-    y2 = ceil (surface->height - _cairo_fixed_to_double (bbox->p1.y));
+    _cairo_box_round_to_rectangle (analysis_bbox, &page_bbox);
 
-    surface->page_bbox.x = x1;
-    surface->page_bbox.y = y1;
-    surface->page_bbox.width  = x2 - x1;
-    surface->page_bbox.height = y2 - y1;
+    /* convert to PS coordinates */
+    bbox_p1.x = page_bbox.x;
+    bbox_p1.y = ceil(surface->height) - (page_bbox.y + page_bbox.height);
+    bbox_p2.x = page_bbox.x + page_bbox.width;
+    bbox_p2.y = ceil(surface->height) - page_bbox.y;
+
+    if (surface->num_pages == 1) {
+	surface->document_bbox_p1 = bbox_p1;
+	surface->document_bbox_p2 = bbox_p2;
+    } else {
+	if (bbox_p1.x < surface->document_bbox_p1.x)
+	    surface->document_bbox_p1.x = bbox_p1.x;
+	if (bbox_p1.y < surface->document_bbox_p1.y)
+	    surface->document_bbox_p1.y = bbox_p1.y;
+	if (bbox_p2.x < surface->document_bbox_p2.x)
+	    surface->document_bbox_p2.x = bbox_p2.x;
+	if (bbox_p2.y < surface->document_bbox_p2.y)
+	    surface->document_bbox_p2.y = bbox_p2.y;
+    }
 
     _cairo_output_stream_printf (surface->stream,
 				 "%%%%Page: %d %d\n",
@@ -4541,7 +4631,10 @@ _cairo_ps_surface_set_bounding_box (void		*abstract_surface,
     if (!has_page_bbox) {
 	_cairo_output_stream_printf (surface->stream,
 				     "%%%%PageBoundingBox: %d %d %d %d\n",
-				     x1, y1, x2, y2);
+				     bbox_p1.x,
+				     bbox_p1.y,
+				     bbox_p2.x,
+				     bbox_p2.y);
     }
 
     if (!surface->eps) {
@@ -4555,27 +4648,12 @@ _cairo_ps_surface_set_bounding_box (void		*abstract_surface,
                                  "%%%%EndPageSetup\n"
 				 "q %d %d %d %d rectclip\n"
                                  "1 0 0 -1 0 %f cm q\n",
-				 surface->page_bbox.x,
-				 surface->page_bbox.y,
-				 surface->page_bbox.width,
-				 surface->page_bbox.height,
-				 surface->height);
+				 bbox_p1.x,
+				 bbox_p1.y,
+				 bbox_p2.x - bbox_p1.x,
+				 bbox_p2.y - bbox_p1.y,
+				 ceil(surface->height));
 
-    if (surface->num_pages == 1) {
-	surface->bbox_x1 = x1;
-	surface->bbox_y1 = y1;
-	surface->bbox_x2 = x2;
-	surface->bbox_y2 = y2;
-    } else {
-	if (x1 < surface->bbox_x1)
-	    surface->bbox_x1 = x1;
-	if (y1 < surface->bbox_y1)
-	    surface->bbox_y1 = y1;
-	if (x2 > surface->bbox_x2)
-	    surface->bbox_x2 = x2;
-	if (y2 > surface->bbox_y2)
-	    surface->bbox_y2 = y2;
-    }
     surface->current_pattern_is_solid_color = FALSE;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
 
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index d35512e..218a8e3 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -1679,8 +1679,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
     cairo_surface_wrapper_t wrapper;
     cairo_command_t **elements;
     cairo_bool_t replay_all =
-	type == CAIRO_RECORDING_REPLAY &&
-	region == CAIRO_RECORDING_REGION_ALL;
+	type == CAIRO_RECORDING_CREATE_REGIONS || region == CAIRO_RECORDING_REGION_ALL;
     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_rectangle_int_t extents;
     cairo_bool_t use_indices = FALSE;
@@ -1871,7 +1870,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
 	    ASSERT_NOT_REACHED;
 	}
 
-	if (type == CAIRO_RECORDING_CREATE_REGIONS) {
+	if (type == CAIRO_RECORDING_CREATE_REGIONS && command->header.region != CAIRO_RECORDING_REGION_NATIVE) {
 	    if (status == CAIRO_INT_STATUS_SUCCESS) {
 		command->header.region = CAIRO_RECORDING_REGION_NATIVE;
 	    } else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
diff --git a/src/cairoint.h b/src/cairoint.h
index 88b1bf7..efc9ad1 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1784,6 +1784,9 @@ _cairo_matrix_to_pixman_matrix_offset (const cairo_matrix_t	*matrix,
 cairo_private void
 _cairo_debug_print_matrix (FILE *file, const cairo_matrix_t *matrix);
 
+cairo_private void
+_cairo_debug_print_rect (FILE *file, const cairo_rectangle_int_t *rect);
+
 cairo_private cairo_status_t
 _cairo_bentley_ottmann_tessellate_rectilinear_polygon (cairo_traps_t	 *traps,
 						       const cairo_polygon_t *polygon,
commit a14d319e4385033d726861dcd448154d393ffc53
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    ps: change from ps coordinates to cairo coordinates

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index fd0d284..df5f355 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -109,7 +109,7 @@
 
 /**
  * CAIRO_HAS_PS_SURFACE:
- * 
+ *
  * Defined if the PostScript surface backend is available.
  * This macro can be used to conditionally compile backend-specific code.
  *
@@ -670,7 +670,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t		*surface,
     _cairo_output_stream_printf (surface->final_stream,
 				 "8 dict begin\n"
 				 "/FontType 3 def\n"
-				 "/FontMatrix [1 0 0 1 0 0] def\n"
+				 "/FontMatrix [1 0 0 -1 0 0] def\n"
 				 "/Encoding 256 array def\n"
 				 "0 1 255 { Encoding exch /.notdef put } for\n");
 
@@ -1053,7 +1053,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
     surface->ps_level_used = CAIRO_PS_LEVEL_2;
     surface->width  = width;
     surface->height = height;
-    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, height);
+    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
     surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
     surface->force_fallbacks = FALSE;
     surface->content = CAIRO_CONTENT_COLOR_ALPHA;
@@ -1401,7 +1401,7 @@ cairo_ps_surface_set_size (cairo_surface_t	*surface,
 
     ps_surface->width = width_in_points;
     ps_surface->height = height_in_points;
-    cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, -1, 0, height_in_points);
+    cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&ps_surface->pdf_operators,
 						  &ps_surface->cairo_to_ps);
     status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface,
@@ -2980,7 +2980,7 @@ _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t          *surface,
 
     surface->current_pattern_is_solid_color = FALSE;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
-    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
+    cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, 1, 0, 0);
     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
 						  &surface->cairo_to_ps);
     _cairo_output_stream_printf (surface->stream, "  q\n");
@@ -3232,8 +3232,12 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
     ps_p2d = surface->cairo_to_ps;
     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
     cairo_matrix_translate (&ps_p2d, x_offset, y_offset);
-    cairo_matrix_translate (&ps_p2d, 0.0, height);
-    cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
+    if (!(pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
+          ((cairo_surface_pattern_t *)pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING))
+    {
+	cairo_matrix_translate (&ps_p2d, 0.0, height);
+	cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
+    }
 
     if (! _cairo_matrix_is_identity (&ps_p2d)) {
 	_cairo_output_stream_printf (surface->stream, "[ ");
@@ -3421,11 +3425,13 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
     assert (status == CAIRO_STATUS_SUCCESS);
 
     cairo_matrix_init_identity (&ps_p2d);
-    cairo_matrix_translate (&ps_p2d, 0.0, surface->height);
-    cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
-    cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
-    cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
+
+    if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
+    {
+	cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
+	cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
+    }
 
     _cairo_output_stream_printf (surface->stream, "[ ");
     _cairo_output_stream_print_matrix (surface->stream, &ps_p2d);
@@ -4547,11 +4553,13 @@ _cairo_ps_surface_set_bounding_box (void		*abstract_surface,
 
     _cairo_output_stream_printf (surface->stream,
                                  "%%%%EndPageSetup\n"
-				 "q %d %d %d %d rectclip q\n",
+				 "q %d %d %d %d rectclip\n"
+                                 "1 0 0 -1 0 %f cm q\n",
 				 surface->page_bbox.x,
 				 surface->page_bbox.y,
 				 surface->page_bbox.width,
-				 surface->page_bbox.height);
+				 surface->page_bbox.height,
+				 surface->height);
 
     if (surface->num_pages == 1) {
 	surface->bbox_x1 = x1;
commit 14fa88fd02d81cdab52c882b98a1130148b72820
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    pdf: fix record-replay-extend test failures

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index b2a4416..9a922ec 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -146,6 +146,7 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
     cairo_surface_t *source, *proxy;
     cairo_matrix_t p2d, surface_transform;
     cairo_status_t status, analysis_status;
+    cairo_bool_t surface_is_unbounded;
     cairo_bool_t unused;
 
     assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
@@ -175,8 +176,12 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
     surface_transform = tmp->ctm;
     status = cairo_matrix_invert (&surface_transform);
     source = _cairo_surface_get_source (source, NULL);
+    surface_is_unbounded = (pattern->extend == CAIRO_EXTEND_REPEAT
+				     || pattern->extend == CAIRO_EXTEND_REFLECT);
     status = _cairo_recording_surface_replay_and_create_regions (source,
-								 &surface_transform, &tmp->base);
+								 &surface_transform,
+								 &tmp->base,
+								 surface_is_unbounded);
 
     if (!tmp->first_op)
 	_cairo_box_add_box (&surface->page_bbox, &tmp->page_bbox);
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index d08a407..68fa37c 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -355,7 +355,7 @@ _paint_page (cairo_paginated_surface_t *surface)
     surface->backend->set_paginated_mode (surface->target,
 	                                  CAIRO_PAGINATED_MODE_ANALYZE);
     status = _cairo_recording_surface_replay_and_create_regions (surface->recording_surface,
-								 NULL, analysis);
+								 NULL, analysis, FALSE);
     if (status)
 	goto FAIL;
 
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index cf1a608..0229dbc 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -166,6 +166,7 @@ struct _cairo_pdf_surface {
     double width;
     double height;
     cairo_rectangle_int_t surface_extents;
+    cairo_bool_t surface_bounded;
     cairo_matrix_t cairo_to_pdf;
     cairo_bool_t in_xobject;
 
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index af3e56c..1dd3c55 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -380,6 +380,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t	*output,
     surface->surface_extents.y = 0;
     surface->surface_extents.width  = ceil (surface->width);
     surface->surface_extents.height = ceil (surface->height);
+    surface->surface_bounded = TRUE;
 
     _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t));
     _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t));
@@ -3028,6 +3029,7 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
 {
     double old_width, old_height;
     cairo_rectangle_int_t old_surface_extents;
+    cairo_bool_t old_surface_bounded;
     cairo_paginated_mode_t old_paginated_mode;
     cairo_surface_clipper_t old_clipper;
     cairo_bool_t old_in_xobject;
@@ -3069,16 +3071,17 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
     old_height = surface->height;
     old_in_xobject = surface->in_xobject;
     old_surface_extents = surface->surface_extents;
+    old_surface_bounded = surface->surface_bounded;
     old_paginated_mode = surface->paginated_mode;
     old_clipper = surface->clipper;
     surface->surface_extents = *extents;
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_pdf_surface_clipper_intersect_clip_path);
 
-    _cairo_pdf_surface_set_size_internal (surface, width, height);
     _cairo_pdf_operators_reset (&surface->pdf_operators);
     surface->in_xobject = TRUE;
     surface->surface_extents = *extents;
+    surface->surface_bounded = FALSE;
 
     /* Patterns are emitted after fallback images. The paginated mode
      * needs to be set to _RENDER while the recording surface is replayed
@@ -3131,13 +3134,11 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
 
     _cairo_surface_clipper_reset (&surface->clipper);
     surface->clipper = old_clipper;
-    _cairo_pdf_surface_set_size_internal (surface,
-					  old_width,
-					  old_height);
     _cairo_pdf_operators_reset (&surface->pdf_operators);
     surface->in_xobject = old_in_xobject;
     surface->paginated_mode = old_paginated_mode;
     surface->surface_extents = old_surface_extents;
+    surface->surface_bounded = old_surface_bounded;
 
 err:
     cairo_surface_destroy (free_me);
@@ -3165,16 +3166,16 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
     cairo_extend_t extend = cairo_pattern_get_extend (pattern);
     double xstep, ystep;
     cairo_rectangle_int_t pattern_extents;
-    int pattern_width = 0; /* squelch bogus compiler warning */
-    int pattern_height = 0; /* squelch bogus compiler warning */
     double x_offset;
     double y_offset;
-    char draw_surface[200];
+    char draw_surface[50];
+    char draw_surface2[200];
     cairo_box_double_t bbox;
     cairo_matrix_t mat;
     cairo_pdf_source_surface_entry_t *pdf_source;
     cairo_rectangle_int_t op_extents;
 
+    assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
     if (pattern->extend == CAIRO_EXTEND_PAD) {
 	status = _cairo_pdf_surface_add_padded_image_surface (surface,
 							      pattern,
@@ -3202,8 +3203,6 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 	return status;
 
     pattern_extents = pdf_source->extents;
-    pattern_width = pdf_source->extents.width;
-    pattern_height = pdf_source->extents.height;
     if (!pdf_source->bounded)
     {
 	extend = CAIRO_EXTEND_NONE;
@@ -3238,13 +3237,12 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 	 * required an answer that's large enough, we don't really
 	 * care if it's not as tight as possible.*/
 	xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
-			      pattern_width + pattern_height);
+			      pattern_extents.width + pattern_extents.height);
     }
     break;
-
     case CAIRO_EXTEND_REPEAT:
-	xstep = pattern_width;
-	ystep = pattern_height;
+	xstep = pattern_extents.width;
+	ystep = pattern_extents.height;
 	break;
 
     case CAIRO_EXTEND_REFLECT:
@@ -3303,11 +3301,11 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
     cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
     if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
     {
-	cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
+	cairo_matrix_translate (&pdf_p2d, 0.0, pdf_source->extents.height);
 	cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
     }
 
-    _get_bbox_from_extents (pattern_height, &pattern_extents, &bbox);
+    _get_bbox_from_extents (pattern_extents.height, &pattern_extents, &bbox);
     _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
     status = _cairo_pdf_surface_open_stream (surface,
 				             &pdf_pattern->pattern_res,
@@ -3330,35 +3328,54 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
     if (unlikely (status))
 	return status;
 
-    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
-	((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
+    if (((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
 	snprintf(draw_surface,
 		 sizeof (draw_surface),
-		 "/x%d Do\n",
+		 "/x%d Do",
 		 pdf_source->surface_res.id);
     } else {
 	snprintf(draw_surface,
 		 sizeof (draw_surface),
 		 "q %d 0 0 %d 0 0 cm /x%d Do Q",
-		 pattern_width,
-		 pattern_height,
+		 pdf_source->extents.width,
+		 pdf_source->extents.height,
 		 pdf_source->surface_res.id);
     }
 
     if (extend == CAIRO_EXTEND_REFLECT) {
-	_cairo_output_stream_printf (surface->output,
-				     "q 0 0 %d %d re W n %s Q\n"
-				     "q -1 0 0 1 %d 0 cm 0 0 %d %d re W n %s Q\n"
-				     "q 1 0 0 -1 0 %d cm 0 0 %d %d re W n %s Q\n"
-				     "q -1 0 0 -1 %d %d cm 0 0 %d %d re W n %s Q\n",
-				     pattern_width, pattern_height,
-				     draw_surface,
-				     pattern_width*2, pattern_width, pattern_height,
-				     draw_surface,
-				     pattern_height*2, pattern_width, pattern_height,
-				     draw_surface,
-				     pattern_width*2, pattern_height*2, pattern_width, pattern_height,
-				     draw_surface);
+	cairo_rectangle_int_t p_extents = pdf_source->extents;
+	snprintf(draw_surface2,
+		 sizeof (draw_surface2),
+		 "%d %d %d %d re W n %s",
+		 p_extents.x, p_extents.y,
+		 p_extents.width, p_extents.height,
+		 draw_surface);
+
+	_cairo_output_stream_printf (surface->output, "q %s Q\n", draw_surface2);
+
+	cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
+	cairo_matrix_scale (&mat, -1, 1);
+	cairo_matrix_translate (&mat, -2*p_extents.width, 0);
+	cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
+	_cairo_output_stream_printf (surface->output, "q ");
+	_cairo_output_stream_print_matrix (surface->output, &mat);
+	_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
+
+	cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
+	cairo_matrix_scale (&mat, 1, -1);
+	cairo_matrix_translate (&mat, 0, -2*p_extents.height);
+	cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
+	_cairo_output_stream_printf (surface->output, "q ");
+	_cairo_output_stream_print_matrix (surface->output, &mat);
+	_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
+
+	cairo_matrix_init_translate (&mat, p_extents.x, p_extents.y);
+	cairo_matrix_scale (&mat, -1, -1);
+	cairo_matrix_translate (&mat, -2*p_extents.width, -2*p_extents.height);
+	cairo_matrix_translate (&mat, -p_extents.x, -p_extents.y);
+	_cairo_output_stream_printf (surface->output, "q ");
+	_cairo_output_stream_print_matrix (surface->output, &mat);
+	_cairo_output_stream_printf (surface->output, " cm %s Q\n", draw_surface2);
     } else {
 	_cairo_output_stream_printf (surface->output,
 				     " %s \n",
@@ -4681,9 +4698,10 @@ _cairo_pdf_surface_get_extents (void		        *abstract_surface,
 {
     cairo_pdf_surface_t *surface = abstract_surface;
 
-    *rectangle = surface->surface_extents;
+    if (surface->surface_bounded)
+	*rectangle = surface->surface_extents;
 
-    return TRUE;
+    return surface->surface_bounded;
 }
 
 static void
@@ -6280,9 +6298,11 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t     *surface,
     cairo_bool_t old_in_xobject;
     cairo_int_status_t status;
     cairo_box_double_t bbox;
+    cairo_rectangle_int_t old_surface_extents;
 
     old_width = surface->width;
     old_height = surface->height;
+    old_surface_extents = surface->surface_extents;
     old_in_xobject = surface->in_xobject;
     surface->in_xobject = TRUE;
     _cairo_pdf_surface_set_size_internal (surface,
@@ -6352,6 +6372,7 @@ RESTORE_SIZE:
     _cairo_pdf_surface_set_size_internal (surface,
 					  old_width,
 					  old_height);
+    surface->surface_extents = old_surface_extents;
     _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return status;
diff --git a/src/cairo-recording-surface-private.h b/src/cairo-recording-surface-private.h
index 9f5216d..021b73c 100644
--- a/src/cairo-recording-surface-private.h
+++ b/src/cairo-recording-surface-private.h
@@ -170,7 +170,8 @@ _cairo_recording_surface_replay_with_clip (cairo_surface_t *surface,
 cairo_private cairo_status_t
 _cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface,
 						    const cairo_matrix_t *surface_transform,
-						    cairo_surface_t *target);
+						    cairo_surface_t *target,
+						    cairo_bool_t surface_is_unbounded);
 cairo_private cairo_status_t
 _cairo_recording_surface_replay_region (cairo_surface_t			*surface,
 					const cairo_rectangle_int_t *surface_extents,
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 94d7a5a..d35512e 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -725,10 +725,6 @@ _cairo_recording_surface_paint (void			  *abstract_surface,
 	  (surface->base.is_clear || _cairo_pattern_is_opaque_solid (source)))))
     {
 	_cairo_recording_surface_reset (surface);
-	if (is_identity_recording_pattern (source)) {
-	    cairo_surface_t *src = ((cairo_surface_pattern_t *)source)->surface;
-	    return _cairo_recording_surface_replay (src, &surface->base);
-	}
     }
 
     status = _cairo_composite_rectangles_init_for_paint (&composite,
@@ -1676,6 +1672,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
 					  const cairo_matrix_t *surface_transform,
 					  cairo_surface_t	     *target,
 					  const cairo_clip_t *target_clip,
+					  cairo_bool_t surface_is_unbounded,
 					  cairo_recording_replay_type_t type,
 					  cairo_recording_region_type_t region)
 {
@@ -1708,7 +1705,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
     if (surface_extents)
 	_cairo_surface_wrapper_intersect_extents (&wrapper, surface_extents);
     r = &_cairo_unbounded_rectangle;
-    if (! surface->unbounded) {
+    if (! surface->unbounded && !surface_is_unbounded) {
 	_cairo_surface_wrapper_intersect_extents (&wrapper, &surface->extents);
 	r = &surface->extents;
     }
@@ -1716,7 +1713,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
     _cairo_surface_wrapper_set_clip (&wrapper, target_clip);
 
     /* Compute the extents of the target clip in recorded device space */
-    if (! _cairo_surface_wrapper_get_target_extents (&wrapper, &extents))
+    if (! _cairo_surface_wrapper_get_target_extents (&wrapper, surface_is_unbounded, &extents))
 	goto done;
 
     surface->has_bilevel_alpha = TRUE;
@@ -2001,7 +1998,7 @@ _cairo_recording_surface_replay (cairo_surface_t *surface,
 				 cairo_surface_t *target)
 {
     return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, NULL,
-						     target, NULL,
+						     target, NULL, FALSE,
 						     CAIRO_RECORDING_REPLAY,
 						     CAIRO_RECORDING_REGION_ALL);
 }
@@ -2013,7 +2010,7 @@ _cairo_recording_surface_replay_with_clip (cairo_surface_t *surface,
 					   const cairo_clip_t *target_clip)
 {
     return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, surface_transform,
-						     target, target_clip,
+						     target, target_clip, FALSE,
 						     CAIRO_RECORDING_REPLAY,
 						     CAIRO_RECORDING_REGION_ALL);
 }
@@ -2027,10 +2024,12 @@ _cairo_recording_surface_replay_with_clip (cairo_surface_t *surface,
 cairo_status_t
 _cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface,
 						    const cairo_matrix_t *surface_transform,
-						    cairo_surface_t *target)
+						    cairo_surface_t *target,
+						    cairo_bool_t surface_is_unbounded)
 {
     return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, surface_transform,
 						     target, NULL,
+						     surface_is_unbounded,
 						     CAIRO_RECORDING_CREATE_REGIONS,
 						     CAIRO_RECORDING_REGION_ALL);
 }
@@ -2043,7 +2042,7 @@ _cairo_recording_surface_replay_region (cairo_surface_t          *surface,
 {
     return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface,
 						     surface_extents, NULL,
-						     target, NULL,
+						     target, NULL, FALSE,
 						     CAIRO_RECORDING_REPLAY,
 						     region);
 }
diff --git a/src/cairo-surface-wrapper-private.h b/src/cairo-surface-wrapper-private.h
index 6529ebc..e412fc6 100644
--- a/src/cairo-surface-wrapper-private.h
+++ b/src/cairo-surface-wrapper-private.h
@@ -186,6 +186,7 @@ _cairo_surface_wrapper_is_active (cairo_surface_wrapper_t *wrapper)
 
 cairo_private cairo_bool_t
 _cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper,
+					   cairo_bool_t surface_is_unbounded,
 					   cairo_rectangle_int_t *extents);
 
 CAIRO_END_DECLS
diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index f69755f..b9b4b44 100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -625,12 +625,15 @@ _cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper)
 
 cairo_bool_t
 _cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper,
+					   cairo_bool_t surface_is_unbounded,
 					   cairo_rectangle_int_t *extents)
 {
     cairo_rectangle_int_t clip;
-    cairo_bool_t has_clip;
+    cairo_bool_t has_clip = FALSE;
+
+    if (!surface_is_unbounded)
+	has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
 
-    has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
     if (wrapper->clip) {
 	if (has_clip) {
 	    if (! _cairo_rectangle_intersect (&clip,
diff --git a/test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png b/test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png
index 1592836..78feffb 100644
Binary files a/test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png and b/test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png b/test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png
index 1592836..78feffb 100644
Binary files a/test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png and b/test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-replay-extend-none.pdf.argb32.ref.png b/test/reference/record-replay-extend-none.pdf.argb32.ref.png
new file mode 100644
index 0000000..6ca0f10
Binary files /dev/null and b/test/reference/record-replay-extend-none.pdf.argb32.ref.png differ
diff --git a/test/reference/record-replay-extend-none.pdf.rgb24.ref.png b/test/reference/record-replay-extend-none.pdf.rgb24.ref.png
new file mode 100644
index 0000000..3cbe869
Binary files /dev/null and b/test/reference/record-replay-extend-none.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-replay-extend-pad.pdf.argb32.ref.png b/test/reference/record-replay-extend-pad.pdf.argb32.ref.png
new file mode 100644
index 0000000..74d3043
Binary files /dev/null and b/test/reference/record-replay-extend-pad.pdf.argb32.ref.png differ
diff --git a/test/reference/record-replay-extend-reflect.pdf.argb32.ref.png b/test/reference/record-replay-extend-reflect.pdf.argb32.ref.png
new file mode 100644
index 0000000..d7845ab
Binary files /dev/null and b/test/reference/record-replay-extend-reflect.pdf.argb32.ref.png differ
diff --git a/test/reference/record-replay-extend-reflect.pdf.rgb24.ref.png b/test/reference/record-replay-extend-reflect.pdf.rgb24.ref.png
new file mode 100644
index 0000000..2c47015
Binary files /dev/null and b/test/reference/record-replay-extend-reflect.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-replay-extend-repeat.pdf.argb32.ref.png b/test/reference/record-replay-extend-repeat.pdf.argb32.ref.png
new file mode 100644
index 0000000..4df0313
Binary files /dev/null and b/test/reference/record-replay-extend-repeat.pdf.argb32.ref.png differ
diff --git a/test/reference/record-replay-extend-repeat.pdf.rgb24.ref.png b/test/reference/record-replay-extend-repeat.pdf.rgb24.ref.png
new file mode 100644
index 0000000..7efac20
Binary files /dev/null and b/test/reference/record-replay-extend-repeat.pdf.rgb24.ref.png differ
commit e7b1cb0c53fe0dc9af4cae280c34d98a1165bcf1
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    image: fix record-replay-extend test failures

diff --git a/src/cairo-image-source.c b/src/cairo-image-source.c
index 4b79db9..3e3ca28 100644
--- a/src/cairo-image-source.c
+++ b/src/cairo-image-source.c
@@ -1113,10 +1113,12 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
 {
     cairo_surface_t *source, *clone, *proxy;
     cairo_rectangle_int_t limit;
+    cairo_rectangle_int_t src_limit;
     pixman_image_t *pixman_image;
     cairo_status_t status;
     cairo_extend_t extend;
     cairo_matrix_t *m, matrix;
+    double sx = 1.0, sy = 1.0;
     int tx = 0, ty = 0;
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
@@ -1124,34 +1126,38 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
     *ix = *iy = 0;
 
     source = _cairo_pattern_get_source (pattern, &limit);
+    src_limit = limit;
 
     extend = pattern->base.extend;
     if (_cairo_rectangle_contains_rectangle (&limit, sample))
 	extend = CAIRO_EXTEND_NONE;
+
     if (extend == CAIRO_EXTEND_NONE) {
 	if (! _cairo_rectangle_intersect (&limit, sample))
 	    return _pixman_transparent_image ();
+    }
 
-	if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
-	    double x1, y1, x2, y2;
-
-	    matrix = pattern->base.matrix;
-	    status = cairo_matrix_invert (&matrix);
-	    assert (status == CAIRO_STATUS_SUCCESS);
-
-	    x1 = limit.x;
-	    y1 = limit.y;
-	    x2 = limit.x + limit.width;
-	    y2 = limit.y + limit.height;
-
-	    _cairo_matrix_transform_bounding_box (&matrix,
-						  &x1, &y1, &x2, &y2, NULL);
+    if (! _cairo_matrix_is_identity (&pattern->base.matrix)) {
+	double x1, y1, x2, y2;
 
-	    limit.x = floor (x1);
-	    limit.y = floor (y1);
-	    limit.width  = ceil (x2) - limit.x;
-	    limit.height = ceil (y2) - limit.y;
-	}
+	matrix = pattern->base.matrix;
+	status = cairo_matrix_invert (&matrix);
+	assert (status == CAIRO_STATUS_SUCCESS);
+
+	x1 = limit.x;
+	y1 = limit.y;
+	x2 = limit.x + limit.width;
+	y2 = limit.y + limit.height;
+
+	_cairo_matrix_transform_bounding_box (&matrix,
+					      &x1, &y1, &x2, &y2, NULL);
+
+	limit.x = floor (x1);
+	limit.y = floor (y1);
+	limit.width  = ceil (x2) - limit.x;
+	limit.height = ceil (y2) - limit.y;
+	sx = (double)src_limit.width / limit.width;
+	sy = (double)src_limit.height / limit.height;
     }
     tx = limit.x;
     ty = limit.y;
@@ -1183,7 +1189,9 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
 	    cairo_matrix_translate (&matrix, tx, ty);
 	m = &matrix;
     } else {
-	/* XXX extract scale factor for repeating patterns */
+	cairo_matrix_init_scale (&matrix, sx, sy);
+	cairo_matrix_translate (&matrix, src_limit.x/sx, src_limit.y/sy);
+	m = &matrix;
     }
 
     /* Handle recursion by returning future reads from the current image */
@@ -1199,11 +1207,22 @@ done:
     pixman_image = pixman_image_ref (((cairo_image_surface_t *)clone)->pixman_image);
     cairo_surface_destroy (clone);
 
-    *ix = -limit.x;
-    *iy = -limit.y;
-    if (extend != CAIRO_EXTEND_NONE) {
+    if (extend == CAIRO_EXTEND_NONE) {
+	*ix = -limit.x;
+	*iy = -limit.y;
+    } else {
+	cairo_pattern_union_t tmp_pattern;
+	_cairo_pattern_init_static_copy (&tmp_pattern.base, &pattern->base);
+	matrix = pattern->base.matrix;
+	status = cairo_matrix_invert(&matrix);
+	assert (status == CAIRO_STATUS_SUCCESS);
+	cairo_matrix_translate (&matrix, src_limit.x, src_limit.y);
+	cairo_matrix_scale (&matrix, sx, sy);
+	status = cairo_matrix_invert(&matrix);
+	assert (status == CAIRO_STATUS_SUCCESS);
+	cairo_pattern_set_matrix (&tmp_pattern.base, &matrix);
 	if (! _pixman_image_set_properties (pixman_image,
-					    &pattern->base, extents,
+					    &tmp_pattern.base, extents,
 					    ix, iy)) {
 	    pixman_image_unref (pixman_image);
 	    pixman_image= NULL;
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 9cb89e9..3aafcb2 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -357,6 +357,7 @@ _cairo_pattern_init_copy (cairo_pattern_t	*pattern,
     /* The reference count and user_data array are unique to the copy. */
     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
     _cairo_user_data_array_init (&pattern->user_data);
+    cairo_list_init (&pattern->observers);
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -396,6 +397,7 @@ _cairo_pattern_init_static_copy (cairo_pattern_t	*pattern,
 
     CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
     _cairo_user_data_array_init (&pattern->user_data);
+    cairo_list_init (&pattern->observers);
 }
 
 cairo_status_t
diff --git a/test/reference/record-replay-extend-pad.ref.png b/test/reference/record-replay-extend-pad.ref.png
new file mode 100644
index 0000000..7acd8af
Binary files /dev/null and b/test/reference/record-replay-extend-pad.ref.png differ
diff --git a/test/reference/record-replay-extend-reflect.ref.png b/test/reference/record-replay-extend-reflect.ref.png
new file mode 100644
index 0000000..de53e5c
Binary files /dev/null and b/test/reference/record-replay-extend-reflect.ref.png differ
diff --git a/test/reference/record-replay-extend-repeat.ref.png b/test/reference/record-replay-extend-repeat.ref.png
new file mode 100644
index 0000000..5a95d86
Binary files /dev/null and b/test/reference/record-replay-extend-repeat.ref.png differ
commit 8e4d4de2a3ceb67188c93f8fbf22ed79be927753
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    test: replay record surface with negative extents for each extend mode
    
    image fails for repeat, reflect, and pad.

diff --git a/test/Makefile.sources b/test/Makefile.sources
index 2d3781a..8a11c0b 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -274,6 +274,7 @@ test_sources = \
 	record-extend.c					\
 	record-neg-extents.c                            \
 	record-mesh.c					\
+	record-replay-extend.c                          \
 	recording-ink-extents.c                         \
 	recording-surface-pattern.c			\
 	recording-surface-extend.c			\
diff --git a/test/record-replay-extend.c b/test/record-replay-extend.c
new file mode 100644
index 0000000..4a41233
--- /dev/null
+++ b/test/record-replay-extend.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright © 2016 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#include "cairo-test.h"
+#include <stdio.h>
+#include <math.h>
+
+#define PAT_SIZE  32
+#define REPLAY_SIZE (PAT_SIZE*4)
+#define PAD 10
+#define WIDTH (REPLAY_SIZE*4 + PAD*5)
+#define HEIGHT (REPLAY_SIZE + PAD*2)
+
+/* Test replaying a recording surface pattern for each type of extend. */
+
+static void
+transform_extents(cairo_rectangle_t *extents, cairo_matrix_t *mat)
+{
+    double x1, y1, x2, y2, x, y;
+
+#define UPDATE_BBOX \
+    x1 = x < x1 ? x : x1; \
+    y1 = y < y1 ? y : y1; \
+    x2 = x > x2 ? x : x2; \
+    y2 = y > y2 ? y : y2;
+
+    x = extents->x;
+    y = extents->y;
+    cairo_matrix_transform_point (mat, &x, &y);
+    x1 = x2 = x;
+    y1 = y2 = y;
+
+    x = extents->x + extents->width;
+    y = extents->y;
+    cairo_matrix_transform_point (mat, &x, &y);
+    UPDATE_BBOX;
+
+    x = extents->x;
+    y = extents->y + extents->height;
+    cairo_matrix_transform_point (mat, &x, &y);
+    UPDATE_BBOX;
+
+    x = extents->x + extents->width;
+    y = extents->y + extents->height;
+    cairo_matrix_transform_point (mat, &x, &y);
+    UPDATE_BBOX;
+
+    extents->x = x1;
+    extents->y = y1;
+    extents->width = x2 - extents->x;
+    extents->height = y2 - extents->y;
+
+#undef UPDATE_BBOX
+}
+
+static cairo_pattern_t *
+create_pattern (cairo_matrix_t *mat, cairo_extend_t extend)
+{
+    cairo_surface_t *surf;
+    cairo_pattern_t *pat;
+    cairo_t *cr;
+    cairo_rectangle_t extents = { 0, 0, PAT_SIZE, PAT_SIZE };
+
+    transform_extents (&extents, mat);
+    surf = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, &extents);
+
+    cr = cairo_create (surf);
+    cairo_transform (cr, mat);
+
+    cairo_rectangle (cr, 0, 0, PAT_SIZE/2, PAT_SIZE/2);
+    cairo_set_source_rgb (cr, 1, 0, 0);
+    cairo_fill (cr);
+
+    cairo_translate (cr, PAT_SIZE/2, 0);
+    cairo_rectangle (cr, 0, 0, PAT_SIZE/2, PAT_SIZE/2);
+    cairo_set_source_rgb (cr, 0, 1, 0);
+    cairo_fill (cr);
+
+    cairo_translate (cr, 0, PAT_SIZE/2);
+    cairo_rectangle (cr, 0, 0, PAT_SIZE/2, PAT_SIZE/2);
+    cairo_set_source_rgb (cr, 0, 0, 1);
+    cairo_fill (cr);
+
+    cairo_translate (cr, -PAT_SIZE/2, 0);
+    cairo_rectangle (cr, 0, 0, PAT_SIZE/2, PAT_SIZE/2);
+    cairo_set_source_rgb (cr, 1, 1, 0);
+    cairo_fill (cr);
+
+    cairo_destroy (cr);
+
+    pat = cairo_pattern_create_for_surface (surf);
+    cairo_surface_destroy (surf);
+    cairo_pattern_set_matrix (pat, mat);
+    cairo_pattern_set_extend (pat, extend);
+    cairo_pattern_set_filter (pat, CAIRO_FILTER_NEAREST);
+
+    return pat;
+}
+
+static cairo_test_status_t
+record_replay_extend (cairo_t *cr, int width, int height, cairo_extend_t extend)
+{
+    cairo_pattern_t *pat;
+    cairo_matrix_t mat;
+
+    /* record surface extents (-PAT_SIZE/2, -PAT_SIZE/2) to (PAT_SIZE/2, PAT_SIZE/2) */
+    cairo_translate (cr, PAD, PAD);
+    cairo_matrix_init_translate (&mat, -PAT_SIZE/2, -PAT_SIZE/2);
+    pat = create_pattern (&mat, extend);
+
+    /* test repeating patterns when the source is outside of the target clip */
+    if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) {
+	cairo_matrix_init_translate (&mat, 3*PAT_SIZE/2, 3*PAT_SIZE/2);
+	cairo_pattern_set_matrix (pat, &mat);
+    }
+
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_rectangle (cr, 0, 0, REPLAY_SIZE, REPLAY_SIZE);
+    cairo_fill (cr);
+
+    /* record surface extents (-2*PAT_SIZE/2, -2*PAT_SIZE/2) to (2*PAT_SIZE/2, 2*PAT_SIZE/2) */
+    cairo_translate (cr, REPLAY_SIZE + PAD, 0);
+    cairo_matrix_init_translate (&mat, -2.0*PAT_SIZE/2, -2.0*PAT_SIZE/2);
+    cairo_matrix_scale (&mat, 2, 2);
+    pat = create_pattern (&mat, extend);
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_rectangle (cr, 0, 0, REPLAY_SIZE, REPLAY_SIZE);
+    cairo_fill (cr);
+
+    /* record surface extents (-0.5*PAT_SIZE/2, -0.5*PAT_SIZE/2) to (0.5*PAT_SIZE/2, 0.5*PAT_SIZE/2) */
+    cairo_translate (cr, REPLAY_SIZE + PAD, 0);
+    cairo_matrix_init_translate (&mat, -0.5*PAT_SIZE/2, -0.5*PAT_SIZE/2);
+    cairo_matrix_scale (&mat, 0.5, 0.5);
+    pat = create_pattern (&mat, extend);
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_rectangle (cr, 0, 0, REPLAY_SIZE, REPLAY_SIZE);
+    cairo_fill (cr);
+
+    /* record surface centered on (0,0) and rotated 45 deg */
+    cairo_translate (cr, REPLAY_SIZE + PAD, 0);
+    cairo_matrix_init_translate (&mat, -PAT_SIZE/sqrt(2), -PAT_SIZE/sqrt(2));
+    cairo_matrix_rotate (&mat, M_PI/4.0);
+    cairo_matrix_translate (&mat, PAT_SIZE/2, -PAT_SIZE/2);
+    pat = create_pattern (&mat, extend);
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_rectangle (cr, 0, 0, REPLAY_SIZE, REPLAY_SIZE);
+    cairo_fill (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_replay_extend_none (cairo_t *cr, int width, int height)
+{
+    return record_replay_extend (cr, width, height, CAIRO_EXTEND_NONE);
+}
+
+static cairo_test_status_t
+record_replay_extend_repeat (cairo_t *cr, int width, int height)
+{
+    return record_replay_extend (cr, width, height, CAIRO_EXTEND_REPEAT);
+}
+
+static cairo_test_status_t
+record_replay_extend_reflect (cairo_t *cr, int width, int height)
+{
+    return record_replay_extend (cr, width, height, CAIRO_EXTEND_REFLECT);
+}
+
+static cairo_test_status_t
+record_replay_extend_pad (cairo_t *cr, int width, int height)
+{
+    return record_replay_extend (cr, width, height, CAIRO_EXTEND_PAD);
+}
+
+CAIRO_TEST (record_replay_extend_none,
+	    "Paint recording pattern with CAIRO_EXTEND_NONE",
+	    "record,pattern,extend", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, record_replay_extend_none)
+CAIRO_TEST (record_replay_extend_repeat,
+	    "Paint recording pattern with CAIRO_EXTEND_REPEAT",
+	    "record,pattern,extend", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, record_replay_extend_repeat)
+CAIRO_TEST (record_replay_extend_reflect,
+	    "Paint recording pattern with CAIRO_EXTEND_REFLECT",
+	    "record,pattern,extend", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, record_replay_extend_reflect)
+CAIRO_TEST (record_replay_extend_pad,
+	    "Paint recording pattern with CAIRO_EXTEND_PAD",
+	    "record,pattern,extend", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, record_replay_extend_pad)
diff --git a/test/reference/record-replay-extend-none.ref.png b/test/reference/record-replay-extend-none.ref.png
new file mode 100644
index 0000000..204c765
Binary files /dev/null and b/test/reference/record-replay-extend-none.ref.png differ
commit a736fd8699e0ebcdd98392acb8383ea414688caf
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    Fix PDF record-neg-extents test failure
    
    Modify PDF surface to allow surface extents to have negative x, y.
    When emitting recording surfaces, set the surface extents to the
    recording extents.

diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index fb5ef0e..b2a4416 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -146,6 +146,7 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
     cairo_surface_t *source, *proxy;
     cairo_matrix_t p2d, surface_transform;
     cairo_status_t status, analysis_status;
+    cairo_bool_t unused;
 
     assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
     surface_pattern = (const cairo_surface_pattern_t *) pattern;
@@ -176,7 +177,22 @@ _analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
     source = _cairo_surface_get_source (source, NULL);
     status = _cairo_recording_surface_replay_and_create_regions (source,
 								 &surface_transform, &tmp->base);
+
+    if (!tmp->first_op)
+	_cairo_box_add_box (&surface->page_bbox, &tmp->page_bbox);
+
+    if (tmp->has_supported) {
+	surface->has_supported = TRUE;
+	unused = cairo_region_union (&surface->supported_region, &tmp->supported_region);
+    }
+
+    if (tmp->has_unsupported) {
+	surface->has_unsupported = TRUE;
+	unused = cairo_region_union (&surface->fallback_region, &tmp->fallback_region);
+    }
+
     analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS;
+
     detach_proxy (proxy);
     cairo_surface_destroy (&tmp->base);
 
diff --git a/src/cairo-debug.c b/src/cairo-debug.c
index 33d46aa..dbc9e2f 100644
--- a/src/cairo-debug.c
+++ b/src/cairo-debug.c
@@ -237,7 +237,7 @@ _print_close (void *closure)
 }
 
 void
-_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path)
+_cairo_debug_print_path (FILE *stream, const cairo_path_fixed_t *path)
 {
     cairo_status_t status;
     cairo_box_t box;
@@ -302,3 +302,12 @@ _cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon)
 
     }
 }
+
+void
+_cairo_debug_print_matrix (FILE *file, const cairo_matrix_t *matrix)
+{
+    fprintf (file, "[%g %g %g %g %g %g]\n",
+	     matrix->xx, matrix->yx,
+	     matrix->xy, matrix->yy,
+	     matrix->x0, matrix->y0);
+}
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index b4bc83c..9cb89e9 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -4607,7 +4607,36 @@ static void
 _cairo_debug_print_surface_pattern (FILE *file,
 				    const cairo_surface_pattern_t *pattern)
 {
-    printf ("  surface type: %d\n", pattern->surface->type);
+    const char *s;
+    switch (pattern->surface->type) {
+    case CAIRO_SURFACE_TYPE_IMAGE: s = "image"; break;
+    case CAIRO_SURFACE_TYPE_PDF: s = "pdf"; break;
+    case CAIRO_SURFACE_TYPE_PS: s = "ps"; break;
+    case CAIRO_SURFACE_TYPE_XLIB: s = "xlib"; break;
+    case CAIRO_SURFACE_TYPE_XCB: s = "xcb"; break;
+    case CAIRO_SURFACE_TYPE_GLITZ: s = "glitz"; break;
+    case CAIRO_SURFACE_TYPE_QUARTZ: s = "quartz"; break;
+    case CAIRO_SURFACE_TYPE_WIN32: s = "win32"; break;
+    case CAIRO_SURFACE_TYPE_BEOS: s = "beos"; break;
+    case CAIRO_SURFACE_TYPE_DIRECTFB: s = "directfb"; break;
+    case CAIRO_SURFACE_TYPE_SVG: s = "svg"; break;
+    case CAIRO_SURFACE_TYPE_OS2: s = "os2"; break;
+    case CAIRO_SURFACE_TYPE_WIN32_PRINTING: s = "win32_printing"; break;
+    case CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: s = "quartz_image"; break;
+    case CAIRO_SURFACE_TYPE_SCRIPT: s = "script"; break;
+    case CAIRO_SURFACE_TYPE_QT: s = "qt"; break;
+    case CAIRO_SURFACE_TYPE_RECORDING: s = "recording"; break;
+    case CAIRO_SURFACE_TYPE_VG: s = "vg"; break;
+    case CAIRO_SURFACE_TYPE_GL: s = "gl"; break;
+    case CAIRO_SURFACE_TYPE_DRM: s = "drm"; break;
+    case CAIRO_SURFACE_TYPE_TEE: s = "tee"; break;
+    case CAIRO_SURFACE_TYPE_XML: s = "xml"; break;
+    case CAIRO_SURFACE_TYPE_SKIA: s = "skia"; break;
+    case CAIRO_SURFACE_TYPE_SUBSURFACE: s = "subsurface"; break;
+    case CAIRO_SURFACE_TYPE_COGL: s = "cogl"; break;
+    default: s = "invalid"; ASSERT_NOT_REACHED; break;
+    }
+    fprintf (file, "  surface type: %s\n", s);
 }
 
 static void
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index 66ebf60..cf1a608 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -76,9 +76,14 @@ typedef struct _cairo_pdf_source_surface_entry {
     cairo_bool_t smask;
     cairo_pdf_resource_t surface_res;
     cairo_pdf_resource_t smask_res;
-    int width;
-    int height;
+
+    /* Extents of the source surface. If bounded is false,
+     * extents is the ink extents. */
+    cairo_bool_t bounded;
     cairo_rectangle_int_t extents;
+
+    /* Union of source extents requried for all operations using this source */
+    cairo_rectangle_int_t required_extents;
 } cairo_pdf_source_surface_entry_t;
 
 typedef struct _cairo_pdf_source_surface {
@@ -160,6 +165,7 @@ struct _cairo_pdf_surface {
 
     double width;
     double height;
+    cairo_rectangle_int_t surface_extents;
     cairo_matrix_t cairo_to_pdf;
     cairo_bool_t in_xobject;
 
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index db75bc6..af3e56c 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -300,6 +300,10 @@ _cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface,
 {
     surface->width = width;
     surface->height = height;
+    surface->surface_extents.x = 0;
+    surface->surface_extents.y = 0;
+    surface->surface_extents.width  = ceil (surface->width);
+    surface->surface_extents.height = ceil (surface->height);
 }
 
 static cairo_bool_t
@@ -372,6 +376,10 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t	*output,
     surface->height = height;
     cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, 1, 0, 0);
     surface->in_xobject = FALSE;
+    surface->surface_extents.x = 0;
+    surface->surface_extents.y = 0;
+    surface->surface_extents.width  = ceil (surface->width);
+    surface->surface_extents.height = ceil (surface->height);
 
     _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t));
     _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t));
@@ -1237,16 +1245,18 @@ _get_jpeg_image_info (cairo_surface_t		 *source,
 }
 
 static cairo_int_status_t
-_get_source_surface_size (cairo_surface_t         *source,
-			  int                     *width,
-			  int                     *height,
-			  cairo_rectangle_int_t   *extents)
+_get_source_surface_extents (cairo_surface_t         *source,
+			     cairo_rectangle_int_t   *extents,
+			     cairo_bool_t            *bounded,
+			     cairo_bool_t            *subsurface)
 {
     cairo_int_status_t status;
     cairo_image_info_t info;
     const unsigned char *mime_data;
     unsigned long mime_data_length;
 
+    *bounded = TRUE;
+    *subsurface = FALSE;
     if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
 	cairo_surface_t *free_me = NULL;
 
@@ -1257,28 +1267,20 @@ _get_source_surface_size (cairo_surface_t         *source,
 	    cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
 
 	    *extents = sub->extents;
-	    extents->x = 0;
-	    extents->y = 0;
-	    *width  = extents->width;
-	    *height = extents->height;
+	    *subsurface = TRUE;
 	} else {
 	    cairo_rectangle_int_t surf_extents;
 	    cairo_box_t box;
-	    cairo_bool_t bounded;
 
-	    status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)source,
-							    &box, NULL);
-	    if (unlikely (status)) {
-		cairo_surface_destroy (free_me);
-		return status;
+	    if (! _cairo_surface_get_extents (source, extents)) {
+		    status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)source,
+								    &box, NULL);
+		    if (unlikely (status)) {
+			cairo_surface_destroy (free_me);
+			return status;
+		    }
+		    _cairo_box_round_to_rectangle (&box, extents);
 	    }
-
-	    bounded = _cairo_surface_get_extents (source, &surf_extents);
-
-	    *width = surf_extents.width;
-	    *height = surf_extents.height;
-
-	    _cairo_box_round_to_rectangle (&box, extents);
 	}
 	cairo_surface_destroy (free_me);
 
@@ -1290,8 +1292,6 @@ _get_source_surface_size (cairo_surface_t         *source,
 
     status = _get_jbig2_image_info (source, &info, &mime_data, &mime_data_length);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-	*width = info.width;
-	*height = info.height;
 	extents->width = info.width;
 	extents->height = info.height;
 	return status;
@@ -1299,8 +1299,6 @@ _get_source_surface_size (cairo_surface_t         *source,
 
     status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-	*width = info.width;
-	*height = info.height;
 	extents->width = info.width;
 	extents->height = info.height;
 	return status;
@@ -1308,8 +1306,6 @@ _get_source_surface_size (cairo_surface_t         *source,
 
     status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
-	*width = info.width;
-	*height = info.height;
 	extents->width = info.width;
 	extents->height = info.height;
 	return status;
@@ -1318,9 +1314,6 @@ _get_source_surface_size (cairo_surface_t         *source,
     if (! _cairo_surface_get_extents (source, extents))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    *width = extents->width;
-    *height = extents->height;
-
     return CAIRO_STATUS_SUCCESS;
 }
 
@@ -1333,51 +1326,52 @@ _get_source_surface_size (cairo_surface_t         *source,
  * @filter: filter type of the source pattern
  * @stencil_mask: if true, the surface will be written to the PDF as an /ImageMask
  * @smask: if true, only the alpha channel will be written (images only)
+ * @smask_res: if not NULL, the image written will specify this resource as the smask for
+   the image (images only)
  * @extents: extents of the operation that is using this source
- * @smask_res: if not NULL, the image written will specify this resource as the smask for the image (images only)
- * @surface_res: return PDF resource number of the surface
- * @width: returns width of surface
- * @height: returns height of surface
- * @x_offset: x offset of surface
- * @t_offset: y offset of surface
- * @source_extents: returns extents of source (either ink extents or extents needed to cover @extents)
+ * @pdf_source: return pdf_source_surface entry in hash table
+ * @x_offset: if not NULL return x offset of surface
+ * @y_offset: if not NULL return y offset of surface
+ * @source_extents: if not NULL return operation extents in source space
  *
  * Add surface or raster_source pattern to list of surfaces to be
  * written to the PDF file when the current page is finished. Returns
- * a PDF resource to reference the image. A hash table of all images
- * in the PDF files (keyed by CAIRO_MIME_TYPE_UNIQUE_ID or surface
- * unique_id) to ensure surfaces with the same id are only written
- * once to the PDF file.
+ * a PDF resource to reference the surface. A hash table of all
+ * surfaces in the PDF file (keyed by CAIRO_MIME_TYPE_UNIQUE_ID or
+ * surface unique_id) is used to ensure surfaces with the same id are
+ * only written once to the PDF file.
  *
  * Only one of @source_pattern or @source_surface is to be
  * specified. Set the other to NULL.
  **/
 static cairo_int_status_t
-_cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	    *surface,
-				       cairo_surface_t	            *source_surface,
-				       const cairo_pattern_t	    *source_pattern,
-				       cairo_operator_t              op,
-				       cairo_filter_t		     filter,
-				       cairo_bool_t                  stencil_mask,
-				       cairo_bool_t                  smask,
-				       const cairo_rectangle_int_t  *extents,
-				       cairo_pdf_resource_t	    *smask_res,
-				       cairo_pdf_resource_t	    *surface_res,
-				       int                          *width,
-				       int                          *height,
-				       double                       *x_offset,
-				       double                       *y_offset,
-				       cairo_rectangle_int_t        *source_extents)
+_cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	         *surface,
+				       cairo_surface_t	                 *source_surface,
+				       const cairo_pattern_t	         *source_pattern,
+				       cairo_operator_t                   op,
+				       cairo_filter_t		          filter,
+				       cairo_bool_t                       stencil_mask,
+				       cairo_bool_t                       smask,
+				       cairo_pdf_resource_t	         *smask_res,
+				       const cairo_rectangle_int_t       *extents,
+				       cairo_pdf_source_surface_entry_t **pdf_source,
+				       double                            *x_offset,
+				       double                            *y_offset,
+				       cairo_rectangle_int_t             *source_extents)
 {
     cairo_pdf_source_surface_t src_surface;
     cairo_pdf_source_surface_entry_t surface_key;
     cairo_pdf_source_surface_entry_t *surface_entry;
-    cairo_int_status_t status;
+    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_bool_t interpolate;
     unsigned char *unique_id = NULL;
     unsigned long unique_id_length = 0;
     cairo_image_surface_t *image;
     void *image_extra;
+    cairo_box_t box;
+    cairo_rectangle_int_t op_extents;
+    double x, y;
+    cairo_bool_t subsurface;
 
     switch (filter) {
     default:
@@ -1393,8 +1387,8 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	    *surface,
 	break;
     }
 
-    *x_offset = 0;
-    *y_offset = 0;
+    x = 0;
+    y = 0;
     if (source_pattern) {
 	if (source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
 	    status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source_pattern,
@@ -1402,12 +1396,27 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	    *surface,
 	    if (unlikely (status))
 		return status;
 	    source_surface = &image->base;
-	    cairo_surface_get_device_offset (source_surface, x_offset, y_offset);
+	    cairo_surface_get_device_offset (source_surface, &x, &y);
 	} else {
 	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source_pattern;
 	    source_surface = surface_pattern->surface;
 	}
     }
+    if (x_offset)
+	*x_offset = x;
+    if (y_offset)
+	*y_offset = y;
+
+    /* transform operation extents to pattern space */
+    op_extents = *extents;
+    if (source_pattern)
+    {
+	_cairo_box_from_rectangle (&box, extents);
+	_cairo_matrix_transform_bounding_box_fixed (&source_pattern->matrix, &box, NULL);
+	_cairo_box_round_to_rectangle (&box, &op_extents);
+    }
+    if (source_extents)
+	*source_extents = op_extents;
 
     surface_key.id  = source_surface->unique_id;
     surface_key.interpolate = interpolate;
@@ -1417,40 +1426,36 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	    *surface,
     _cairo_pdf_source_surface_init_key (&surface_key);
     surface_entry = _cairo_hash_table_lookup (surface->all_surfaces, &surface_key.base);
     if (surface_entry) {
-	*surface_res = surface_entry->surface_res;
-	*width = surface_entry->width;
-	*height = surface_entry->height;
-	*source_extents = surface_entry->extents;
-	status = CAIRO_STATUS_SUCCESS;
-    } else {
-	status = _get_source_surface_size (source_surface,
-					   width,
-					   height,
-					   source_extents);
-	if (unlikely(status))
-	    goto release_source;
+	if (pdf_source)
+	    *pdf_source = surface_entry;
 
-	if (surface_key.unique_id && surface_key.unique_id_length > 0) {
-	    unique_id = _cairo_malloc (surface_key.unique_id_length);
-	    if (unique_id == NULL) {
-		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-		goto release_source;
-	    }
+	if (source_pattern && source_pattern->extend != CAIRO_EXTEND_NONE)
+	    _cairo_unbounded_rectangle_init (&op_extents);
 
-	    unique_id_length = surface_key.unique_id_length;
-	    memcpy (unique_id, surface_key.unique_id, unique_id_length);
-	} else {
-	    unique_id = NULL;
-	    unique_id_length = 0;
-	}
+	_cairo_rectangle_intersect (&op_extents, &surface_entry->extents);
+	_cairo_rectangle_union (&surface_entry->required_extents, &op_extents);
+	status = CAIRO_STATUS_SUCCESS;
     }
 
-release_source:
-    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
-	_cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
-
-    if (status || surface_entry)
+    if (status || surface_entry) {
+	if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
+	    _cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
 	return status;
+    }
+
+    if (surface_key.unique_id && surface_key.unique_id_length > 0) {
+	unique_id = _cairo_malloc (surface_key.unique_id_length);
+	if (unique_id == NULL) {
+	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    goto fail1;
+	}
+
+	unique_id_length = surface_key.unique_id_length;
+	    memcpy (unique_id, surface_key.unique_id, unique_id_length);
+    } else {
+	unique_id = NULL;
+	unique_id_length = 0;
+    }
 
     surface_entry = malloc (sizeof (cairo_pdf_source_surface_entry_t));
     if (surface_entry == NULL) {
@@ -1458,6 +1463,8 @@ release_source:
 	goto fail1;
     }
 
+    if (pdf_source)
+	*pdf_source = surface_entry;
     surface_entry->id = surface_key.id;
     surface_entry->operator = op;
     surface_entry->interpolate = interpolate;
@@ -1465,13 +1472,29 @@ release_source:
     surface_entry->smask = smask;
     surface_entry->unique_id_length = unique_id_length;
     surface_entry->unique_id = unique_id;
-    surface_entry->width = *width;
-    surface_entry->height = *height;
-    surface_entry->extents = *source_extents;
     if (smask_res)
 	surface_entry->smask_res = *smask_res;
     else
 	surface_entry->smask_res.id = 0;
+
+    status = _get_source_surface_extents (source_surface,
+					  &surface_entry->extents,
+					  &surface_entry->bounded,
+					  &subsurface);
+    if (unlikely (status))
+	goto fail2;
+
+    if (subsurface) {
+	*x_offset = -surface_entry->extents.x;
+	*y_offset = -surface_entry->extents.y;
+    }
+
+    if (source_pattern && source_pattern->extend != CAIRO_EXTEND_NONE)
+	_cairo_unbounded_rectangle_init (&op_extents);
+
+    _cairo_rectangle_intersect (&op_extents, &surface_entry->extents);
+    surface_entry->required_extents = op_extents;
+
     _cairo_pdf_source_surface_init_key (surface_entry);
 
     src_surface.hash_entry = surface_entry;
@@ -1503,9 +1526,10 @@ release_source:
     if (unlikely(status))
 	goto fail3;
 
-    *surface_res = surface_entry->surface_res;
+    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
+	_cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
 
-    return status;
+    return CAIRO_STATUS_SUCCESS;
 
 fail3:
     if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
@@ -1517,7 +1541,11 @@ fail2:
     free (surface_entry);
 
 fail1:
-    free (unique_id);
+    if (unique_id)
+	free (unique_id);
+
+    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
+	_cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
 
     return status;
 }
@@ -2166,6 +2194,7 @@ _cairo_pdf_surface_start_page (void *abstract_surface)
     }
 
     _cairo_pdf_group_resources_clear (&surface->resources);
+    surface->in_xobject = FALSE;
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -2179,6 +2208,7 @@ _cairo_pdf_surface_has_fallback_images (void		*abstract_surface,
     cairo_box_double_t bbox;
 
     surface->has_fallback_images = has_fallbacks;
+    surface->in_xobject = has_fallbacks;
     bbox.p1.x = 0;
     bbox.p1.y = 0;
     bbox.p2.x = surface->width;
@@ -2200,18 +2230,16 @@ static cairo_int_status_t
 _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t          *surface,
 					     const cairo_pattern_t        *source,
 					     const cairo_rectangle_int_t  *extents,
-					     cairo_pdf_resource_t         *surface_res,
-					     int                          *width,
-					     int                          *height,
+					     cairo_pdf_source_surface_entry_t **pdf_source,
 					     double                       *x_offset,
-					     double                       *y_offset)
+					     double                       *y_offset,
+					     cairo_rectangle_int_t        *source_extents)
 {
     cairo_image_surface_t *image;
     cairo_surface_t *pad_image;
     void *image_extra;
     cairo_int_status_t status;
     int w, h;
-    cairo_rectangle_int_t extents2;
     cairo_box_t box;
     cairo_rectangle_int_t rect;
     cairo_surface_pattern_t pad_pattern;
@@ -2258,18 +2286,16 @@ _cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t          *surfa
     status = _cairo_pdf_surface_add_source_surface (surface,
 						    pad_image,
 						    NULL,
-						    FALSE,
+						    CAIRO_OPERATOR_OVER, /* not used for images */
 						    source->filter,
-						    FALSE,
-						    FALSE,
+						    FALSE, /* stencil mask */
+						    FALSE, /* smask */
+						    NULL, /* smask_res */
 						    extents,
-						    NULL,
-						    surface_res,
-						    width,
-						    height,
+						    pdf_source,
 						    x_offset,
 						    y_offset,
-						    &extents2);
+						    source_extents);
     if (unlikely (status))
         goto BAIL;
 
@@ -3001,6 +3027,7 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
 					   cairo_pdf_source_surface_t *pdf_source)
 {
     double old_width, old_height;
+    cairo_rectangle_int_t old_surface_extents;
     cairo_paginated_mode_t old_paginated_mode;
     cairo_surface_clipper_t old_clipper;
     cairo_bool_t old_in_xobject;
@@ -3017,9 +3044,9 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
     cairo_recording_surface_t *recording;
 
     assert (pdf_source->type == CAIRO_PATTERN_TYPE_SURFACE);
-    extents = &pdf_source->hash_entry->extents;
-    width = pdf_source->hash_entry->width;
-    height = pdf_source->hash_entry->height;
+    extents = &pdf_source->hash_entry->required_extents;
+    width = pdf_source->hash_entry->extents.width;
+    height = pdf_source->hash_entry->extents.height;
     is_subsurface = FALSE;
     source = pdf_source->surface;
     if (_cairo_surface_is_snapshot (source))
@@ -3041,15 +3068,17 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
     old_width = surface->width;
     old_height = surface->height;
     old_in_xobject = surface->in_xobject;
-
+    old_surface_extents = surface->surface_extents;
     old_paginated_mode = surface->paginated_mode;
     old_clipper = surface->clipper;
+    surface->surface_extents = *extents;
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_pdf_surface_clipper_intersect_clip_path);
 
     _cairo_pdf_surface_set_size_internal (surface, width, height);
     _cairo_pdf_operators_reset (&surface->pdf_operators);
     surface->in_xobject = TRUE;
+    surface->surface_extents = *extents;
 
     /* Patterns are emitted after fallback images. The paginated mode
      * needs to be set to _RENDER while the recording surface is replayed
@@ -3058,10 +3087,10 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
     surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
     _cairo_pdf_group_resources_clear (&surface->resources);
     if (is_subsurface) {
-	bbox.p1.x = 0;
-	bbox.p1.y = 0;
-	bbox.p2.x = extents->width;
-	bbox.p2.y = extents->height;
+	bbox.p1.x = extents->x;
+	bbox.p1.y = extents->y;
+	bbox.p2.x = extents->x + extents->width;
+	bbox.p2.y = extents->y + extents->height;
     } else {
 	_get_bbox_from_extents (height, extents, &bbox);
     }
@@ -3108,6 +3137,7 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
     _cairo_pdf_operators_reset (&surface->pdf_operators);
     surface->in_xobject = old_in_xobject;
     surface->paginated_mode = old_paginated_mode;
+    surface->surface_extents = old_surface_extents;
 
 err:
     cairo_surface_destroy (free_me);
@@ -3131,7 +3161,6 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 {
     cairo_pattern_t *pattern = pdf_pattern->pattern;
     cairo_int_status_t status;
-    cairo_pdf_resource_t pattern_resource = {0};
     cairo_matrix_t cairo_p2d, pdf_p2d;
     cairo_extend_t extend = cairo_pattern_get_extend (pattern);
     double xstep, ystep;
@@ -3141,42 +3170,46 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
     double x_offset;
     double y_offset;
     char draw_surface[200];
-    cairo_box_double_t     bbox;
+    cairo_box_double_t bbox;
     cairo_matrix_t mat;
+    cairo_pdf_source_surface_entry_t *pdf_source;
+    cairo_rectangle_int_t op_extents;
 
     if (pattern->extend == CAIRO_EXTEND_PAD) {
 	status = _cairo_pdf_surface_add_padded_image_surface (surface,
 							      pattern,
 							      &pdf_pattern->extents,
-							      &pattern_resource,
-							      &pattern_width,
-							      &pattern_height,
+							      &pdf_source,
 							      &x_offset,
-							      &y_offset);
-	pattern_extents.x = 0;
-	pattern_extents.y = 0;
-	pattern_extents.width = pattern_width;
-	pattern_extents.height = pattern_height;
+							      &y_offset,
+							      &op_extents);
     } else {
 	status = _cairo_pdf_surface_add_source_surface (surface,
 							NULL,
 							pattern,
 							pdf_pattern->operator,
 							pattern->filter,
-							FALSE,
-							FALSE,
+							FALSE, /* stencil mask */
+							FALSE, /* smask */
+							NULL, /* smask_res */
 							&pdf_pattern->extents,
-							NULL,
-							&pattern_resource,
-							&pattern_width,
-							&pattern_height,
+							&pdf_source,
 							&x_offset,
 							&y_offset,
-							&pattern_extents);
+							&op_extents);
     }
     if (unlikely (status))
 	return status;
 
+    pattern_extents = pdf_source->extents;
+    pattern_width = pdf_source->extents.width;
+    pattern_height = pdf_source->extents.height;
+    if (!pdf_source->bounded)
+    {
+	extend = CAIRO_EXTEND_NONE;
+	_cairo_rectangle_intersect (&pattern_extents, &op_extents);
+    }
+
     switch (extend) {
     case CAIRO_EXTEND_PAD:
     case CAIRO_EXTEND_NONE:
@@ -3194,7 +3227,8 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 	 * repeat visibly.
 	 */
 	double x1 = 0.0, y1 = 0.0;
-	double x2 = surface->width, y2 = surface->height;
+	double x2 = surface->surface_extents.width;
+	double y2 = surface->surface_extents.height;
 	_cairo_matrix_transform_bounding_box (&pattern->matrix,
 					      &x1, &y1, &x2, &y2,
 					      NULL);
@@ -3207,20 +3241,21 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 			      pattern_width + pattern_height);
     }
     break;
+
     case CAIRO_EXTEND_REPEAT:
 	xstep = pattern_width;
 	ystep = pattern_height;
 	break;
+
     case CAIRO_EXTEND_REFLECT:
-	pattern_extents.x = 0;
-	pattern_extents.y = 0;
-	pattern_extents.width = pattern_width*2;
-	pattern_extents.height = pattern_height*2;
-	xstep = pattern_width*2;
-	ystep = pattern_height*2;
+	pattern_extents.width *= 2;
+	pattern_extents.height *= 2;
+	xstep = pattern_extents.width;
+	ystep = pattern_extents.height;
 	break;
-	/* All the rest (if any) should have been analyzed away, so this
-	 * case should be unreachable. */
+
+    /* All the rest (if any) should have been analyzed away, so this
+     * case should be unreachable. */
     default:
 	ASSERT_NOT_REACHED;
 	xstep = 0;
@@ -3265,7 +3300,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 	cairo_matrix_init (&mat, 1, 0, 0, -1, 0, surface->height);
 
     cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &mat);
-    cairo_matrix_translate (&pdf_p2d, -x_offset, -y_offset);
+    cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
     if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
     {
 	cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
@@ -3290,8 +3325,8 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 					     pdf_p2d.xx, pdf_p2d.yx,
 					     pdf_p2d.xy, pdf_p2d.yy,
 					     pdf_p2d.x0, pdf_p2d.y0,
-					     pattern_resource.id,
-					     pattern_resource.id);
+					     pdf_source->surface_res.id,
+					     pdf_source->surface_res.id);
     if (unlikely (status))
 	return status;
 
@@ -3300,14 +3335,14 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
 	snprintf(draw_surface,
 		 sizeof (draw_surface),
 		 "/x%d Do\n",
-		 pattern_resource.id);
+		 pdf_source->surface_res.id);
     } else {
 	snprintf(draw_surface,
 		 sizeof (draw_surface),
 		 "q %d 0 0 %d 0 0 cm /x%d Do Q",
 		 pattern_width,
 		 pattern_height,
-		 pattern_resource.id);
+		 pdf_source->surface_res.id);
     }
 
     if (extend == CAIRO_EXTEND_REFLECT) {
@@ -4245,16 +4280,8 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t    *surface,
 static cairo_int_status_t
 _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern_t *pdf_pattern)
 {
-    double old_width, old_height;
     cairo_int_status_t status;
 
-    old_width = surface->width;
-    old_height = surface->height;
-    _cairo_pdf_surface_set_size_internal (surface,
-					  pdf_pattern->width,
-					  pdf_pattern->height);
-    _cairo_pdf_operators_reset (&surface->pdf_operators);
-
     switch (pdf_pattern->pattern->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
 	ASSERT_NOT_REACHED;
@@ -4281,11 +4308,6 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
 	break;
     }
 
-    _cairo_pdf_surface_set_size_internal (surface,
-					  old_width,
-					  old_height);
-    _cairo_pdf_operators_reset (&surface->pdf_operators);
-
     return status;
 }
 
@@ -4297,14 +4319,12 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
 					  cairo_pdf_resource_t	       *smask_res,
 					  cairo_bool_t                  stencil_mask)
 {
-    cairo_pdf_resource_t surface_res;
-    int width, height;
     cairo_matrix_t cairo_p2d, pdf_p2d;
     cairo_int_status_t status;
     int alpha;
-    cairo_rectangle_int_t extents2;
     double x_offset;
     double y_offset;
+    cairo_pdf_source_surface_entry_t *pdf_source;
 
     if (source->extend == CAIRO_EXTEND_PAD &&
 	!(source->type == CAIRO_PATTERN_TYPE_SURFACE &&
@@ -4313,11 +4333,10 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
 	status = _cairo_pdf_surface_add_padded_image_surface (surface,
 							      source,
 							      extents,
-							      &surface_res,
-							      &width,
-							      &height,
+							      &pdf_source,
 							      &x_offset,
-							      &y_offset);
+							      &y_offset,
+							      NULL);
     } else {
 	status = _cairo_pdf_surface_add_source_surface (surface,
 							NULL,
@@ -4325,15 +4344,13 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
 							op,
 							source->filter,
 							stencil_mask,
-							FALSE,
-							extents,
+							FALSE, /* smask */
 							smask_res,
-							&surface_res,
-							&width,
-							&height,
+							extents,
+							&pdf_source,
 							&x_offset,
 							&y_offset,
-							&extents2);
+							NULL);
     }
     if (unlikely (status))
 	return status;
@@ -4349,9 +4366,9 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
     if (!(source->type == CAIRO_PATTERN_TYPE_SURFACE &&
 	  ((cairo_surface_pattern_t *)source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING))
     {
-	cairo_matrix_translate (&pdf_p2d, 0.0, height);
+	cairo_matrix_translate (&pdf_p2d, 0.0, pdf_source->extents.height);
 	cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
-	cairo_matrix_scale (&pdf_p2d, width, height);
+	cairo_matrix_scale (&pdf_p2d, pdf_source->extents.width, pdf_source->extents.height);
     }
 
     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
@@ -4370,15 +4387,15 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
     if (stencil_mask) {
 	_cairo_output_stream_printf (surface->output,
 				     "/x%d Do\n",
-				     surface_res.id);
+				     pdf_source->surface_res.id);
     } else {
 	_cairo_output_stream_printf (surface->output,
 				     "/a%d gs /x%d Do\n",
 				     alpha,
-				     surface_res.id);
+				     pdf_source->surface_res.id);
     }
 
-    return _cairo_pdf_surface_add_xobject (surface, surface_res);
+    return _cairo_pdf_surface_add_xobject (surface, pdf_source->surface_res);
 }
 
 static cairo_int_status_t
@@ -4664,15 +4681,7 @@ _cairo_pdf_surface_get_extents (void		        *abstract_surface,
 {
     cairo_pdf_surface_t *surface = abstract_surface;
 
-    rectangle->x = 0;
-    rectangle->y = 0;
-
-    /* XXX: The conversion to integers here is pretty bogus, (not to
-     * mention the arbitrary limitation of width to a short(!). We
-     * may need to come up with a better interface for get_size.
-     */
-    rectangle->width  = ceil (surface->width);
-    rectangle->height = ceil (surface->height);
+    *rectangle = surface->surface_extents;
 
     return TRUE;
 }
@@ -6744,7 +6753,6 @@ _cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t         *surface,
     cairo_image_surface_t  *image;
     void		   *image_extra;
     cairo_image_transparency_t transparency;
-    cairo_pdf_resource_t smask_res;
     int src_width, src_height;
     int mask_width, mask_height;
     double src_x_offset, src_y_offset;
@@ -6753,8 +6761,8 @@ _cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t         *surface,
     double mask_x1, mask_y1, mask_x2, mask_y2;
     cairo_matrix_t p2u;
     double src_radius, mask_radius, e;
-    cairo_rectangle_int_t extents2;
     cairo_bool_t need_smask;
+    cairo_pdf_source_surface_entry_t *pdf_source;
 
     /* Check that source and mask are images */
 
@@ -6873,16 +6881,14 @@ _cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t         *surface,
 							mask,
 							op,
 							source->filter,
-							FALSE,
-							TRUE,
+							FALSE, /* stencil mask */
+							TRUE, /* smask */
+							NULL, /* smask_res */
 							extents,
+							&pdf_source,
+							NULL,
 							NULL,
-							&smask_res,
-							&mask_width,
-							&mask_height,
-							&mask_x_offset,
-							&mask_y_offset,
-							&extents2);
+							NULL);
 	if (unlikely (status))
 	    return status;
     }
@@ -6893,7 +6899,7 @@ _cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t         *surface,
 
     _cairo_output_stream_printf (surface->output, "q\n");
     status = _cairo_pdf_surface_paint_surface_pattern (surface, op, source, extents,
-						       need_smask ? &smask_res : NULL,
+						       need_smask ? &pdf_source->smask_res : NULL,
 						       FALSE);
     if (unlikely (status))
 	return status;
@@ -7010,7 +7016,7 @@ _cairo_pdf_surface_paint (void			*abstract_surface,
 	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
 	goto cleanup;
     } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
-	status = _cairo_pdf_surface_start_fallback (surface);
+	status = _cairo_pdf_surface_start_fallback  (surface);
 	if (unlikely (status))
 	    goto cleanup;
     }
@@ -7091,8 +7097,11 @@ _cairo_pdf_surface_paint (void			*abstract_surface,
 	    goto cleanup;
 
 	_cairo_output_stream_printf (surface->output,
-				     "0 0 %f %f re f\n",
-				     surface->width, surface->height);
+				     "%d %d %d %d re f\n",
+				     surface->surface_extents.x,
+				     surface->surface_extents.y,
+				     surface->surface_extents.width,
+				     surface->surface_extents.height);
 
 	status = _cairo_pdf_surface_unselect_pattern (surface);
 	if (unlikely (status))
@@ -7887,6 +7896,12 @@ _cairo_pdf_surface_set_paginated_mode (void			*abstract_surface,
     cairo_pdf_surface_t *surface = abstract_surface;
 
     surface->paginated_mode = paginated_mode;
+    if (paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
+	surface->surface_extents.x = 0;
+	surface->surface_extents.y = 0;
+	surface->surface_extents.width  = ceil (surface->width);
+	surface->surface_extents.height = ceil (surface->height);
+    }
 }
 
 static const cairo_surface_backend_t cairo_pdf_surface_backend = {
diff --git a/src/cairoint.h b/src/cairoint.h
index f781748..88b1bf7 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1781,6 +1781,9 @@ _cairo_matrix_to_pixman_matrix_offset (const cairo_matrix_t	*matrix,
 				       int                      *out_x_offset,
 				       int                      *out_y_offset);
 
+cairo_private void
+_cairo_debug_print_matrix (FILE *file, const cairo_matrix_t *matrix);
+
 cairo_private cairo_status_t
 _cairo_bentley_ottmann_tessellate_rectilinear_polygon (cairo_traps_t	 *traps,
 						       const cairo_polygon_t *polygon,
@@ -2062,7 +2065,7 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface);
 #endif
 
 cairo_private void
-_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path);
+_cairo_debug_print_path (FILE *stream, const cairo_path_fixed_t *path);
 
 cairo_private void
 _cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon);
diff --git a/test/reference/record-neg-extents-bounded.pdf.argb32.ref.png b/test/reference/record-neg-extents-bounded.pdf.argb32.ref.png
new file mode 100644
index 0000000..1592836
Binary files /dev/null and b/test/reference/record-neg-extents-bounded.pdf.argb32.ref.png differ
diff --git a/test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png b/test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png
new file mode 100644
index 0000000..1592836
Binary files /dev/null and b/test/reference/record-neg-extents-bounded.pdf.rgb24.ref.png differ
diff --git a/test/reference/record-neg-extents-unbounded.pdf.argb32.ref.png b/test/reference/record-neg-extents-unbounded.pdf.argb32.ref.png
new file mode 100644
index 0000000..1592836
Binary files /dev/null and b/test/reference/record-neg-extents-unbounded.pdf.argb32.ref.png differ
diff --git a/test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png b/test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png
new file mode 100644
index 0000000..1592836
Binary files /dev/null and b/test/reference/record-neg-extents-unbounded.pdf.rgb24.ref.png differ
commit 1e07ced66d26475e6631df9ffa2a15709104bd8f
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    pdf: change from pdf coordinates to cairo coordinates
    
    When an unbounded recording surface is used multiple times with
    different extents for each operation we need the XObject containing
    the recording surface to have the same origin for each operation. This
    is not possible when the recording surface is converted to PDF
    coordinates because each operation has different extents resulting in
    a different origin when the Y-axis is flipped (since the flip matrix
    depends on the recording surface height which for unbounded surfaces
    depends on the extents of the operation that paints the recording
    surface).
    
    Switching to cairo coordinates by emitting a Y-axis flip matrix as the
    first object of each page allows the recording surface to be emitted
    in cairo coordinates. This results in the same origin for all
    operations using the recording surface XObject.

diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index dcee25f..dec8ca0 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -1492,9 +1492,6 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t	  *pdf_operators,
     cairo_matrix_init_scale (&invert_y_axis, 1, -1);
     text_matrix = scaled_font->scale;
 
-    /* Invert y axis in font space  */
-    cairo_matrix_multiply (&text_matrix, &text_matrix, &invert_y_axis);
-
     /* Invert y axis in device space  */
     cairo_matrix_multiply (&text_matrix, &invert_y_axis, &text_matrix);
 
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h
index 618ca4e..66ebf60 100644
--- a/src/cairo-pdf-surface-private.h
+++ b/src/cairo-pdf-surface-private.h
@@ -97,6 +97,17 @@ typedef struct _cairo_pdf_pattern {
     cairo_pdf_resource_t gstate_res;
     cairo_operator_t operator;
     cairo_bool_t is_shading;
+
+    /* PDF pattern space is the pattern matrix concatenated with the
+     * initial space of the parent object. If the parent object is the
+     * page, the intial space does not include the Y-axis flipping
+     * matrix emitted at the start of the page content stream.  If the
+     * parent object is not the page content stream, the initial space
+     * will have a flipped Y-axis. The inverted_y_axis flag is true
+     * when the initial space of the parent object that is drawing
+     * this pattern has a flipped Y-axis.
+     */
+    cairo_bool_t inverted_y_axis;
 } cairo_pdf_pattern_t;
 
 typedef enum _cairo_pdf_operation {
@@ -150,6 +161,7 @@ struct _cairo_pdf_surface {
     double width;
     double height;
     cairo_matrix_t cairo_to_pdf;
+    cairo_bool_t in_xobject;
 
     cairo_array_t objects;
     cairo_array_t pages;
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index a6274bd..db75bc6 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -300,9 +300,6 @@ _cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface,
 {
     surface->width = width;
     surface->height = height;
-    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height);
-    _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
-						  &surface->cairo_to_pdf);
 }
 
 static cairo_bool_t
@@ -373,7 +370,8 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t	*output,
     surface->output = output;
     surface->width = width;
     surface->height = height;
-    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height);
+    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, 1, 0, 0);
+    surface->in_xobject = FALSE;
 
     _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t));
     _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t));
@@ -1259,6 +1257,8 @@ _get_source_surface_size (cairo_surface_t         *source,
 	    cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
 
 	    *extents = sub->extents;
+	    extents->x = 0;
+	    extents->y = 0;
 	    *width  = extents->width;
 	    *height = extents->height;
 	} else {
@@ -1586,6 +1586,10 @@ _cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t	   *surface,
 
     *pattern_res = pdf_pattern.pattern_res;
     *gstate_res = pdf_pattern.gstate_res;
+    /* If the pattern requires a gstate it will be drawn from within
+     * an XObject. The initial space of each XObject has an inverted
+     * Y-axis. */
+    pdf_pattern.inverted_y_axis = pdf_pattern.gstate_res.id ? TRUE : surface->in_xobject;
 
     status = _cairo_array_append (&surface->page_patterns, &pdf_pattern);
     if (unlikely (status)) {
@@ -1603,9 +1607,9 @@ _get_bbox_from_extents (double                       surface_height,
 		       cairo_box_double_t          *bbox)
 {
     bbox->p1.x = extents->x;
-    bbox->p1.y = surface_height - (extents->y + extents->height);
+    bbox->p1.y = extents->y;
     bbox->p2.x = extents->x + extents->width;
-    bbox->p2.y = surface_height - extents->y;
+    bbox->p2.y = extents->y + extents->height;
 }
 
 static cairo_int_status_t
@@ -1707,6 +1711,7 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t	*surface,
         surface->output = output;
 	_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
     }
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return _cairo_output_stream_get_status (surface->output);
 }
@@ -1967,6 +1972,9 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t       *surface,
 					    resource,
 					    surface->compress_content,
 					    NULL);
+	_cairo_output_stream_printf (surface->output,
+				     "1 0 0 -1 0 %f cm\n",
+				     surface->height);
     }
     if (unlikely (status))
 	return status;
@@ -1974,6 +1982,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t       *surface,
     surface->content = surface->pdf_stream.self;
 
     _cairo_output_stream_printf (surface->output, "q\n");
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return _cairo_output_stream_get_status (surface->output);
 }
@@ -2994,6 +3003,7 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
     double old_width, old_height;
     cairo_paginated_mode_t old_paginated_mode;
     cairo_surface_clipper_t old_clipper;
+    cairo_bool_t old_in_xobject;
     cairo_box_double_t bbox;
     cairo_int_status_t status;
     int alpha = 0;
@@ -3030,12 +3040,16 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
 
     old_width = surface->width;
     old_height = surface->height;
+    old_in_xobject = surface->in_xobject;
+
     old_paginated_mode = surface->paginated_mode;
     old_clipper = surface->clipper;
     _cairo_surface_clipper_init (&surface->clipper,
 				 _cairo_pdf_surface_clipper_intersect_clip_path);
 
     _cairo_pdf_surface_set_size_internal (surface, width, height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
+    surface->in_xobject = TRUE;
 
     /* Patterns are emitted after fallback images. The paginated mode
      * needs to be set to _RENDER while the recording surface is replayed
@@ -3091,6 +3105,8 @@ _cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
     _cairo_pdf_surface_set_size_internal (surface,
 					  old_width,
 					  old_height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
+    surface->in_xobject = old_in_xobject;
     surface->paginated_mode = old_paginated_mode;
 
 err:
@@ -3126,6 +3142,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
     double y_offset;
     char draw_surface[200];
     cairo_box_double_t     bbox;
+    cairo_matrix_t mat;
 
     if (pattern->extend == CAIRO_EXTEND_PAD) {
 	status = _cairo_pdf_surface_add_padded_image_surface (surface,
@@ -3242,10 +3259,18 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_INT_STATUS_SUCCESS);
 
-    cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &surface->cairo_to_pdf);
+    if (pdf_pattern->inverted_y_axis)
+	cairo_matrix_init (&mat, 1, 0, 0, 1, 0, 0);
+    else
+	cairo_matrix_init (&mat, 1, 0, 0, -1, 0, surface->height);
+
+    cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &mat);
     cairo_matrix_translate (&pdf_p2d, -x_offset, -y_offset);
-    cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
-    cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
+    if (((cairo_surface_pattern_t *)pattern)->surface->type != CAIRO_SURFACE_TYPE_RECORDING)
+    {
+	cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
+	cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
+    }
 
     _get_bbox_from_extents (pattern_height, &pattern_extents, &bbox);
     _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
@@ -3923,6 +3948,7 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t    *surface,
     cairo_circle_double_t start, end;
     double domain[2];
     cairo_int_status_t status;
+    cairo_matrix_t mat;
 
     assert (pattern->n_stops != 0);
 
@@ -3937,7 +3963,13 @@ _cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t    *surface,
     status = cairo_matrix_invert (&pat_to_pdf);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_INT_STATUS_SUCCESS);
-    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
+
+    if (pdf_pattern->inverted_y_axis)
+       cairo_matrix_init (&mat, 1, 0, 0, 1, 0, 0);
+    else
+       cairo_matrix_init (&mat, 1, 0, 0, -1, 0, surface->height);
+
+    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &mat);
 
     if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
 	pattern->base.extend == CAIRO_EXTEND_REFLECT)
@@ -4069,13 +4101,19 @@ _cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t    *surface,
     cairo_pdf_shading_t shading;
     int i;
     cairo_pdf_resource_t res;
+    cairo_matrix_t mat;
 
     pat_to_pdf = pattern->matrix;
     status = cairo_matrix_invert (&pat_to_pdf);
     /* cairo_pattern_set_matrix ensures the matrix is invertible */
     assert (status == CAIRO_INT_STATUS_SUCCESS);
 
-    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
+    if (pdf_pattern->inverted_y_axis)
+	cairo_matrix_init (&mat, 1, 0, 0, 1, 0, 0);
+    else
+	cairo_matrix_init (&mat, 1, 0, 0, -1, 0, surface->height);
+
+    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &mat);
 
     status = _cairo_pdf_shading_init_color (&shading, (cairo_mesh_pattern_t *) pattern);
     if (unlikely (status))
@@ -4215,6 +4253,7 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
     _cairo_pdf_surface_set_size_internal (surface,
 					  pdf_pattern->width,
 					  pdf_pattern->height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     switch (pdf_pattern->pattern->type) {
     case CAIRO_PATTERN_TYPE_SOLID:
@@ -4245,6 +4284,7 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
     _cairo_pdf_surface_set_size_internal (surface,
 					  old_width,
 					  old_height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return status;
 }
@@ -4306,11 +4346,11 @@ _cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
     pdf_p2d = surface->cairo_to_pdf;
     cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
     cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
-    cairo_matrix_translate (&pdf_p2d, 0.0, height);
-    cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
     if (!(source->type == CAIRO_PATTERN_TYPE_SURFACE &&
 	  ((cairo_surface_pattern_t *)source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING))
     {
+	cairo_matrix_translate (&pdf_p2d, 0.0, height);
+	cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
 	cairo_matrix_scale (&pdf_p2d, width, height);
     }
 
@@ -5859,16 +5899,16 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
 				 "<< /Type /Font\n"
 				 "   /Subtype /Type3\n"
 				 "   /FontBBox [%f %f %f %f]\n"
-				 "   /FontMatrix [ 1 0 0 1 0 0 ]\n"
+				 "   /FontMatrix [ 1 0 0 -1 0 0 ]\n"
 				 "   /Encoding %d 0 R\n"
 				 "   /CharProcs %d 0 R\n"
 				 "   /FirstChar 0\n"
 				 "   /LastChar %d\n",
 				 subset_resource.id,
 				 _cairo_fixed_to_double (font_bbox.p1.x),
-				 - _cairo_fixed_to_double (font_bbox.p2.y),
+				 _cairo_fixed_to_double (font_bbox.p1.y),
 				 _cairo_fixed_to_double (font_bbox.p2.x),
-				 - _cairo_fixed_to_double (font_bbox.p1.y),
+				 _cairo_fixed_to_double (font_bbox.p2.y),
 				 encoding.id,
 				 char_procs.id,
 				 font_subset->num_glyphs - 1);
@@ -6228,14 +6268,18 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t     *surface,
 				      cairo_pdf_smask_group_t *group)
 {
     double old_width, old_height;
+    cairo_bool_t old_in_xobject;
     cairo_int_status_t status;
     cairo_box_double_t bbox;
 
     old_width = surface->width;
     old_height = surface->height;
+    old_in_xobject = surface->in_xobject;
+    surface->in_xobject = TRUE;
     _cairo_pdf_surface_set_size_internal (surface,
 					  group->width,
 					  group->height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
     /* _mask is a special case that requires two groups - source
      * and mask as well as a smask and gstate dictionary */
     if (group->operation == PDF_MASK) {
@@ -6295,9 +6339,11 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t     *surface,
     status = _cairo_pdf_surface_close_group (surface, NULL);
 
 RESTORE_SIZE:
+    surface->in_xobject = old_in_xobject;
     _cairo_pdf_surface_set_size_internal (surface,
 					  old_width,
 					  old_height);
+    _cairo_pdf_operators_reset (&surface->pdf_operators);
 
     return status;
 }
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index 8c154b3..86c24ed 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -78,7 +78,6 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t			 *scaled_font,
 				   cairo_bool_t ps)
 {
     cairo_type3_glyph_surface_t *surface;
-    cairo_matrix_t invert_y_axis;
 
     if (unlikely (stream != NULL && stream->status))
 	return _cairo_surface_create_in_error (stream->status);
@@ -102,8 +101,6 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t			 *scaled_font,
      * entry in the Type 3 dictionary. In the PDF backend this is an
      * identity matrix. */
     surface->cairo_to_pdf = scaled_font->scale_inverse;
-    cairo_matrix_init_scale (&invert_y_axis, 1, -1);
-    cairo_matrix_multiply (&surface->cairo_to_pdf, &surface->cairo_to_pdf, &invert_y_axis);
 
     _cairo_pdf_operators_init (&surface->pdf_operators,
 			       surface->stream,
@@ -295,15 +292,13 @@ _cairo_type3_glyph_surface_show_glyphs (void		     *abstract_surface,
     cairo_type3_glyph_surface_t *surface = abstract_surface;
     cairo_int_status_t status;
     cairo_scaled_font_t *font;
-    cairo_matrix_t new_ctm, invert_y_axis;
+    cairo_matrix_t new_ctm;
 
     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
     if (unlikely (status))
 	return status;
 
-    cairo_matrix_init_scale (&invert_y_axis, 1, -1);
-    cairo_matrix_multiply (&new_ctm, &invert_y_axis, &scaled_font->ctm);
-    cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &new_ctm);
+    cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &scaled_font->ctm);
     font = cairo_scaled_font_create (scaled_font->font_face,
 				     &scaled_font->font_matrix,
 				     &new_ctm,
@@ -388,14 +383,10 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur
 
     x = _cairo_fixed_to_double (scaled_glyph->bbox.p1.x);
     y = _cairo_fixed_to_double (scaled_glyph->bbox.p2.y);
-    mat.xx = image->width;
-    mat.xy = 0;
-    mat.yx = 0;
-    mat.yy = image->height;
-    mat.x0 = x;
-    mat.y0 = y;
+    cairo_matrix_init(&mat, image->width, 0,
+		      0, -image->height,
+		      x, y);
     cairo_matrix_multiply (&mat, &mat, &surface->scaled_font->scale_inverse);
-    mat.y0 *= -1;
 
     return _cairo_type3_glyph_surface_emit_image (surface, image, &mat);
 }
@@ -524,9 +515,9 @@ _cairo_type3_glyph_surface_emit_glyph (void		     *abstract_surface,
 				 "%f 0 %f %f %f %f d1\n",
                                  x_advance,
 				 _cairo_fixed_to_double (bbox->p1.x),
-				 - _cairo_fixed_to_double (bbox->p2.y),
+				 _cairo_fixed_to_double (bbox->p1.y),
 				 _cairo_fixed_to_double (bbox->p2.x),
-				 - _cairo_fixed_to_double (bbox->p1.y));
+				 _cairo_fixed_to_double (bbox->p2.y));
 
     if (status == CAIRO_INT_STATUS_SUCCESS) {
 	cairo_output_stream_t *mem_stream;
commit d2dc2e90a71ae4822845ac4bab3871475335a69e
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    Fix test failures when recording surface extents has negative x,y
    
    Fixes record-neg-bounded-extents (image only) and
    recording-ink-extents.

diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index 64e2d1e..f69755f 100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -81,9 +81,6 @@ _cairo_surface_wrapper_get_transform (cairo_surface_wrapper_t *wrapper,
 {
     cairo_matrix_init_identity (m);
 
-    if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y))
-	cairo_matrix_translate (m, -wrapper->extents.x, -wrapper->extents.y);
-
     if (! _cairo_matrix_is_identity (&wrapper->transform))
 	cairo_matrix_multiply (m, &wrapper->transform, m);
 
@@ -109,9 +106,6 @@ _cairo_surface_wrapper_get_inverse_transform (cairo_surface_wrapper_t *wrapper,
 	assert (status == CAIRO_STATUS_SUCCESS);
 	cairo_matrix_multiply (m, &inv, m);
     }
-
-    if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y))
-	cairo_matrix_translate (m, wrapper->extents.x, wrapper->extents.y);
 }
 
 static cairo_clip_t *
diff --git a/test/reference/record-neg-extents-bounded.ref.png b/test/reference/record-neg-extents-bounded.ref.png
new file mode 100644
index 0000000..6d29da1
Binary files /dev/null and b/test/reference/record-neg-extents-bounded.ref.png differ
commit 58df191946b7d275c5706dc40e1cf3dffa7cceae
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    Add recording-ink-extents test
    
    bounded_fill fails returning extents origin of (0, 0) instead of (-150, -100)

diff --git a/test/Makefile.sources b/test/Makefile.sources
index 5d3756a..2d3781a 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -274,6 +274,7 @@ test_sources = \
 	record-extend.c					\
 	record-neg-extents.c                            \
 	record-mesh.c					\
+	recording-ink-extents.c                         \
 	recording-surface-pattern.c			\
 	recording-surface-extend.c			\
 	rectangle-rounding-error.c			\
diff --git a/test/recording-ink-extents.c b/test/recording-ink-extents.c
new file mode 100644
index 0000000..dcc905d
--- /dev/null
+++ b/test/recording-ink-extents.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2016 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#include "cairo-test.h"
+
+/* Check cairo_recording_surface_ink_extents() returns correct extents. */
+
+
+static cairo_test_status_t
+check_extents (cairo_test_context_t *cr,
+	       cairo_surface_t *recording_surface,
+	       const char * func_name,
+	       double expected_x, double expected_y, double expected_w, double expected_h)
+{
+    double x, y, w, h;
+    cairo_recording_surface_ink_extents (recording_surface, &x, &y, &w, &h);
+    if (x != expected_x ||
+	y != expected_y ||
+	w != expected_w ||
+	h != expected_h)
+    {
+	cairo_test_log (cr,
+			"%s: x: %f, y: %f, w: %f, h: %f\n"
+			"    expected: x: %f, y: %f, w: %f, h: %f\n",
+			func_name,
+			x, y, w, h,
+			expected_x, expected_y,
+			expected_w, expected_h);
+       return CAIRO_TEST_ERROR;
+    }
+    return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+unbounded_fill (cairo_test_context_t *test_cr)
+{
+    cairo_test_status_t status;
+    cairo_surface_t *surface;
+    cairo_t *cr;
+
+    surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
+    cr = cairo_create (surface);
+
+    cairo_rectangle (cr, -300, -150, 900, 600);
+    cairo_fill (cr);
+
+    cairo_destroy(cr);
+
+    status = check_extents (test_cr, surface,  __func__,
+			    -300, -150, 900, 600);
+    cairo_surface_destroy (surface);
+    return status;
+}
+
+static cairo_test_status_t
+bounded_fill (cairo_test_context_t *test_cr)
+{
+    cairo_test_status_t status;
+    cairo_surface_t *surface;
+    cairo_t *cr;
+    cairo_rectangle_t extents = { -150, -100, 300, 200 };
+
+    surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, &extents);
+    cr = cairo_create (surface);
+
+    cairo_rectangle (cr, -300, -300, 650, 600);
+    cairo_fill (cr);
+
+    cairo_destroy(cr);
+
+    status = check_extents (test_cr, surface,  __func__,
+			    -150, -100, 300, 200);
+    cairo_surface_destroy (surface);
+    return status;
+}
+
+static cairo_test_status_t
+unbounded_paint (cairo_test_context_t *test_cr)
+{
+    cairo_test_status_t status;
+    cairo_surface_t *surface;
+    cairo_t *cr;
+
+    surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
+    cr = cairo_create (surface);
+
+    cairo_paint (cr);
+
+    cairo_destroy(cr);
+
+    status = check_extents (test_cr, surface,  __func__,
+			    -(1 << 23), -(1 << 23), -1, -1);
+    cairo_surface_destroy (surface);
+    return status;
+}
+
+static cairo_test_status_t
+bounded_paint (cairo_test_context_t *test_cr)
+{
+    cairo_test_status_t status;
+    cairo_surface_t *surface;
+    cairo_t *cr;
+    cairo_rectangle_t extents = { -150, -100, 300, 200 };
+
+    surface = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, &extents);
+    cr = cairo_create (surface);
+
+    cairo_paint (cr);
+
+    cairo_destroy(cr);
+
+    status = check_extents (test_cr, surface,  __func__,
+			    -150, -100, 300, 200);
+    cairo_surface_destroy (surface);
+    return status;
+}
+
+static cairo_test_status_t
+preamble (cairo_test_context_t *cr)
+{
+    cairo_test_status_t status;
+
+    status = unbounded_fill (cr);
+    if (status != CAIRO_TEST_SUCCESS)
+	return status;
+
+    status = bounded_fill (cr);
+    if (status != CAIRO_TEST_SUCCESS)
+	return status;
+
+    status = unbounded_paint (cr);
+    if (status != CAIRO_TEST_SUCCESS)
+	return status;
+
+    status = bounded_paint (cr);
+    if (status != CAIRO_TEST_SUCCESS)
+	return status;
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+
+CAIRO_TEST (recording_ink_extents,
+	    "Test cairo_recording_surface_ink_extents()",
+	    "api,recording,extents", /* keywords */
+	    NULL, /* requirements */
+	    0, 0,
+	    preamble, NULL)
commit 9fff6f0be3ed1a7af474ddfd8e384eb0376093c2
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 4 14:43:43 2016 +0930

    test: add record-neg-extents
    
    Test case for bug 89232 - painting a recording surface to a
    pdf/ps surface omits objects on the recording surface with negative
    coordinates even though the pattern matrix has transformed the objects
    to within the page extents.
    
    The image surface also fails when the recording surface is bounded.

diff --git a/test/Makefile.sources b/test/Makefile.sources
index 24ded46..5d3756a 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -272,6 +272,7 @@ test_sources = \
 	record90.c					\
 	recordflip.c					\
 	record-extend.c					\
+	record-neg-extents.c                            \
 	record-mesh.c					\
 	recording-surface-pattern.c			\
 	recording-surface-extend.c			\
diff --git a/test/record-neg-extents.c b/test/record-neg-extents.c
new file mode 100644
index 0000000..29a2aa1
--- /dev/null
+++ b/test/record-neg-extents.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2016 Adrian Johnson
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *	Adrian Johnson <ajohnson at redneon.com>
+ */
+
+#include "cairo-test.h"
+#include <stdio.h>
+#include <math.h>
+
+#define PAT_SIZE  64
+#define PAD (PAT_SIZE/8)
+#define WIDTH (PAT_SIZE*4 + PAD*5)
+#define HEIGHT (PAT_SIZE + PAD*2)
+
+/* Test case based on bug 89232 - painting a recording surface to a pdf/ps surface
+ * omits objects on the recording surface with negative coordinates even though
+ * the pattern matrix has transformed the objects to within the page extents.
+ * The bug is a result of pdf/ps assuming the surface extents are always
+ * (0,0) to (page_width, page_height).
+ *
+ * Each test has four cases of painting a recording pattern where:
+ * 1) recording surface origin is transformed to the center of the pattern
+ * 2) same as 1) but also scaled up 10x
+ * 3) same as 1) but also scaled down 10x
+ * 4) same as 1) but also rotated 45 deg
+ */
+
+
+static void
+transform_extents(cairo_rectangle_t *extents, cairo_matrix_t *mat)
+{
+    double x1, y1, x2, y2, x, y;
+
+#define UPDATE_BBOX \
+    x1 = x < x1 ? x : x1; \
+    y1 = y < y1 ? y : y1; \
+    x2 = x > x2 ? x : x2; \
+    y2 = y > y2 ? y : y2;
+
+    x = extents->x;
+    y = extents->y;
+    cairo_matrix_transform_point (mat, &x, &y);
+    x1 = x2 = x;
+    y1 = y2 = y;
+
+    x = extents->x + extents->width;
+    y = extents->y;
+    cairo_matrix_transform_point (mat, &x, &y);
+    UPDATE_BBOX;
+
+    x = extents->x;
+    y = extents->y + extents->height;
+    cairo_matrix_transform_point (mat, &x, &y);
+    UPDATE_BBOX;
+
+    x = extents->x + extents->width;
+    y = extents->y + extents->height;
+    cairo_matrix_transform_point (mat, &x, &y);
+    UPDATE_BBOX;
+
+    extents->x = x1;
+    extents->y = y1;
+    extents->width = x2 - extents->x;
+    extents->height = y2 - extents->y;
+
+#undef UPDATE_BBOX
+}
+
+static cairo_pattern_t *
+create_pattern (cairo_matrix_t *mat, cairo_bool_t bounded)
+{
+    cairo_surface_t *surf;
+    cairo_pattern_t *pat;
+    cairo_t *cr;
+    int border;
+    int square;
+
+    if (bounded) {
+	cairo_rectangle_t extents = { 0, 0, PAT_SIZE, PAT_SIZE };
+	transform_extents (&extents, mat);
+	surf = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, &extents);
+    } else {
+	surf = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL);
+    }
+
+    cr = cairo_create (surf);
+    cairo_transform (cr, mat);
+
+    border  = PAT_SIZE/8;
+    square = (PAT_SIZE - 2*border)/2;
+
+    cairo_rectangle (cr, 0, 0, PAT_SIZE, PAT_SIZE);
+    cairo_clip (cr);
+    cairo_set_source_rgb (cr, 1, 0, 0);
+    cairo_paint (cr);
+
+    cairo_translate (cr, border, border);
+    cairo_rectangle (cr, 0, 0, square, square);
+    cairo_set_source_rgb (cr, 0, 1, 0);
+    cairo_fill (cr);
+
+    cairo_translate (cr, square, 0);
+    cairo_rectangle (cr, 0, 0, square, square);
+    cairo_set_source_rgb (cr, 0, 0, 1);
+    cairo_fill (cr);
+
+    cairo_translate (cr, 0, square);
+    cairo_rectangle (cr, 0, 0, square, square);
+    cairo_set_source_rgb (cr, 0, 1, 1);
+    cairo_fill (cr);
+
+    cairo_translate (cr, -square, 0);
+    cairo_rectangle (cr, 0, 0, square, square);
+    cairo_set_source_rgb (cr, 1, 1, 0);
+    cairo_fill (cr);
+
+    cairo_destroy (cr);
+
+    pat = cairo_pattern_create_for_surface (surf);
+    cairo_surface_destroy (surf);
+    cairo_pattern_set_matrix (pat, mat);
+
+    return pat;
+}
+
+static cairo_test_status_t
+record_extents (cairo_t *cr, int width, int height, cairo_bool_t bounded)
+{
+    cairo_pattern_t *pat;
+    cairo_matrix_t mat;
+
+    /* record surface extents (-PAT_SIZE/2, -PAT_SIZE/2) to (PAT_SIZE/2, PAT_SIZE/2) */
+    cairo_translate (cr, PAD, PAD);
+    cairo_matrix_init_translate (&mat, -PAT_SIZE/2, -PAT_SIZE/2);
+    pat = create_pattern (&mat, bounded);
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_paint (cr);
+
+    /* record surface extents (-10*PAT_SIZE/2, -10*PAT_SIZE/2) to (10*PAT_SIZE/2, 10*PAT_SIZE/2) */
+    cairo_translate (cr, PAT_SIZE + PAD, 0);
+    cairo_matrix_init_translate (&mat, -10.0*PAT_SIZE/2, -10.0*PAT_SIZE/2);
+    cairo_matrix_scale (&mat, 10, 10);
+    pat = create_pattern (&mat, bounded);
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_paint (cr);
+
+    /* record surface extents (-0.1*PAT_SIZE/2, -0.1*PAT_SIZE/2) to (0.1*PAT_SIZE/2, 0.1*PAT_SIZE/2) */
+    cairo_translate (cr, PAT_SIZE + PAD, 0);
+    cairo_matrix_init_translate (&mat, -0.1*PAT_SIZE/2, -0.1*PAT_SIZE/2);
+    cairo_matrix_scale (&mat, 0.1, 0.1);
+    pat = create_pattern (&mat, bounded);
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_paint (cr);
+
+    /* record surface centered on (0,0) and rotated 45 deg */
+    cairo_translate (cr, PAT_SIZE + PAD, 0);
+    cairo_matrix_init_translate (&mat, -PAT_SIZE/sqrt(2), -PAT_SIZE/sqrt(2));
+    cairo_matrix_rotate (&mat, M_PI/4.0);
+    cairo_matrix_translate (&mat, PAT_SIZE/2, -PAT_SIZE/2);
+    pat = create_pattern (&mat, bounded);
+    cairo_set_source (cr, pat);
+    cairo_pattern_destroy (pat);
+    cairo_paint (cr);
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+static cairo_test_status_t
+record_neg_extents_bounded (cairo_t *cr, int width, int height)
+{
+    return record_extents(cr, width, height, TRUE);
+}
+
+static cairo_test_status_t
+record_neg_extents_unbounded (cairo_t *cr, int width, int height)
+{
+    return record_extents(cr, width, height, FALSE);
+}
+
+
+CAIRO_TEST (record_neg_extents_unbounded,
+	    "Paint unbounded recording pattern with untransformed extents outside of target extents",
+	    "record,transform,pattern", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, record_neg_extents_unbounded)
+CAIRO_TEST (record_neg_extents_bounded,
+	    "Paint bounded recording pattern with untransformed extents outside of target extents",
+	    "record,transform,pattern", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, record_neg_extents_bounded)
diff --git a/test/reference/record-neg-extents-unbounded.ref.png b/test/reference/record-neg-extents-unbounded.ref.png
new file mode 100644
index 0000000..5218be5
Binary files /dev/null and b/test/reference/record-neg-extents-unbounded.ref.png differ


More information about the cairo-commit mailing list