From bed2701e1c89095878d549cbca8f22d84f3dda3c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 23 Jul 2009 15:32:13 +0100 Subject: [PATCH] Remove clip handling from generic surface layer. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handling clip as part of the surface state, as opposed to being part of the operation state, is cumbersome and a hindrance to providing true proxy surface support. For example, the clip must be copied from the surface onto the fallback image, but this was forgotten causing undue hassle in each backend. Another example is the contortion the meta surface endures to ensure the clip is correctly recorded. By contrast passing the clip along with the operation is quite simple and enables us to write generic handlers for providing surface wrappers. (And in the future, we should be able to write more esoteric wrappers, e.g. automatic 2x FSAA, trivially.) In brief, instead of the surface automatically applying the clip before calling the backend, the backend can call into a generic helper to apply clipping. For raster surfaces, clip regions are handled automatically as part of the composite interface. For vector surfaces, a clip helper is introduced to replay and callback into an intersect_clip_path() function as necessary. Whilst this is not primarily a performance related change (the change should just move the computation of the clip from the moment it is applied by the user to the moment it is required by the backend), it is important to track any potential regression: ppc: Speedups ======== image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup ▌ image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup ▎ image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup ▏ image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup ▏ Slowdowns ========= image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown ▏ --- NEWS | 6 + boilerplate/cairo-boilerplate-glitz-glx.c | 4 - boilerplate/cairo-boilerplate-pdf.c | 1 - boilerplate/cairo-boilerplate-ps.c | 8 +- boilerplate/cairo-boilerplate-qt.cpp | 4 +- boilerplate/cairo-boilerplate-svg.c | 1 - boilerplate/cairo-boilerplate-test-surfaces.c | 113 +- boilerplate/cairo-boilerplate.c | 100 +- boilerplate/cairo-boilerplate.h | 2 + perf/unaligned-clip.c | 3 + src/Makefile.sources | 7 + src/cairo-analysis-surface-private.h | 6 +- src/cairo-analysis-surface.c | 551 +++---- src/cairo-beos-surface.cpp | 407 +++-- src/cairo-clip-private.h | 87 +- src/cairo-clip.c | 1452 +++++++++-------- src/cairo-debug.c | 2 + src/cairo-directfb-surface.c | 491 +++--- src/cairo-ft-font.c | 53 +- src/cairo-gl-private.h | 1 + src/cairo-gl-surface.c | 216 ++- src/cairo-glitz-surface.c | 213 +-- src/cairo-gstate.c | 233 ++- src/cairo-image-surface.c | 173 +- src/cairo-meta-surface-private.h | 43 +- src/cairo-meta-surface.c | 550 +++---- src/cairo-os2-surface.c | 14 +- src/cairo-paginated-private.h | 2 - src/cairo-paginated-surface-private.h | 9 - src/cairo-paginated-surface.c | 234 ++- src/cairo-path-bounds.c | 65 +- src/cairo-path-fill.c | 11 +- src/cairo-path-fixed-private.h | 36 +- src/cairo-path-fixed.c | 201 ++- src/cairo-path-in-fill.c | 27 +- src/cairo-path-stroke.c | 8 +- src/cairo-pattern.c | 131 +- src/cairo-pdf-surface-private.h | 3 + src/cairo-pdf-surface.c | 220 +-- src/cairo-ps-surface-private.h | 4 + src/cairo-ps-surface.c | 367 +++-- src/cairo-qt-surface.cpp | 377 ++--- src/cairo-quartz-image-surface.c | 14 +- src/cairo-quartz-private.h | 2 + src/cairo-quartz-surface.c | 136 +- src/cairo-region-private.h | 73 + src/cairo-region.c | 170 +- src/cairo-scaled-font.c | 132 +- src/cairo-script-surface.c | 613 +++++-- src/cairo-script.h | 10 + src/cairo-spans-private.h | 19 +- src/cairo-spans.c | 20 +- src/cairo-stroke-style.c | 8 +- src/cairo-surface-clipper-private.h | 72 + src/cairo-surface-clipper.c | 138 ++ src/cairo-surface-fallback-private.h | 21 +- src/cairo-surface-fallback.c | 1009 +++++++----- src/cairo-surface-private.h | 19 +- src/cairo-surface-wrapper-private.h | 156 ++ src/cairo-surface-wrapper.c | 449 +++++ src/cairo-surface.c | 859 +++------- src/cairo-svg-surface-private.h | 4 +- src/cairo-svg-surface.c | 535 +++--- src/cairo-traps.c | 26 +- src/cairo-type3-glyph-surface-private.h | 9 +- src/cairo-type3-glyph-surface.c | 94 +- src/cairo-types-private.h | 9 +- src/cairo-user-font.c | 30 +- src/cairo-vg-surface.c | 122 +- src/cairo-win32-font.c | 16 +- src/cairo-win32-printing-surface.c | 194 +-- src/cairo-win32-private.h | 15 +- src/cairo-win32-surface.c | 279 ++-- src/cairo-xcb-surface.c | 248 +-- src/cairo-xlib-surface-private.h | 2 +- src/cairo-xlib-surface.c | 492 +++--- src/cairo.c | 83 +- src/cairo.h | 30 +- src/cairoint.h | 325 ++-- src/test-fallback-surface.c | 4 +- src/test-fallback16-surface.c | 4 +- src/test-null-surface.c | 35 +- src/test-paginated-surface.c | 100 +- src/test-paginated-surface.h | 6 +- src/test-wrapping-surface.c | 272 +++ src/test-wrapping-surface.h | 51 + test/Makefile.am | 75 +- test/Makefile.sources | 2 + test/buffer-diff.c | 12 +- test/cairo-test.c | 18 +- test/clip-operator.pdf.argb32.ref.png | Bin 0 -> 9340 bytes test/clip-operator.pdf.argb32.xfail.png | Bin 9340 -> 0 bytes test/clip-operator.pdf.rgb24.ref.png | Bin 0 -> 5146 bytes test/clip-operator.pdf.rgb24.xfail.png | Bin 5155 -> 0 bytes test/clip-operator.svg12.argb32.xfail.png | Bin 8404 -> 8406 bytes test/clip-operator.svg12.rgb24.xfail.png | Bin 4523 -> 4540 bytes test/clip-operator.xlib-fallback.ref.png | Bin 0 -> 3226 bytes .../clip-operator.xlib-fallback.rgb24.ref.png | Bin 3254 -> 0 bytes test/clip-push-group.pdf.ref.png | Bin 0 -> 164 bytes test/clip-push-group.ref.png | Bin 199 -> 164 bytes test/clip-push-group.xlib.ref.png | Bin 0 -> 155 bytes test/clip-unbounded.c | 80 + test/clip-unbounded.ref.png | Bin 0 -> 100 bytes test/clip-unbounded.rgb24.ref.png | Bin 0 -> 97 bytes test/clip-unbounded.svg12.rgb24.xfail.png | Bin 0 -> 100 bytes test/clipped-group.pdf.argb32.ref.png | Bin 298 -> 0 bytes test/clipped-group.pdf.ref.png | Bin 0 -> 310 bytes test/clipped-group.pdf.rgb24.ref.png | Bin 298 -> 0 bytes test/clipped-group.ref.png | Bin 350 -> 316 bytes ...er-translate-source.svg12.argb32.xfail.png | Bin 0 -> 16392 bytes ...ger-translate-source.svg12.rgb24.xfail.png | Bin 0 -> 16392 bytes ...evice-offset-fractional.pdf.argb32.ref.png | Bin 275 -> 0 bytes test/device-offset-fractional.pdf.ref.png | Bin 277 -> 0 bytes ...device-offset-fractional.pdf.rgb24.ref.png | Bin 275 -> 0 bytes test/device-offset-fractional.pdf.xfail.png | Bin 0 -> 275 bytes ...xtended-blend-alpha.svg12.argb32.xfail.png | Bin 0 -> 6857 bytes ...extended-blend-alpha.svg12.rgb24.xfail.png | Bin 0 -> 5014 bytes test/extended-blend.svg12.argb32.xfail.png | Bin 0 -> 2273 bytes test/extended-blend.svg12.rgb24.xfail.png | Bin 0 -> 1856 bytes test/fill-empty.argb32.ref.png | Bin 0 -> 99 bytes test/fill-empty.c | 62 + test/fill-empty.rgb24.ref.png | Bin 0 -> 97 bytes test/fill-empty.svg12.rgb24.xfail.png | Bin 0 -> 99 bytes test/filter-nearest-offset.pdf.xfail.png | Bin 1926 -> 1867 bytes test/filter-nearest-transformed.pdf.xfail.png | Bin 488 -> 482 bytes ...t-vertical-layout-type1.pdf.argb32.ref.png | Bin 3632 -> 0 bytes .../ft-text-vertical-layout-type1.pdf.ref.png | Bin 3968 -> 3635 bytes ...xt-vertical-layout-type1.pdf.rgb24.ref.png | Bin 3632 -> 0 bytes ...t-vertical-layout-type3.pdf.argb32.ref.png | Bin 3642 -> 0 bytes .../ft-text-vertical-layout-type3.pdf.ref.png | Bin 3634 -> 3639 bytes ...xt-vertical-layout-type3.pdf.rgb24.ref.png | Bin 3642 -> 0 bytes test/ft-text-vertical-layout-type3.ref.png | Bin 3609 -> 3608 bytes test/group-unaligned.svg.argb32.xfail.png | Bin 522 -> 520 bytes test/group-unaligned.xlib-fallback.ref.png | Bin 496 -> 474 bytes ...mage-surface-source.svg12.argb32.xfail.png | Bin 0 -> 278 bytes ...image-surface-source.svg12.rgb24.xfail.png | Bin 0 -> 278 bytes test/in-fill-trapezoid.c | 19 +- test/mask-glyphs.svg.ref.png | Bin 1211170 -> 1211147 bytes test/mask.pdf.argb32.ref.png | Bin 0 -> 7837 bytes test/mask.pdf.argb32.xfail.png | Bin 7944 -> 0 bytes test/mask.pdf.rgb24.ref.png | Bin 0 -> 7301 bytes test/mask.pdf.rgb24.xfail.png | Bin 7388 -> 0 bytes test/mask.xlib-fallback.rgb24.ref.png | Bin 7216 -> 0 bytes test/meta-surface-pattern.pdf.argb32.ref.png | Bin 4009 -> 3868 bytes test/meta-surface-pattern.pdf.rgb24.ref.png | Bin 3905 -> 3806 bytes test/operator-clear.xlib.argb32.ref.png | Bin 0 -> 1071 bytes ....png => operator-clear.xlib.rgb24.ref.png} | Bin ....png => operator-source.pdf.rgb24.ref.png} | Bin test/operator-source.svg12.argb32.xfail.png | Bin 2951 -> 2967 bytes test/operator-source.svg12.rgb24.xfail.png | Bin 2963 -> 2976 bytes test/operator-source.xlib-fallback.ref.png | Bin 0 -> 3177 bytes ...perator-source.xlib-fallback.rgb24.ref.png | Bin 3193 -> 0 bytes test/path-append.xlib-fallback.ref.png | Bin 6357 -> 6320 bytes .../pdf-surface-source.svg12.argb32.xfail.png | Bin 0 -> 278 bytes test/pdf-surface-source.svg12.rgb24.xfail.png | Bin 0 -> 278 bytes test/ps-surface-source.svg12.argb32.xfail.png | Bin 0 -> 278 bytes test/ps-surface-source.svg12.rgb24.xfail.png | Bin 0 -> 278 bytes test/push-group.xlib-fallback.rgb24.ref.png | Bin 2912 -> 0 bytes test/scale-offset-image.meta.xfail.png | Bin 0 -> 8599 bytes test/scale-offset-image.pdf.rgb24.ref.png | Bin 8691 -> 0 bytes ...f.png => scale-offset-image.pdf.xfail.png} | Bin ...scale-offset-image.xlib-fallback.xfail.png | Bin 0 -> 8580 bytes test/scale-offset-similar.meta.xfail.png | Bin 0 -> 9095 bytes test/scale-offset-similar.pdf.argb32.ref.png | Bin 9278 -> 0 bytes test/scale-offset-similar.pdf.rgb24.ref.png | Bin 9278 -> 0 bytes test/scale-offset-similar.pdf.xfail.png | Bin 0 -> 9369 bytes ...ale-offset-similar.xlib-fallback.xfail.png | Bin 0 -> 8580 bytes test/self-intersecting.argb32.xfail.png | Bin 287 -> 235 bytes test/self-intersecting.pdf.argb32.xfail.png | Bin 295 -> 285 bytes test/self-intersecting.pdf.rgb24.xfail.png | Bin 272 -> 269 bytes test/self-intersecting.rgb24.xfail.png | Bin 282 -> 240 bytes test/smask-fill.xlib-fallback.ref.png | Bin 1156 -> 0 bytes test/smask-text.xlib.ref.png | Bin 0 -> 1672 bytes test/smask.xlib.ref.png | Bin 0 -> 3393 bytes ...urface-pattern-big-scale-down.ps.xfail.png | Bin 0 -> 238 bytes .../svg-surface-source.svg12.argb32.xfail.png | Bin 0 -> 278 bytes test/svg-surface-source.svg12.rgb24.xfail.png | Bin 0 -> 278 bytes ...ck16-surface-source.svg12.argb32.xfail.png | Bin 0 -> 278 bytes ...ack16-surface-source.svg12.rgb24.xfail.png | Bin 0 -> 278 bytes test/text-pattern.pdf.argb32.ref.png | Bin 0 -> 1831 bytes test/text-pattern.pdf.argb32.xfail.png | Bin 1845 -> 0 bytes test/text-pattern.pdf.rgb24.ref.png | Bin 0 -> 1598 bytes test/text-pattern.pdf.rgb24.xfail.png | Bin 1599 -> 0 bytes .../unbounded-operator.svg12.argb32.xfail.png | Bin 2767 -> 2771 bytes test/unbounded-operator.svg12.rgb24.xfail.png | Bin 1719 -> 1731 bytes test/user-font-proxy.svg.ref.png | Bin 16817 -> 16814 bytes ...xlib-surface-source.svg12.argb32.xfail.png | Bin 0 -> 278 bytes .../xlib-surface-source.svg12.rgb24.xfail.png | Bin 0 -> 278 bytes util/cairo-script/cairo-script-file.c | 39 +- util/cairo-script/cairo-script-objects.c | 22 + util/cairo-script/cairo-script-private.h | 9 +- util/cairo-script/cairo-script-scanner.c | 52 +- util/cairo-trace/trace.c | 119 +- 193 files changed, 7844 insertions(+), 6006 deletions(-) create mode 100644 src/cairo-region-private.h create mode 100644 src/cairo-surface-clipper-private.h create mode 100644 src/cairo-surface-clipper.c create mode 100644 src/cairo-surface-wrapper-private.h create mode 100644 src/cairo-surface-wrapper.c create mode 100644 src/test-wrapping-surface.c create mode 100644 src/test-wrapping-surface.h create mode 100644 test/clip-operator.pdf.argb32.ref.png delete mode 100644 test/clip-operator.pdf.argb32.xfail.png create mode 100644 test/clip-operator.pdf.rgb24.ref.png delete mode 100644 test/clip-operator.pdf.rgb24.xfail.png create mode 100644 test/clip-operator.xlib-fallback.ref.png delete mode 100644 test/clip-operator.xlib-fallback.rgb24.ref.png create mode 100644 test/clip-push-group.pdf.ref.png create mode 100644 test/clip-push-group.xlib.ref.png create mode 100644 test/clip-unbounded.c create mode 100644 test/clip-unbounded.ref.png create mode 100644 test/clip-unbounded.rgb24.ref.png create mode 100644 test/clip-unbounded.svg12.rgb24.xfail.png delete mode 100644 test/clipped-group.pdf.argb32.ref.png create mode 100644 test/clipped-group.pdf.ref.png delete mode 100644 test/clipped-group.pdf.rgb24.ref.png create mode 100644 test/composite-integer-translate-source.svg12.argb32.xfail.png create mode 100644 test/composite-integer-translate-source.svg12.rgb24.xfail.png delete mode 100644 test/device-offset-fractional.pdf.argb32.ref.png delete mode 100644 test/device-offset-fractional.pdf.ref.png delete mode 100644 test/device-offset-fractional.pdf.rgb24.ref.png create mode 100644 test/device-offset-fractional.pdf.xfail.png create mode 100644 test/extended-blend-alpha.svg12.argb32.xfail.png create mode 100644 test/extended-blend-alpha.svg12.rgb24.xfail.png create mode 100644 test/extended-blend.svg12.argb32.xfail.png create mode 100644 test/extended-blend.svg12.rgb24.xfail.png create mode 100644 test/fill-empty.argb32.ref.png create mode 100644 test/fill-empty.c create mode 100644 test/fill-empty.rgb24.ref.png create mode 100644 test/fill-empty.svg12.rgb24.xfail.png delete mode 100644 test/ft-text-vertical-layout-type1.pdf.argb32.ref.png delete mode 100644 test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png delete mode 100644 test/ft-text-vertical-layout-type3.pdf.argb32.ref.png delete mode 100644 test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png create mode 100644 test/image-surface-source.svg12.argb32.xfail.png create mode 100644 test/image-surface-source.svg12.rgb24.xfail.png create mode 100644 test/mask.pdf.argb32.ref.png delete mode 100644 test/mask.pdf.argb32.xfail.png create mode 100644 test/mask.pdf.rgb24.ref.png delete mode 100644 test/mask.pdf.rgb24.xfail.png delete mode 100644 test/mask.xlib-fallback.rgb24.ref.png create mode 100644 test/operator-clear.xlib.argb32.ref.png rename test/{operator-clear.xlib.ref.png => operator-clear.xlib.rgb24.ref.png} (100%) rename test/{operator-source.pdf.rgb24.xfail.png => operator-source.pdf.rgb24.ref.png} (100%) create mode 100644 test/operator-source.xlib-fallback.ref.png delete mode 100644 test/operator-source.xlib-fallback.rgb24.ref.png create mode 100644 test/pdf-surface-source.svg12.argb32.xfail.png create mode 100644 test/pdf-surface-source.svg12.rgb24.xfail.png create mode 100644 test/ps-surface-source.svg12.argb32.xfail.png create mode 100644 test/ps-surface-source.svg12.rgb24.xfail.png delete mode 100644 test/push-group.xlib-fallback.rgb24.ref.png create mode 100644 test/scale-offset-image.meta.xfail.png delete mode 100644 test/scale-offset-image.pdf.rgb24.ref.png rename test/{scale-offset-image.pdf.argb32.ref.png => scale-offset-image.pdf.xfail.png} (100%) create mode 100644 test/scale-offset-image.xlib-fallback.xfail.png create mode 100644 test/scale-offset-similar.meta.xfail.png delete mode 100644 test/scale-offset-similar.pdf.argb32.ref.png delete mode 100644 test/scale-offset-similar.pdf.rgb24.ref.png create mode 100644 test/scale-offset-similar.pdf.xfail.png create mode 100644 test/scale-offset-similar.xlib-fallback.xfail.png delete mode 100644 test/smask-fill.xlib-fallback.ref.png create mode 100644 test/smask-text.xlib.ref.png create mode 100644 test/smask.xlib.ref.png create mode 100644 test/surface-pattern-big-scale-down.ps.xfail.png create mode 100644 test/svg-surface-source.svg12.argb32.xfail.png create mode 100644 test/svg-surface-source.svg12.rgb24.xfail.png create mode 100644 test/test-fallback16-surface-source.svg12.argb32.xfail.png create mode 100644 test/test-fallback16-surface-source.svg12.rgb24.xfail.png create mode 100644 test/text-pattern.pdf.argb32.ref.png delete mode 100644 test/text-pattern.pdf.argb32.xfail.png create mode 100644 test/text-pattern.pdf.rgb24.ref.png delete mode 100644 test/text-pattern.pdf.rgb24.xfail.png create mode 100644 test/xlib-surface-source.svg12.argb32.xfail.png create mode 100644 test/xlib-surface-source.svg12.rgb24.xfail.png diff --git a/NEWS b/NEWS index 681f2345f..a561a3f9a 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,12 @@ API additions: Finally exporting the internal meta-surface so that applications have a method to record and replay a sequence of drawing commands. + cairo_in_clip() + + Determines whether a given point is inside the current clip. + ??? Should this be called cairo_in_paint() instead? in-clip is the test + that is performed, but in-paint would be similar to in-fill and in-stroke. + New utilities: cairo-test-trace diff --git a/boilerplate/cairo-boilerplate-glitz-glx.c b/boilerplate/cairo-boilerplate-glitz-glx.c index 6dfdb7fec..6e3cfec37 100644 --- a/boilerplate/cairo-boilerplate-glitz-glx.c +++ b/boilerplate/cairo-boilerplate-glitz-glx.c @@ -33,7 +33,6 @@ static const cairo_user_data_key_t glitz_closure_key; typedef struct _glitz_glx_target_closure { - glitz_target_closure_base_t base; Display *dpy; int scr; Window win; @@ -206,9 +205,6 @@ _cairo_boilerplate_glitz_glx_create_surface (const char *name, if (cairo_surface_status (surface)) goto FAIL_CLOSE_DISPLAY; - gxtc->base.width = width; - gxtc->base.height = height; - gxtc->base.content = content; status = cairo_surface_set_user_data (surface, &glitz_closure_key, gxtc, NULL); if (status == CAIRO_STATUS_SUCCESS) diff --git a/boilerplate/cairo-boilerplate-pdf.c b/boilerplate/cairo-boilerplate-pdf.c index 166ba1c96..e941d46ff 100644 --- a/boilerplate/cairo-boilerplate-pdf.c +++ b/boilerplate/cairo-boilerplate-pdf.c @@ -129,7 +129,6 @@ _cairo_boilerplate_pdf_finish_surface (cairo_surface_t *surface) if (status) return status; - cairo_surface_finish (surface); status = cairo_surface_status (surface); if (status) return status; diff --git a/boilerplate/cairo-boilerplate-ps.c b/boilerplate/cairo-boilerplate-ps.c index 0fdd0cfab..40148ddeb 100644 --- a/boilerplate/cairo-boilerplate-ps.c +++ b/boilerplate/cairo-boilerplate-ps.c @@ -178,6 +178,7 @@ _cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface) if (ptc->target) { cairo_t *cr; + cr = cairo_create (ptc->target); cairo_set_source_surface (cr, surface, 0, 0); cairo_paint (cr); @@ -188,7 +189,6 @@ _cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface) if (status) return status; - cairo_surface_finish (surface); status = cairo_surface_status (surface); if (status) return status; @@ -197,11 +197,7 @@ _cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface) } cairo_surface_finish (surface); - status = cairo_surface_status (surface); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; + return cairo_surface_status (surface); } static cairo_status_t diff --git a/boilerplate/cairo-boilerplate-qt.cpp b/boilerplate/cairo-boilerplate-qt.cpp index 5d8d3f933..8f19811f5 100644 --- a/boilerplate/cairo-boilerplate-qt.cpp +++ b/boilerplate/cairo-boilerplate-qt.cpp @@ -30,7 +30,7 @@ * The Initial Developer of the Original Code is Chris Wilson. */ -#include "cairo-boilerplate.h" +#include "cairo-boilerplate-private.h" #include @@ -108,4 +108,6 @@ static const cairo_boilerplate_target_t targets[] = { _cairo_boilerplate_qt_cleanup }, }; +extern "C" { CAIRO_BOILERPLATE (qt, targets) +} diff --git a/boilerplate/cairo-boilerplate-svg.c b/boilerplate/cairo-boilerplate-svg.c index 9d03b203a..45e085ce9 100644 --- a/boilerplate/cairo-boilerplate-svg.c +++ b/boilerplate/cairo-boilerplate-svg.c @@ -166,7 +166,6 @@ _cairo_boilerplate_svg_finish_surface (cairo_surface_t *surface) if (status) return status; - cairo_surface_finish (surface); status = cairo_surface_status (surface); if (status) return status; diff --git a/boilerplate/cairo-boilerplate-test-surfaces.c b/boilerplate/cairo-boilerplate-test-surfaces.c index 849627fd3..501866bad 100644 --- a/boilerplate/cairo-boilerplate-test-surfaces.c +++ b/boilerplate/cairo-boilerplate-test-surfaces.c @@ -33,6 +33,7 @@ #include #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,9,3) #include +#include #endif #include @@ -49,7 +50,8 @@ _cairo_boilerplate_test_fallback_create_surface (const char *name, void **closure) { *closure = NULL; - return _cairo_test_fallback_surface_create (content, width, height); + return _cairo_test_fallback_surface_create (content, + ceil (width), ceil (height)); } static cairo_surface_t * @@ -64,7 +66,8 @@ _cairo_boilerplate_test_fallback16_create_surface (const char *name, void **closure) { *closure = NULL; - return _cairo_test_fallback16_surface_create (content, width, height); + return _cairo_test_fallback16_surface_create (content, + ceil (width), ceil (height)); } static cairo_surface_t * @@ -89,11 +92,7 @@ _cairo_boilerplate_test_null_create_surface (const char *name, static const cairo_user_data_key_t test_paginated_closure_key; typedef struct { - unsigned char *data; - cairo_content_t content; - int width; - int height; - int stride; + cairo_surface_t *target; } test_paginated_closure_t; static cairo_surface_t * @@ -115,18 +114,10 @@ _cairo_boilerplate_test_paginated_create_surface (const char *name, *closure = tpc = xmalloc (sizeof (test_paginated_closure_t)); format = cairo_boilerplate_format_from_content (content); + tpc->target = cairo_image_surface_create (format, + ceil (width), ceil (height)); - tpc->content = content; - tpc->width = width; - tpc->height = height; - tpc->stride = cairo_format_stride_for_width (format, width); - tpc->data = xcalloc (tpc->stride, height); - - surface = _cairo_test_paginated_surface_create_for_data (tpc->data, - tpc->content, - tpc->width, - tpc->height, - tpc->stride); + surface = _cairo_test_paginated_surface_create (tpc->target); if (cairo_surface_status (surface)) goto CLEANUP; @@ -139,8 +130,9 @@ _cairo_boilerplate_test_paginated_create_surface (const char *name, cairo_surface_destroy (surface); surface = cairo_boilerplate_surface_create_in_error (status); + cairo_surface_destroy (tpc->target); + CLEANUP: - free (tpc->data); free (tpc); return surface; } @@ -160,8 +152,6 @@ static cairo_status_t _cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t *surface, const char *filename) { - cairo_surface_t *image; - cairo_format_t format; test_paginated_closure_t *tpc; cairo_status_t status; @@ -172,19 +162,7 @@ _cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t *surface return status; tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key); - - format = cairo_boilerplate_format_from_content (tpc->content); - - image = cairo_image_surface_create_for_data (tpc->data, - format, - tpc->width, - tpc->height, - tpc->stride); - - status = cairo_surface_write_to_png (image, filename); - cairo_surface_destroy (image); - - return status; + return cairo_surface_write_to_png (tpc->target, filename); } static cairo_surface_t * @@ -193,7 +171,6 @@ _cairo_boilerplate_test_paginated_get_image_surface (cairo_surface_t *surface, int width, int height) { - cairo_format_t format; test_paginated_closure_t *tpc; cairo_status_t status; @@ -208,30 +185,7 @@ _cairo_boilerplate_test_paginated_get_image_surface (cairo_surface_t *surface, return cairo_boilerplate_surface_create_in_error (status); tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key); - - format = cairo_boilerplate_format_from_content (tpc->content); - - if (0) { - return cairo_image_surface_create_for_data (tpc->data + tpc->stride * (tpc->height - height) + 4 * (tpc->width - width), /* hide the device offset */ - format, - width, - height, - tpc->stride); - } else { - cairo_surface_t *image, *surface; - - image = cairo_image_surface_create_for_data (tpc->data, - format, - tpc->width, - tpc->height, - tpc->stride); - cairo_surface_set_device_offset (image, - tpc->width - width, - tpc->height - height); - surface = _cairo_boilerplate_get_image_surface (image, 0, width, height); - cairo_surface_destroy (image); - return surface; - } + return _cairo_boilerplate_get_image_surface (tpc->target, 0, width, height); } static void @@ -239,10 +193,40 @@ _cairo_boilerplate_test_paginated_cleanup (void *closure) { test_paginated_closure_t *tpc = closure; - free (tpc->data); + cairo_surface_destroy (tpc->target); free (tpc); } +static cairo_surface_t * +_cairo_boilerplate_test_wrapping_create_surface (const char *name, + cairo_content_t content, + double width, + double height, + double max_width, + double max_height, + cairo_boilerplate_mode_t mode, + int id, + void **closure) +{ +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,9,3) + cairo_surface_t *target; + cairo_surface_t *surface; + cairo_format_t format; + + *closure = NULL; + + format = cairo_boilerplate_format_from_content (content); + target = cairo_image_surface_create (format, ceil (width), ceil (height)); + surface = _cairo_test_wrapping_surface_create (target); + cairo_surface_destroy (target); + + return surface; +#else + *closure = NULL; + return NULL; +#endif +} + static const cairo_boilerplate_target_t targets[] = { { "test-fallback", "image", NULL, NULL, @@ -304,6 +288,15 @@ static const cairo_boilerplate_target_t targets[] = { NULL, FALSE, TRUE }, + { + "test-wrapping", "image", NULL, NULL, + CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING, + CAIRO_CONTENT_COLOR_ALPHA, 0, + _cairo_boilerplate_test_wrapping_create_surface, + NULL, NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png, + }, { "null", "image", NULL, NULL, CAIRO_INTERNAL_SURFACE_TYPE_NULL, diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c index ea88c691e..a0810457a 100644 --- a/boilerplate/cairo-boilerplate.c +++ b/boilerplate/cairo-boilerplate.c @@ -32,6 +32,10 @@ #include #include +#if CAIRO_HAS_SCRIPT_SURFACE +#include +#endif + /* get the "real" version info instead of dummy cairo-version.h */ #undef CAIRO_VERSION_H #include "../cairo-version.h" @@ -136,48 +140,74 @@ _cairo_boilerplate_meta_create_surface (const char *name, int id, void **closure) { + cairo_rectangle_t extents; + *closure = NULL; - return cairo_meta_surface_create (content, width, height); + + extents.x = 0; + extents.y = 0; + extents.width = width; + extents.height = height; + return cairo_meta_surface_create (content, &extents); } +const cairo_user_data_key_t cairo_boilerplate_output_basename_key; + +#if CAIRO_HAS_SCRIPT_SURFACE +static cairo_status_t +stdio_write (void *closure, const unsigned char *data, unsigned int len) +{ + if (fwrite (data, len, 1, closure) != 1) + return CAIRO_STATUS_WRITE_ERROR; + + return CAIRO_STATUS_SUCCESS; +} +#endif + cairo_surface_t * _cairo_boilerplate_get_image_surface (cairo_surface_t *src, int page, int width, int height) { - cairo_surface_t *surface; + FILE *file = NULL; + cairo_surface_t *surface, *image; cairo_t *cr; + cairo_status_t status; if (cairo_surface_status (src)) return cairo_surface_reference (src); -#if 0 - if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_IMAGE) { - int ww = cairo_image_surface_get_width (src); - int hh = cairo_image_surface_get_height (src); - if (width == ww && hh == height) { - return cairo_surface_reference (src); - } else { - cairo_format_t format = cairo_image_surface_get_format (src); - unsigned char *data = cairo_image_surface_get_data (src); - int stride = cairo_image_surface_get_stride (src); - - data += stride * (hh - height) + 4 * (ww - width); - return cairo_image_surface_create_for_data (data, - format, - width, - height, - stride); - } - } -#endif - if (page != 0) return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); /* extract sub-surface */ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); + image = cairo_surface_reference (surface); + + /* open a logging channel (only interesting for meta surfaces) */ +#if CAIRO_HAS_SCRIPT_SURFACE + if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_META) { + const char *test_name; + + test_name = cairo_surface_get_user_data (src, + &cairo_boilerplate_output_basename_key); + if (test_name != NULL) { + char *filename; + + xasprintf (&filename, "%s.out.trace", test_name); + file = fopen (filename, "w"); + free (filename); + + if (file != NULL) { + surface = cairo_script_surface_create_for_target (image, + stdio_write, + file); + } + } + } +#endif + cr = cairo_create (surface); cairo_surface_destroy (surface); @@ -185,10 +215,17 @@ _cairo_boilerplate_get_image_surface (cairo_surface_t *src, cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); - surface = cairo_surface_reference (cairo_get_target (cr)); + status = cairo_status (cr); + if (status) { + cairo_surface_destroy (image); + image = cairo_surface_reference (cairo_get_target (cr)); + } cairo_destroy (cr); - return surface; + if (file != NULL) + fclose (file); + + return image; } cairo_surface_t * @@ -705,8 +742,13 @@ cairo_boilerplate_convert_to_image (const char *filename, int page) image = cairo_boilerplate_image_surface_create_from_ppm_stream (file); ret = pclose (file); + /* check for fatal errors from the interpreter */ + if (ret) { /* any2pmm should never die... */ + cairo_surface_destroy (image); + return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_INVALID_STATUS); + } - if (cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) { + if (ret == 0 && cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) { if (flags == 0) { /* Try again in a standalone process. */ cairo_surface_destroy (image); @@ -715,12 +757,6 @@ cairo_boilerplate_convert_to_image (const char *filename, int page) } } - if (cairo_surface_status (image) == CAIRO_STATUS_SUCCESS && ret != 0) { - cairo_surface_destroy (image); - image = - cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); - }; - return image; } diff --git a/boilerplate/cairo-boilerplate.h b/boilerplate/cairo-boilerplate.h index aaa196c5f..377d2f913 100644 --- a/boilerplate/cairo-boilerplate.h +++ b/boilerplate/cairo-boilerplate.h @@ -99,6 +99,8 @@ CAIRO_BEGIN_DECLS * PDF surfaces. */ #define CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED ((unsigned int) -1) +extern const cairo_user_data_key_t cairo_boilerplate_output_basename_key; + cairo_content_t cairo_boilerplate_content (cairo_content_t content); diff --git a/perf/unaligned-clip.c b/perf/unaligned-clip.c index 7fd5245e1..f379b61e5 100644 --- a/perf/unaligned-clip.c +++ b/perf/unaligned-clip.c @@ -49,6 +49,9 @@ do_unaligned_clip (cairo_t *cr, int width, int height) cairo_rectangle (cr, 55, 55, 35, 35); cairo_clip (cr); + /* And paint something to force the clip to be evaluated. */ + cairo_paint (cr); + cairo_perf_timer_stop (); cairo_restore (cr); diff --git a/src/Makefile.sources b/src/Makefile.sources index c5c14f73b..d6fa582a9 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -79,11 +79,14 @@ cairo_private = \ cairo-path-private.h \ cairo-private.h \ cairo-reference-count-private.h \ + cairo-region-private.h \ cairo-scaled-font-private.h \ cairo-skiplist-private.h \ cairo-spans-private.h \ cairo-surface-fallback-private.h \ cairo-surface-private.h \ + cairo-surface-clipper-private.h \ + cairo-surface-wrapper-private.h \ cairo-types-private.h \ cairo-user-font-private.h \ cairo-wideint-private.h \ @@ -138,6 +141,8 @@ cairo_sources = \ cairo-stroke-style.c \ cairo-surface.c \ cairo-surface-fallback.c \ + cairo-surface-clipper.c \ + cairo-surface-wrapper.c \ cairo-tor-scan-converter.c \ cairo-system.c \ cairo-traps.c \ @@ -198,12 +203,14 @@ cairo_test_surfaces_private = \ test-fallback16-surface.h \ test-null-surface.h \ test-paginated-surface.h \ + test-wrapping-surface.h \ $(NULL) cairo_test_surfaces_sources = \ test-fallback-surface.c \ test-fallback16-surface.c \ test-null-surface.c \ test-paginated-surface.c \ + test-wrapping-surface.c \ $(NULL) cairo_xlib_headers = cairo-xlib.h diff --git a/src/cairo-analysis-surface-private.h b/src/cairo-analysis-surface-private.h index 28bfd3bf4..f67caf904 100644 --- a/src/cairo-analysis-surface-private.h +++ b/src/cairo-analysis-surface-private.h @@ -38,13 +38,11 @@ #include "cairoint.h" cairo_private cairo_surface_t * -_cairo_analysis_surface_create (cairo_surface_t *target, - int width, - int height); +_cairo_analysis_surface_create (cairo_surface_t *target); cairo_private void _cairo_analysis_surface_set_ctm (cairo_surface_t *surface, - cairo_matrix_t *ctm); + const cairo_matrix_t *ctm); cairo_private void _cairo_analysis_surface_get_ctm (cairo_surface_t *surface, diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 3a1b2f9ff..eb1e87d4c 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -39,13 +39,12 @@ #include "cairo-analysis-surface-private.h" #include "cairo-paginated-private.h" #include "cairo-meta-surface-private.h" +#include "cairo-region-private.h" typedef struct { cairo_surface_t base; - int width; - int height; - cairo_surface_t *target; + cairo_surface_t *target; cairo_bool_t first_op; cairo_bool_t has_supported; @@ -53,7 +52,6 @@ typedef struct { cairo_region_t supported_region; cairo_region_t fallback_region; - cairo_rectangle_int_t current_clip; cairo_box_t page_bbox; cairo_bool_t has_ctm; @@ -97,61 +95,38 @@ static cairo_int_status_t _analyze_meta_surface_pattern (cairo_analysis_surface_t *surface, const cairo_pattern_t *pattern) { - cairo_surface_t *analysis = &surface->base; const cairo_surface_pattern_t *surface_pattern; - cairo_status_t status; cairo_bool_t old_has_ctm; cairo_matrix_t old_ctm, p2d; - cairo_rectangle_int_t old_clip; - cairo_rectangle_int_t meta_extents; - int old_width; - int old_height; + cairo_status_t status; assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE); surface_pattern = (const cairo_surface_pattern_t *) pattern; assert (_cairo_surface_is_meta (surface_pattern->surface)); - old_width = surface->width; - old_height = surface->height; - old_clip = surface->current_clip; - status = _cairo_surface_get_extents (surface_pattern->surface, &meta_extents); - if (_cairo_status_is_error (status)) - return status; - - surface->width = meta_extents.width; - surface->height = meta_extents.height; - surface->current_clip.x = 0; - surface->current_clip.y = 0; - surface->current_clip.width = surface->width; - surface->current_clip.height = surface->height; old_ctm = surface->ctm; old_has_ctm = surface->has_ctm; + p2d = pattern->matrix; status = cairo_matrix_invert (&p2d); - /* _cairo_pattern_set_matrix guarantees invertibility */ assert (status == CAIRO_STATUS_SUCCESS); cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm); - surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm); + surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm); status = _cairo_meta_surface_replay_and_create_regions (surface_pattern->surface, - analysis); - if (status == CAIRO_STATUS_SUCCESS) - status = analysis->status; + &surface->base); surface->ctm = old_ctm; surface->has_ctm = old_has_ctm; - surface->current_clip = old_clip; - surface->width = old_width; - surface->height = old_height; return status; } static cairo_int_status_t -_add_operation (cairo_analysis_surface_t *surface, - cairo_rectangle_int_t *rect, - cairo_int_status_t backend_status) +_add_operation (cairo_analysis_surface_t *surface, + cairo_rectangle_int_t *rect, + cairo_int_status_t backend_status) { cairo_int_status_t status; cairo_box_t bbox; @@ -174,26 +149,33 @@ _add_operation (cairo_analysis_surface_t *surface, _cairo_box_from_rectangle (&bbox, rect); if (surface->has_ctm) { + int tx, ty; - _cairo_matrix_transform_bounding_box_fixed (&surface->ctm, &bbox, NULL); + if (_cairo_matrix_is_integer_translation (&surface->ctm, &tx, &ty)) { + rect->x += tx; + rect->y += ty; + } else { + _cairo_matrix_transform_bounding_box_fixed (&surface->ctm, + &bbox, NULL); - if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) { - /* Even though the operation is not visible we must be - * careful to not allow unsupported operations to be - * replayed to the backend during - * CAIRO_PAGINATED_MODE_RENDER */ - if (backend_status == CAIRO_STATUS_SUCCESS || - backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) - { - return CAIRO_STATUS_SUCCESS; - } - else - { - return CAIRO_INT_STATUS_IMAGE_FALLBACK; + if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) { + /* Even though the operation is not visible we must be + * careful to not allow unsupported operations to be + * replayed to the backend during + * CAIRO_PAGINATED_MODE_RENDER */ + if (backend_status == CAIRO_STATUS_SUCCESS || + backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) + { + return CAIRO_STATUS_SUCCESS; + } + else + { + return CAIRO_INT_STATUS_IMAGE_FALLBACK; + } } + + _cairo_box_round_to_rectangle (&bbox, rect); } - - _cairo_box_round_to_rectangle (&bbox, rect); } if (surface->first_op) { @@ -234,8 +216,7 @@ _add_operation (cairo_analysis_surface_t *surface, * this region will be emitted as native operations. */ surface->has_supported = TRUE; - status = cairo_region_union_rectangle (&surface->supported_region, rect); - return status; + return cairo_region_union_rectangle (&surface->supported_region, rect); } /* Add the operation to the unsupported region. This region will @@ -270,33 +251,7 @@ _cairo_analysis_surface_finish (void *abstract_surface) return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_cairo_analysis_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_analysis_surface_t *surface = abstract_surface; - - if (path == NULL) { - surface->current_clip.x = 0; - surface->current_clip.y = 0; - surface->current_clip.width = surface->width; - surface->current_clip.height = surface->height; - } else { - cairo_rectangle_int_t extents; - cairo_bool_t is_empty; - - _cairo_path_fixed_approximate_clip_extents (path, &extents); - is_empty = _cairo_rectangle_intersect (&surface->current_clip, - &extents); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t +static cairo_bool_t _cairo_analysis_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -305,66 +260,92 @@ _cairo_analysis_surface_get_extents (void *abstract_surface, return _cairo_surface_get_extents (surface->target, rectangle); } -static cairo_int_status_t -_cairo_analysis_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_rectangle_int_t *paint_extents) +static void +_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip) { - cairo_analysis_surface_t *surface = abstract_surface; - cairo_status_t status, backend_status; - cairo_rectangle_int_t extents; + const cairo_rectangle_int_t *clip_extents; cairo_bool_t is_empty; - if (!surface->target->backend->paint) - backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - else - backend_status = (*surface->target->backend->paint) (surface->target, op, - source, NULL); + clip_extents = NULL; + if (clip != NULL) + clip_extents = _cairo_clip_get_extents (clip); - if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) - backend_status = _analyze_meta_surface_pattern (surface, source); + if (clip_extents != NULL) + is_empty = _cairo_rectangle_intersect (extents, clip_extents); +} - status = _cairo_surface_get_extents (&surface->base, &extents); - if (_cairo_status_is_error (status)) - return status; +static void +_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_clip_t *clip, + cairo_rectangle_int_t *extents) +{ + cairo_bool_t is_empty; + + is_empty = _cairo_surface_get_extents (&surface->base, extents); if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - - is_empty = _cairo_rectangle_intersect (&extents, &source_extents); + _cairo_pattern_get_extents (source, &source_extents); + is_empty = _cairo_rectangle_intersect (extents, &source_extents); } - is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip); - if (paint_extents) - *paint_extents = extents; - - status = _add_operation (surface, &extents, backend_status); - - return status; + _rectangle_intersect_clip (extents, clip); } static cairo_int_status_t -_cairo_analysis_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - cairo_rectangle_int_t *mask_extents) +_cairo_analysis_surface_paint (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; - cairo_int_status_t status, backend_status; + cairo_status_t backend_status; + cairo_rectangle_int_t extents; + + if (surface->target->backend->paint == NULL) { + backend_status = CAIRO_INT_STATUS_UNSUPPORTED; + } else { + backend_status = + surface->target->backend->paint (surface->target, + op, source, clip); + if (_cairo_status_is_error (backend_status)) + return backend_status; + } + + if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) + backend_status = _analyze_meta_surface_pattern (surface, source); + + _cairo_analysis_surface_operation_extents (surface, + op, source, clip, + &extents); + + return _add_operation (surface, &extents, backend_status); +} + +static cairo_int_status_t +_cairo_analysis_surface_mask (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_pattern_t *mask, + cairo_clip_t *clip) +{ + cairo_analysis_surface_t *surface = abstract_surface; + cairo_int_status_t backend_status; cairo_rectangle_int_t extents; cairo_bool_t is_empty; - if (!surface->target->backend->mask) + if (surface->target->backend->mask == NULL) { backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - else - backend_status = (*surface->target->backend->mask) (surface->target, op, - source, mask, NULL); + } else { + backend_status = + surface->target->backend->mask (surface->target, + op, source, mask, clip); + if (_cairo_status_is_error (backend_status)) + return backend_status; + } if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) { cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS; @@ -395,37 +376,19 @@ _cairo_analysis_surface_mask (void *abstract_surface, backend_mask_status); } - status = _cairo_surface_get_extents (&surface->base, &extents); - if (_cairo_status_is_error (status)) - return status; - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int_t source_extents; - - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - - is_empty = _cairo_rectangle_intersect (&extents, &source_extents); - } + _cairo_analysis_surface_operation_extents (surface, + op, source, clip, + &extents); if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t mask_extents; - status = _cairo_pattern_get_extents (mask, &mask_extents); - if (unlikely (status)) - return status; - + _cairo_pattern_get_extents (mask, &mask_extents); is_empty = _cairo_rectangle_intersect (&extents, &mask_extents); + } - is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip); - if (mask_extents) - *mask_extents = extents; - - status = _add_operation (surface, &extents, backend_status); - - return status; + return _add_operation (surface, &extents, backend_status); } static cairo_int_status_t @@ -438,55 +401,61 @@ _cairo_analysis_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *stroke_extents) + cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; - cairo_status_t status, backend_status; + cairo_status_t backend_status; cairo_rectangle_int_t extents; cairo_bool_t is_empty; - if (!surface->target->backend->stroke) + if (surface->target->backend->stroke == NULL) { backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - else - backend_status = (*surface->target->backend->stroke) (surface->target, op, - source, path, style, - ctm, ctm_inverse, - tolerance, antialias, NULL); + } else { + backend_status = + surface->target->backend->stroke (surface->target, op, + source, path, style, + ctm, ctm_inverse, + tolerance, antialias, + clip); + if (_cairo_status_is_error (backend_status)) + return backend_status; + } if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) backend_status = _analyze_meta_surface_pattern (surface, source); - status = _cairo_surface_get_extents (&surface->base, &extents); - if (_cairo_status_is_error (status)) - return status; - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int_t source_extents; - - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - - is_empty = _cairo_rectangle_intersect (&extents, &source_extents); - } - - is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip); + _cairo_analysis_surface_operation_extents (surface, + op, source, clip, + &extents); if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t mask_extents; - _cairo_path_fixed_approximate_stroke_extents (path, - style, ctm, - &mask_extents); + /* If the backend can handle the stroke, then mark the approximate + * extents of the operation. However, if we need to fallback in order + * to draw the stroke, then ensure that the fallback is as tight as + * possible -- both to minimise output file size and to ensure good + * quality printed output for neighbouring regions. + */ + if (backend_status == CAIRO_STATUS_SUCCESS) { + _cairo_path_fixed_approximate_stroke_extents (path, + style, ctm, + &mask_extents); + } else { + cairo_status_t status; + + status = _cairo_path_fixed_stroke_extents (path, style, + ctm, ctm_inverse, + tolerance, + &mask_extents); + if (unlikely (status)) + return status; + } is_empty = _cairo_rectangle_intersect (&extents, &mask_extents); } - if (stroke_extents) - *stroke_extents = extents; - status = _add_operation (surface, &extents, backend_status); - - return status; + return _add_operation (surface, &extents, backend_status); } static cairo_int_status_t @@ -497,53 +466,49 @@ _cairo_analysis_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *fill_extents) + cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; - cairo_status_t status, backend_status; + cairo_status_t backend_status; cairo_rectangle_int_t extents; cairo_bool_t is_empty; - if (!surface->target->backend->fill) + if (surface->target->backend->fill == NULL) { backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - else - backend_status = (*surface->target->backend->fill) (surface->target, op, - source, path, fill_rule, - tolerance, antialias, NULL); + } else { + backend_status = + surface->target->backend->fill (surface->target, op, + source, path, fill_rule, + tolerance, antialias, + clip); + if (_cairo_status_is_error (backend_status)) + return backend_status; + } if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) backend_status = _analyze_meta_surface_pattern (surface, source); - status = _cairo_surface_get_extents (&surface->base, &extents); - if (_cairo_status_is_error (status)) - return status; - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int_t source_extents; - - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - - is_empty = _cairo_rectangle_intersect (&extents, &source_extents); - } - - is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip); + _cairo_analysis_surface_operation_extents (surface, + op, source, clip, + &extents); if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t mask_extents; - _cairo_path_fixed_approximate_fill_extents (path, - &mask_extents); - + /* We want speed for the likely case where the operation can be + * performed natively, but accuracy if we have to resort to + * using images. + */ + if (backend_status == CAIRO_STATUS_SUCCESS) { + _cairo_path_fixed_approximate_fill_extents (path, &mask_extents); + } else { + _cairo_path_fixed_fill_extents (path, fill_rule, tolerance, + &mask_extents); + } is_empty = _cairo_rectangle_intersect (&extents, &mask_extents); } - if (fill_extents) - *fill_extents = extents; - status = _add_operation (surface, &extents, backend_status); - - return status; + return _add_operation (surface, &extents, backend_status); } static cairo_int_status_t @@ -553,8 +518,8 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *show_glyphs_extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_analysis_surface_t *surface = abstract_surface; cairo_status_t status, backend_status; @@ -562,41 +527,42 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface, cairo_bool_t is_empty; /* Adapted from _cairo_surface_show_glyphs */ - if (surface->target->backend->show_glyphs) - backend_status = (*surface->target->backend->show_glyphs) (surface->target, op, - source, - glyphs, num_glyphs, - scaled_font, - remaining_glyphs, NULL); - else if (surface->target->backend->show_text_glyphs) - backend_status = surface->target->backend->show_text_glyphs (surface->target, op, - source, - NULL, 0, - glyphs, num_glyphs, - NULL, 0, - FALSE, - scaled_font, NULL); + if (surface->target->backend->show_glyphs != NULL) { + backend_status = + surface->target->backend->show_glyphs (surface->target, op, + source, + glyphs, num_glyphs, + scaled_font, + clip, + remaining_glyphs); + if (_cairo_status_is_error (backend_status)) + return backend_status; + } + else if (surface->target->backend->show_text_glyphs != NULL) + { + backend_status = + surface->target->backend->show_text_glyphs (surface->target, op, + source, + NULL, 0, + glyphs, num_glyphs, + NULL, 0, + FALSE, + scaled_font, + clip); + if (_cairo_status_is_error (backend_status)) + return backend_status; + } else + { backend_status = CAIRO_INT_STATUS_UNSUPPORTED; + } if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) backend_status = _analyze_meta_surface_pattern (surface, source); - status = _cairo_surface_get_extents (&surface->base, &extents); - if (_cairo_status_is_error (status)) - return status; - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int_t source_extents; - - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - - is_empty = _cairo_rectangle_intersect (&extents, &source_extents); - } - - is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip); + _cairo_analysis_surface_operation_extents (surface, + op, source, clip, + &extents); if (_cairo_operator_bounded_by_mask (op)) { status = _cairo_scaled_font_glyph_device_extents (scaled_font, @@ -608,12 +574,8 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface, is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents); } - if (show_glyphs_extents) - *show_glyphs_extents = extents; - status = _add_operation (surface, &extents, backend_status); - - return status; + return _add_operation (surface, &extents, backend_status); } static cairo_bool_t @@ -636,7 +598,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *show_text_glyphs_extents) + cairo_clip_t *clip) { cairo_analysis_surface_t *surface = abstract_surface; cairo_status_t status, backend_status; @@ -645,20 +607,33 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, /* Adapted from _cairo_surface_show_glyphs */ backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - if (surface->target->backend->show_text_glyphs) - backend_status = surface->target->backend->show_text_glyphs (surface->target, op, - source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, cluster_flags, - scaled_font, NULL); - if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED && surface->target->backend->show_glyphs) { + if (surface->target->backend->show_text_glyphs != NULL) { + backend_status = + surface->target->backend->show_text_glyphs (surface->target, op, + source, + utf8, utf8_len, + glyphs, num_glyphs, + clusters, num_clusters, + cluster_flags, + scaled_font, + clip); + if (_cairo_status_is_error (backend_status)) + return backend_status; + } + if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED && + surface->target->backend->show_glyphs != NULL) + { int remaining_glyphs = num_glyphs; - backend_status = surface->target->backend->show_glyphs (surface->target, op, - source, - glyphs, num_glyphs, - scaled_font, - &remaining_glyphs, NULL); + backend_status = + surface->target->backend->show_glyphs (surface->target, op, + source, + glyphs, num_glyphs, + scaled_font, + clip, + &remaining_glyphs); + if (_cairo_status_is_error (backend_status)) + return backend_status; + glyphs += num_glyphs - remaining_glyphs; num_glyphs = remaining_glyphs; if (remaining_glyphs == 0) @@ -668,21 +643,9 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) backend_status = _analyze_meta_surface_pattern (surface, source); - status = _cairo_surface_get_extents (&surface->base, &extents); - if (_cairo_status_is_error (status)) - return status; - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int_t source_extents; - - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - - is_empty = _cairo_rectangle_intersect (&extents, &source_extents); - } - - is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip); + _cairo_analysis_surface_operation_extents (surface, + op, source, clip, + &extents); if (_cairo_operator_bounded_by_mask (op)) { status = _cairo_scaled_font_glyph_device_extents (scaled_font, @@ -694,12 +657,8 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents); } - if (show_text_glyphs_extents) - *show_text_glyphs_extents = extents; - status = _add_operation (surface, &extents, backend_status); - - return status; + return _add_operation (surface, &extents, backend_status); } static const cairo_surface_backend_t cairo_analysis_surface_backend = { @@ -718,8 +677,6 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - _cairo_analysis_surface_intersect_clip_path, _cairo_analysis_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -734,7 +691,6 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = { _cairo_analysis_surface_show_glyphs, NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ @@ -743,9 +699,7 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = { }; cairo_surface_t * -_cairo_analysis_surface_create (cairo_surface_t *target, - int width, - int height) +_cairo_analysis_surface_create (cairo_surface_t *target) { cairo_analysis_surface_t *surface; cairo_status_t status; @@ -763,8 +717,6 @@ _cairo_analysis_surface_create (cairo_surface_t *target, _cairo_surface_init (&surface->base, &cairo_analysis_surface_backend, CAIRO_CONTENT_COLOR_ALPHA); - surface->width = width; - surface->height = height; cairo_matrix_init_identity (&surface->ctm); surface->has_ctm = FALSE; @@ -781,24 +733,12 @@ _cairo_analysis_surface_create (cairo_surface_t *target, surface->page_bbox.p2.x = 0; surface->page_bbox.p2.y = 0; - if (width == -1 && height == -1) { - surface->current_clip.x = CAIRO_RECT_INT_MIN; - surface->current_clip.y = CAIRO_RECT_INT_MIN; - surface->current_clip.width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; - surface->current_clip.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; - } else { - surface->current_clip.x = 0; - surface->current_clip.y = 0; - surface->current_clip.width = width; - surface->current_clip.height = height; - } - return &surface->base; } void _cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface, - cairo_matrix_t *ctm) + const cairo_matrix_t *ctm) { cairo_analysis_surface_t *surface; @@ -808,7 +748,7 @@ _cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface, surface = (cairo_analysis_surface_t *) abstract_surface; surface->ctm = *ctm; - surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm); + surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm); } void @@ -871,22 +811,18 @@ _return_success (void) } /* These typedefs are just to silence the compiler... */ -typedef cairo_int_status_t -(*_set_clip_region_func) (void *surface, - cairo_region_t *region); - typedef cairo_int_status_t (*_paint_func) (void *surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_mask_func) (void *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_stroke_func) (void *surface, @@ -898,7 +834,7 @@ typedef cairo_int_status_t cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_fill_func) (void *surface, @@ -908,7 +844,7 @@ typedef cairo_int_status_t cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_show_glyphs_func) (void *surface, @@ -917,8 +853,8 @@ typedef cairo_int_status_t cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip, + int *remaining_glyphs); static const cairo_surface_backend_t cairo_null_surface_backend = { CAIRO_INTERNAL_SURFACE_TYPE_NULL, @@ -937,8 +873,6 @@ static const cairo_surface_backend_t cairo_null_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - (_set_clip_region_func) _return_success, /* set_clip_region */ - NULL, /* intersect_clip_path */ NULL, /* get_extents */ NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -953,7 +887,6 @@ static const cairo_surface_backend_t cairo_null_surface_backend = { (_show_glyphs_func) _return_success, /* show_glyphs */ NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ diff --git a/src/cairo-beos-surface.cpp b/src/cairo-beos-surface.cpp index e527272e6..6fbdc470e 100644 --- a/src/cairo-beos-surface.cpp +++ b/src/cairo-beos-surface.cpp @@ -56,6 +56,8 @@ struct cairo_beos_surface_t { cairo_surface_t base; + cairo_region_t *clip_region; + BView* view; /* @@ -70,7 +72,6 @@ struct cairo_beos_surface_t { BBitmap* bitmap; - // If true, surface and view should be deleted when this surface is // destroyed bool owns_bitmap_view; @@ -101,27 +102,28 @@ _cairo_beos_surface_create_internal (BView* view, BBitmap* bmp, bool owns_bitmap_view = false); -static BRect -_cairo_rect_to_brect (const cairo_rectangle_int16_t* rect) +static inline BRect +_cairo_rectangle_to_brect (const cairo_rectangle_int_t* rect) { // A BRect is one pixel wider than you'd think - return BRect(rect->x, rect->y, rect->x + rect->width - 1, - rect->y + rect->height - 1); + return BRect (rect->x, rect->y, + rect->x + rect->width - 1, + rect->y + rect->height - 1); } -static cairo_rectangle_int16_t -_brect_to_cairo_rect (const BRect& rect) +static inline cairo_rectangle_int_t +_brect_to_cairo_rectangle (const BRect &rect) { - cairo_rectangle_int16_t retval; - retval.x = int(rect.left + 0.5); - retval.y = int(rect.top + 0.5); - retval.width = rect.IntegerWidth() + 1; - retval.height = rect.IntegerHeight() + 1; + cairo_rectangle_int_t retval; + retval.x = floor (rect.left); + retval.y = floor (rect.top); + retval.width = ceil (rect.right) - retval.x + 1; + retval.height = ceil (rect.bottom) - rectval.y + 1; return retval; } -static rgb_color -_cairo_color_to_be_color (const cairo_color_t* color) +static inline rgb_color +_cairo_color_to_be_color (const cairo_color_t *color) { // This factor ensures a uniform distribution of numbers const float factor = 256 - 1e-5; @@ -199,32 +201,8 @@ _cairo_beos_view_to_bitmap (BView* view, return ERROR; } -inline unsigned char -unpremultiply (unsigned char color, - unsigned char alpha) -{ - if (alpha == 0) - return 0; - // plus alpha/2 to round instead of truncate - return (color * 255 + alpha / 2) / alpha; -} - -inline unsigned char -premultiply (unsigned char color, - unsigned char alpha) -{ - // + 127 to round, instead of truncate - return (color * alpha + 127) / 255; -} - -/** - * unpremultiply_rgba: - * - * Takes an input in ABGR premultiplied image data and unmultiplies it. - * The result is stored in retdata. - **/ static void -unpremultiply_rgba (unsigned char* data, +unpremultiply_bgra (unsigned char* data, int width, int height, int stride, @@ -235,52 +213,108 @@ unpremultiply_rgba (unsigned char* data, in < end; in += stride, out += stride) { - for (int i = 0; i < width; ++i) { - // XXX for a big-endian platform this'd have to change - int idx = 4 * i; - unsigned char alpha = in[idx + 3]; - out[idx + 0] = unpremultiply(in[idx + 0], alpha); // B - out[idx + 1] = unpremultiply(in[idx + 1], alpha); // G - out[idx + 2] = unpremultiply(in[idx + 2], alpha); // R - out[idx + 3] = in[idx + 3]; // Alpha + for (int i = 0; i < width; i ++) { + uint8_t *b = &out[4*i]; + uint32_t pixel; + uint8_t alpha; + + memcpy (&pixel, &data[4*i], sizeof (uint32_t)); + alpha = pixel & 0xff; + if (alpha == 0) { + b[0] = b[1] = b[2] = b[3] = 0; + } else { + b[0] = (((pixel >> 24) & 0xff) * 255 + alpha / 2) / alpha; + b[1] = (((pixel >> 16) & 0xff) * 255 + alpha / 2) / alpha; + b[2] = (((pixel >> 8) & 0xff) * 255 + alpha / 2) / alpha; + b[3] = alpha; + } } } } -/** - * premultiply_rgba: - * - * Takes an input in ABGR non-premultiplied image data and premultiplies it. - * The returned data must be freed with free(). - **/ +static inline int +multiply_alpha (int alpha, int color) +{ + int temp = (alpha * color) + 0x80; + return ((temp + (temp >> 8)) >> 8); +} + static unsigned char* -premultiply_rgba (unsigned char* data, +premultiply_bgra (unsigned char* data, int width, int height, int stride) { - unsigned char* retdata = reinterpret_cast(_cairo_malloc_ab(height, stride)); + uint8_t * retdata = reinterpret_cast(_cairo_malloc_ab(height, stride)); if (!retdata) return NULL; - unsigned char* end = data + stride * height; - for (unsigned char* in = data, *out = retdata; + uint8_t * end = data + stride * height; + for (uint8_t * in = data, *out = retdata; in < end; in += stride, out += stride) { - for (int i = 0; i < width; ++i) { - // XXX for a big-endian platform this'd have to change - int idx = 4 * i; - unsigned char alpha = in[idx + 3]; - out[idx + 0] = premultiply(in[idx + 0], alpha); // B - out[idx + 1] = premultiply(in[idx + 1], alpha); // G - out[idx + 2] = premultiply(in[idx + 2], alpha); // R - out[idx + 3] = in[idx + 3]; // Alpha + for (int i = 0; i < width; i ++) { + uint8_t *base = &in[4*i]; + uint8_t alpha = base[3]; + uint32_t p; + + if (alpha == 0) { + p = 0; + } else { + uint8_t blue = base[0]; + uint8_t green = base[1]; + uint8_t red = base[2]; + + if (alpha != 0xff) { + blue = multiply_alpha (alpha, blue); + green = multiply_alpha (alpha, green); + red = multiply_alpha (alpha, red); + } + p = (alpha << 0) | (red << 8) | (green << 16) | (blue << 24); + } + memcpy (&out[4*i], &p, sizeof (uint32_t)); } } return retdata; } +static cairo_int_status_t +_cairo_beos_surface_set_clip_region (cairo_beos_surface_t *surface, + cairo_region_t *region) +{ + cairo_beos_surface_t *surface = reinterpret_cast( + abstract_surface); + AutoLockView locker(surface->view); + assert (locker); + + if (region == surface->clip_region) + return CAIRO_INT_STATUS_SUCCESS; + + cairo_region_destroy (surface->clip_region); + surface->clip_region = cairo_region_reference (region); + + if (region == NULL) { + // No clipping + surface->view->ConstrainClippingRegion(NULL); + return CAIRO_INT_STATUS_SUCCESS; + } + + int count = cairo_region_num_rectangles (region); + BRegion bregion; + for (int i = 0; i < count; ++i) { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (region, i, &rect); + // Have to substract one, because for pixman, the second coordinate + // lies outside the rectangle. + bregion.Include (_cairo_rectangle_to_brect (&rect)); + } + surface->view->ConstrainClippingRegion(&bregion); + return CAIRO_INT_STATUS_SUCCESS; +} + + /** * _cairo_beos_bitmap_to_surface: * @@ -309,8 +343,8 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap) return imgsurf; } - cairo_format_t cformat = format == B_RGB32 ? CAIRO_FORMAT_RGB24 - : CAIRO_FORMAT_ARGB32; + cairo_format_t cformat = format == B_RGB32 ? + CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32; BRect bounds(bitmap->Bounds()); unsigned char* bits = reinterpret_cast(bitmap->Bits()); @@ -318,8 +352,8 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap) int height = bounds.IntegerHeight() + 1; unsigned char* premultiplied; if (cformat == CAIRO_FORMAT_ARGB32) { - premultiplied = premultiply_rgba(bits, width, height, - bitmap->BytesPerRow()); + premultiplied = premultiply_bgra (bits, width, height, + bitmap->BytesPerRow()); } else { premultiplied = reinterpret_cast( _cairo_malloc_ab(bitmap->BytesPerRow(), height)); @@ -327,7 +361,7 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap) memcpy(premultiplied, bits, bitmap->BytesPerRow() * height); } if (!premultiplied) - return NULL; + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); cairo_image_surface_t* surf = reinterpret_cast (cairo_image_surface_create_for_data(premultiplied, @@ -355,11 +389,11 @@ _cairo_image_surface_to_bitmap (cairo_image_surface_t* surface) switch (surface->format) { case CAIRO_FORMAT_ARGB32: { BBitmap* data = new BBitmap(size, B_RGBA32); - unpremultiply_rgba(surface->data, - surface->width, - surface->height, - surface->stride, - reinterpret_cast(data->Bits())); + unpremultiply_bgra (surface->data, + surface->width, + surface->height, + surface->stride, + reinterpret_cast(data->Bits())); return data; } case CAIRO_FORMAT_RGB24: { @@ -384,44 +418,44 @@ _cairo_op_to_be_op (cairo_operator_t cairo_op, drawing_mode* beos_op) { switch (cairo_op) { + case CAIRO_OPERATOR_SOURCE: + *beos_op = B_OP_COPY; + return true; + case CAIRO_OPERATOR_OVER: + *beos_op = B_OP_ALPHA; + return true; - case CAIRO_OPERATOR_SOURCE: - *beos_op = B_OP_COPY; - return true; - case CAIRO_OPERATOR_OVER: - *beos_op = B_OP_ALPHA; - return true; - - case CAIRO_OPERATOR_ADD: - // Does not actually work + case CAIRO_OPERATOR_ADD: + // Does not actually work + // XXX This is a fundamental compositing operator, it has to work! #if 1 - return false; + return false; #else - *beos_op = B_OP_ADD; - return true; + *beos_op = B_OP_ADD; + return true; #endif - case CAIRO_OPERATOR_CLEAR: - // Does not map to B_OP_ERASE - it replaces the dest with the low - // color, instead of transparency; could be done by setting low - // color appropriately. + case CAIRO_OPERATOR_CLEAR: + // Does not map to B_OP_ERASE - it replaces the dest with the low + // color, instead of transparency; could be done by setting low + // color appropriately. - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_ATOP: + case CAIRO_OPERATOR_IN: + case CAIRO_OPERATOR_OUT: + case CAIRO_OPERATOR_ATOP: - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_DEST_ATOP: + case CAIRO_OPERATOR_DEST: + case CAIRO_OPERATOR_DEST_OVER: + case CAIRO_OPERATOR_DEST_IN: + case CAIRO_OPERATOR_DEST_OUT: + case CAIRO_OPERATOR_DEST_ATOP: - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_SATURATE: + case CAIRO_OPERATOR_XOR: + case CAIRO_OPERATOR_SATURATE: - default: - return false; - }; + default: + return false; + } } static cairo_surface_t * @@ -430,8 +464,6 @@ _cairo_beos_surface_create_similar (void *abstract_surface, int width, int height) { - fprintf(stderr, "Creating similar\n"); - cairo_beos_surface_t *surface = reinterpret_cast( abstract_surface); @@ -444,9 +476,7 @@ _cairo_beos_surface_create_similar (void *abstract_surface, BBitmap* bmp; switch (content) { case CAIRO_CONTENT_ALPHA: - // Can't support this natively - return _cairo_image_surface_create_with_content(content, width, - height); + return NULL; case CAIRO_CONTENT_COLOR_ALPHA: bmp = new BBitmap(rect, B_RGBA32, true); break; @@ -470,10 +500,9 @@ _cairo_beos_surface_create_similar (void *abstract_surface, } break; default: - assert(0); + ASSERT_NOT_REACHED; return NULL; - - }; + } BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0); bmp->AddChild(view); return _cairo_beos_surface_create_internal(view, bmp, true); @@ -495,6 +524,8 @@ _cairo_beos_surface_finish (void *abstract_surface) surface->bitmap = NULL; } + cairo_region_destroy (surface->clip_region); + return CAIRO_STATUS_SUCCESS; } @@ -503,7 +534,6 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa cairo_image_surface_t **image_out, void **image_extra) { - fprintf(stderr, "Getting source image\n"); cairo_beos_surface_t *surface = reinterpret_cast( abstract_surface); AutoLockView locker(surface->view); @@ -514,9 +544,9 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa surface->view->Sync(); if (surface->bitmap) { - *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap); - if (!*image_out) - return CAIRO_STATUS_NO_MEMORY; + *image_out = _cairo_beos_bitmap_to_surface (surface->bitmap); + if (unlikely ((*image_out)->base.status)) + return (*image_out)->base.status; *image_extra = NULL; return CAIRO_STATUS_SUCCESS; @@ -526,10 +556,10 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK) return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE - *image_out = _cairo_beos_bitmap_to_surface(bmp); - if (!*image_out) { + *image_out = _cairo_beos_bitmap_to_surface (bmp); + if (unlikely ((*image_out)->base.status)) { delete bmp; - return CAIRO_STATUS_NO_MEMORY; + return (*image_out)->base.status; } *image_extra = bmp; @@ -543,17 +573,17 @@ _cairo_beos_surface_release_source_image (void *abstract_surfac { cairo_surface_destroy (&image->base); - BBitmap* bmp = static_cast(image_extra); - delete bmp; + if (image_extra != NULL) { + BBitmap* bmp = static_cast(image_extra); + delete bmp; + } } - - static cairo_status_t _cairo_beos_surface_acquire_dest_image (void *abstract_surface, - cairo_rectangle_int16_t *interest_rect, + cairo_rectangle_int_t *interest_rect, cairo_image_surface_t **image_out, - cairo_rectangle_int16_t *image_rect, + cairo_rectangle_int_t *image_rect, void **image_extra) { cairo_beos_surface_t *surface = reinterpret_cast( @@ -563,14 +593,14 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface, if (!locker) { *image_out = NULL; *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; + return (cairo_status_t) CAIRO_INT_STATUS_NOTHING_TO_DO; } if (surface->bitmap) { surface->view->Sync(); *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap); - if (!*image_out) - return CAIRO_STATUS_NO_MEMORY; + if (unlikely ((*image_out)->base.status)) + return (*image_out)->base.status; image_rect->x = 0; image_rect->y = 0; @@ -581,7 +611,7 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } - BRect b_interest_rect(_cairo_rect_to_brect(interest_rect)); + BRect b_interest_rect (_cairo_rectangle_to_brect (interest_rect)); BRect rect; BBitmap* bitmap; @@ -595,18 +625,11 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface, if (status == ERROR) return CAIRO_STATUS_NO_MEMORY; - *image_rect = _brect_to_cairo_rect(rect); - -#if 0 - fprintf(stderr, "Requested: (cairo rects) (%ix%i) dim (%u, %u) returning (%ix%i) dim (%u, %u)\n", - interest_rect->x, interest_rect->y, interest_rect->width, interest_rect->height, - image_rect->x, image_rect->y, image_rect->width, image_rect->height); -#endif - + *image_rect = _brect_to_cairo_rectangle(rect); *image_out = _cairo_beos_bitmap_to_surface(bitmap); delete bitmap; - if (!*image_out) - return CAIRO_STATUS_NO_MEMORY; + if (unlikely ((*image_out)->base.status)) + return (*image_out)->base.status; *image_extra = NULL; @@ -616,13 +639,11 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface, static void _cairo_beos_surface_release_dest_image (void *abstract_surface, - cairo_rectangle_int16_t *intersect_rect, + cairo_rectangle_int_t *intersect_rect, cairo_image_surface_t *image, - cairo_rectangle_int16_t *image_rect, + cairo_rectangle_int_t *image_rect, void *image_extra) { - fprintf(stderr, "Fallback drawing\n"); - cairo_beos_surface_t *surface = reinterpret_cast( abstract_surface); @@ -634,9 +655,9 @@ _cairo_beos_surface_release_dest_image (void *abstract_surface, surface->view->PushState(); surface->view->SetDrawingMode(B_OP_COPY); - BRect rect(_cairo_rect_to_brect(image_rect)); - surface->view->DrawBitmap(bitmap_to_draw, rect); + surface->view->DrawBitmap (bitmap_to_draw, + _cairo_rectangle_to_brect (image_rect)); surface->view->PopState(); @@ -649,17 +670,19 @@ _cairo_beos_surface_composite (cairo_operator_t op, cairo_pattern_t *src, cairo_pattern_t *mask, void *dst, - int src_x, + int src_x, int src_y, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_beos_surface_t *surface = reinterpret_cast( dst); + cairo_int_status_t status; AutoLockView locker(surface->view); if (!locker) return CAIRO_INT_STATUS_SUCCESS; @@ -684,6 +707,10 @@ _cairo_beos_surface_composite (cairo_operator_t op, if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity)) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_beos_surface_set_clip_region (surface, clip_region); + if (unlikely (status)) + return status; + BRect srcRect(src_x + itx, src_y + ity, src_x + itx + width - 1, @@ -731,8 +758,6 @@ _cairo_beos_surface_composite (cairo_operator_t op, return CAIRO_INT_STATUS_UNSUPPORTED; } - fprintf(stderr, "Composite\n"); - // Draw it on screen. surface->view->PushState(); @@ -767,24 +792,17 @@ _cairo_beos_surface_composite (cairo_operator_t op, } -static void -_cairo_beos_surface_fill_rectangle (cairo_beos_surface_t *surface, - cairo_rectangle_int16_t *rect) -{ - BRect brect(_cairo_rect_to_brect(rect)); - surface->view->FillRect(brect); -} - static cairo_int_status_t _cairo_beos_surface_fill_rectangles (void *abstract_surface, cairo_operator_t op, const cairo_color_t *color, - cairo_rectangle_int16_t *rects, - int num_rects) + cairo_rectangle_int_t *rects, + int num_rects, + cairo_region_t *clip_region) { - fprintf(stderr, "Drawing %i rectangles\n", num_rects); cairo_beos_surface_t *surface = reinterpret_cast( abstract_surface); + cairo_int_status_t status; if (num_rects <= 0) return CAIRO_INT_STATUS_SUCCESS; @@ -797,6 +815,10 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface, if (!_cairo_op_to_be_op(op, &mode)) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_beos_surface_set_clip_region (surface, clip_region); + if (unlikely (status)) + return status; + rgb_color be_color = _cairo_color_to_be_color(color); if (mode == B_OP_ALPHA && be_color.alpha == 0xFF) @@ -808,9 +830,9 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface, if (mode == B_OP_COPY && be_color.alpha != 0xFF && (!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32)) { - be_color.red = premultiply(be_color.red, be_color.alpha); - be_color.green = premultiply(be_color.green, be_color.alpha); - be_color.blue = premultiply(be_color.blue, be_color.alpha); + be_color.red = color->red_short >> 8; + be_color.green = color->green_short >> 8; + be_color.blue = color->blue_short >> 8; } surface->view->PushState(); @@ -822,65 +844,26 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface, else surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); - for (int i = 0; i < num_rects; ++i) { - _cairo_beos_surface_fill_rectangle(surface, &rects[i]); - } + for (int i = 0; i < num_rects; ++i) + surface->view->FillRect (_cairo_rectangle_to_brect (&rects[i])); surface->view->PopState(); return CAIRO_INT_STATUS_SUCCESS; } - - -static cairo_int_status_t -_cairo_beos_surface_set_clip_region (void *abstract_surface, - pixman_region16_t *region) -{ - fprintf(stderr, "Setting clip region\n"); - cairo_beos_surface_t *surface = reinterpret_cast( - abstract_surface); - AutoLockView locker(surface->view); - if (!locker) - return CAIRO_INT_STATUS_SUCCESS; - - if (region == NULL) { - // No clipping - surface->view->ConstrainClippingRegion(NULL); - return CAIRO_INT_STATUS_SUCCESS; - } - - int count = pixman_region_num_rects(region); - pixman_box16_t* rects = pixman_region_rects(region); - BRegion bregion; - for (int i = 0; i < count; ++i) { - // Have to substract one, because for pixman, the second coordinate - // lies outside the rectangle. - bregion.Include(BRect(rects[i].x1, rects[i].y1, rects[i].x2 - 1, rects[i].y2 - 1)); - } - surface->view->ConstrainClippingRegion(&bregion); - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t +static cairo_bool_t _cairo_beos_surface_get_extents (void *abstract_surface, - cairo_rectangle_int16_t *rectangle) + cairo_rectangle_int_t *rectangle) { cairo_beos_surface_t *surface = reinterpret_cast( abstract_surface); AutoLockView locker(surface->view); if (!locker) - return CAIRO_INT_STATUS_UNSUPPORTED; + return FALSE; - BRect size = surface->view->Bounds(); - - *rectangle = _brect_to_cairo_rect(size); - - // Make sure to have our upperleft edge as (0,0) - rectangle->x = 0; - rectangle->y = 0; - - return CAIRO_INT_STATUS_SUCCESS; + *rectangle = _brect_to_cairo_rectangle (surface->view->Bounds()); + return TRUE; } static const struct _cairo_surface_backend cairo_beos_surface_backend = { @@ -899,8 +882,6 @@ static const struct _cairo_surface_backend cairo_beos_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - _cairo_beos_surface_set_clip_region, - NULL, /* intersect_clip_path */ _cairo_beos_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -938,7 +919,9 @@ _cairo_beos_surface_create_internal (BView* view, surface->bitmap = bmp; surface->owns_bitmap_view = owns_bitmap_view; - return (cairo_surface_t *) surface; + surface->clip_region = NULL; + + return &surface->base; } /** diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h index 4229e4fb9..8a3e867ab 100644 --- a/src/cairo-clip-private.h +++ b/src/cairo-clip-private.h @@ -43,6 +43,11 @@ extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil; +enum { + CAIRO_CLIP_PATH_HAS_REGION = 0x1, + CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED = 0x2 +}; + struct _cairo_clip_path { cairo_reference_count_t ref_count; cairo_path_fixed_t path; @@ -50,84 +55,74 @@ struct _cairo_clip_path { double tolerance; cairo_antialias_t antialias; cairo_clip_path_t *prev; + + cairo_rectangle_int_t extents; + + /* partial caches */ + unsigned int flags; + cairo_region_t *region; + cairo_surface_t *surface; }; struct _cairo_clip { - cairo_clip_mode_t mode; + /* can be used as a cairo_hash_entry_t for live clips */ + cairo_clip_path_t *path; cairo_bool_t all_clipped; - /* - * Mask-based clipping for cases where the backend - * clipping isn't sufficiently able. - * - * The rectangle here represents the - * portion of the destination surface that this - * clip surface maps to, it does not - * represent the extents of the clip region or - * clip paths - */ - cairo_surface_t *surface; - cairo_rectangle_int_t surface_rect; - /* - * Surface clip serial number to store - * in the surface when this clip is set - */ - unsigned int serial; - /* - * A clip region that can be placed in the surface - */ - cairo_region_t *region; - /* - * If the surface supports path clipping, we store the list of - * clipping paths that has been set here as a linked list. - */ - cairo_clip_path_t *path; }; cairo_private void -_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target); +_cairo_clip_init (cairo_clip_t *clip); cairo_private cairo_status_t +_cairo_clip_init_rectangle (cairo_clip_t *clip, + const cairo_rectangle_int_t *rect); + +cairo_private void _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other); cairo_private cairo_status_t -_cairo_clip_init_deep_copy (cairo_clip_t *clip, - cairo_clip_t *other, - cairo_surface_t *target); +_cairo_clip_init_copy_transformed (cairo_clip_t *clip, + cairo_clip_t *other, + const cairo_matrix_t *matrix); cairo_private void _cairo_clip_reset (cairo_clip_t *clip); cairo_private cairo_status_t _cairo_clip_clip (cairo_clip_t *clip, - cairo_path_fixed_t *path, + const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, - cairo_antialias_t antialias, - cairo_surface_t *target); + cairo_antialias_t antialias); cairo_private cairo_status_t -_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, - cairo_rectangle_int_t *rectangle); +_cairo_clip_apply_clip (cairo_clip_t *clip, + const cairo_clip_t *other); -cairo_private cairo_status_t -_cairo_clip_intersect_to_region (cairo_clip_t *clip, - cairo_region_t *region); +cairo_private const cairo_rectangle_int_t * +_cairo_clip_get_extents (const cairo_clip_t *clip); -cairo_private cairo_status_t -_cairo_clip_combine_to_surface (cairo_clip_t *clip, - cairo_operator_t op, - cairo_surface_t *dst, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents); +cairo_private cairo_surface_t * +_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst); + +cairo_private cairo_int_status_t +_cairo_clip_get_region (cairo_clip_t *clip, + cairo_region_t **region); cairo_private void _cairo_clip_translate (cairo_clip_t *clip, cairo_fixed_t tx, cairo_fixed_t ty); +cairo_private void +_cairo_clip_transform (cairo_clip_t *clip, + const cairo_matrix_t *transform); + +cairo_private void +_cairo_clip_drop_cache (cairo_clip_t *clip); + cairo_private cairo_rectangle_list_t* _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate); diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 79e4cbe61..93348945d 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -3,6 +3,7 @@ * * Copyright © 2002 University of Southern California * Copyright © 2005 Red Hat, Inc. + * Copyright © 2009 Chris Wilson * * This library is free software; you can redistribute it and/or * modify it either under the terms of the GNU Lesser General Public @@ -35,255 +36,122 @@ * Contributor(s): * Carl D. Worth * Kristian Høgsberg + * Chris Wilson */ #include "cairoint.h" #include "cairo-clip-private.h" +#include "cairo-path-fixed-private.h" + +/* Keep a stash of recently freed clip_paths, since we need to + * reallocate them frequently. + */ +#define MAX_FREED_POOL_SIZE 4 +typedef struct { + void *pool[MAX_FREED_POOL_SIZE]; + int top; +} freed_pool_t; + +static freed_pool_t clip_path_pool; + +static void * +_atomic_fetch (void **slot) +{ + return _cairo_atomic_ptr_cmpxchg (slot, *slot, NULL); +} + +static cairo_bool_t +_atomic_store (void **slot, void *ptr) +{ + return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr) == NULL; +} + +static void * +_freed_pool_get (freed_pool_t *pool) +{ + void *ptr; + int i; + + i = pool->top - 1; + if (i < 0) + i = 0; + + ptr = _atomic_fetch (&pool->pool[i]); + if (ptr != NULL) { + pool->top = i; + return ptr; + } + + /* either empty or contended */ + for (i = ARRAY_LENGTH (pool->pool); i--;) { + ptr = _atomic_fetch (&pool->pool[i]); + if (ptr != NULL) { + pool->top = i; + return ptr; + } + } + + /* empty */ + pool->top = 0; + return NULL; +} + +static void +_freed_pool_put (freed_pool_t *pool, void *ptr) +{ + int i = pool->top; + + if (_atomic_store (&pool->pool[i], ptr)) { + pool->top = i + 1; + return; + } + + /* either full or contended */ + for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) { + if (_atomic_store (&pool->pool[i], ptr)) { + pool->top = i + 1; + return; + } + } + + /* full */ + pool->top = ARRAY_LENGTH (pool->pool); + free (ptr); +} + +static void +_freed_pool_reset (freed_pool_t *pool) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) { + free (pool->pool[i]); + pool->pool[i] = NULL; + } +} static cairo_clip_path_t * -_cairo_clip_path_reference (cairo_clip_path_t *clip_path); - -static void -_cairo_clip_path_destroy (cairo_clip_path_t *clip_path); - -void -_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target) -{ - if (target && target->backend) - clip->mode = _cairo_surface_get_clip_mode (target); - else - clip->mode = CAIRO_CLIP_MODE_MASK; - - clip->all_clipped = FALSE; - - clip->surface = NULL; - clip->surface_rect.x = 0; - clip->surface_rect.y = 0; - clip->surface_rect.width = 0; - clip->surface_rect.height = 0; - - clip->serial = 0; - - clip->region = NULL; - - clip->path = NULL; -} - -cairo_status_t -_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) -{ - clip->mode = other->mode; - - clip->all_clipped = other->all_clipped; - - clip->surface = cairo_surface_reference (other->surface); - clip->surface_rect = other->surface_rect; - - clip->serial = other->serial; - - if (other->region) { - cairo_status_t status; - - clip->region = cairo_region_copy (other->region); - - status = cairo_region_status (clip->region); - if (unlikely (status)) { - cairo_surface_destroy (clip->surface); - cairo_region_destroy (clip->region); - clip->region = NULL; - - return status; - } - } else { - clip->region = NULL; - } - - clip->path = _cairo_clip_path_reference (other->path); - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_clip_reset (cairo_clip_t *clip) -{ - clip->all_clipped = FALSE; - - /* destroy any existing clip-region artifacts */ - cairo_surface_destroy (clip->surface); - clip->surface = NULL; - - clip->serial = 0; - - if (clip->region) { - cairo_region_destroy (clip->region); - - clip->region = NULL; - } - - _cairo_clip_path_destroy (clip->path); - clip->path = NULL; -} - -static void -_cairo_clip_set_all_clipped (cairo_clip_t *clip, cairo_surface_t *target) -{ - _cairo_clip_reset (clip); - - clip->all_clipped = TRUE; - clip->serial = _cairo_surface_allocate_clip_serial (target); -} - - -static cairo_status_t -_cairo_clip_path_intersect_to_rectangle (cairo_clip_path_t *clip_path, - cairo_rectangle_int_t *rectangle) -{ - while (clip_path) { - cairo_rectangle_int_t extents; - - _cairo_path_fixed_approximate_clip_extents (&clip_path->path, &extents); - - if (! _cairo_rectangle_intersect (rectangle, &extents)) - return CAIRO_STATUS_SUCCESS; - - clip_path = clip_path->prev; - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, - cairo_rectangle_int_t *rectangle) -{ - cairo_status_t status; - cairo_bool_t is_empty; - - if (!clip) - return CAIRO_STATUS_SUCCESS; - - if (clip->all_clipped) { - *rectangle = clip->surface_rect; - return CAIRO_STATUS_SUCCESS; - } - - if (clip->path) { - status = _cairo_clip_path_intersect_to_rectangle (clip->path, - rectangle); - if (unlikely (status)) - return status; - } - - if (clip->region) { - cairo_rectangle_int_t extents; - - cairo_region_get_extents (clip->region, &extents); - is_empty = _cairo_rectangle_intersect (rectangle, &extents); - if (is_empty) - return CAIRO_STATUS_SUCCESS; - } - - if (clip->surface) - is_empty = _cairo_rectangle_intersect (rectangle, &clip->surface_rect); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_clip_intersect_to_region (cairo_clip_t *clip, - cairo_region_t *region) -{ - cairo_status_t status; - - if (!clip) - return CAIRO_STATUS_SUCCESS; - - if (clip->all_clipped) - return cairo_region_intersect_rectangle (region, &clip->surface_rect); - - if (clip->path) { - /* Intersect clip path into region. */ - } - - if (clip->region) { - status = cairo_region_intersect (region, clip->region); - if (unlikely (status)) - return status; - } - - if (clip->surface) - return cairo_region_intersect_rectangle (region, &clip->surface_rect); - - return CAIRO_STATUS_SUCCESS; -} - -/* Combines the region of clip->surface given by extents in - * device backend coordinates into the given temporary surface, - * which has its origin at dst_x, dst_y in backend coordinates - */ -cairo_status_t -_cairo_clip_combine_to_surface (cairo_clip_t *clip, - cairo_operator_t op, - cairo_surface_t *dst, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_pattern_t pattern; - cairo_status_t status; - - if (clip->all_clipped) - return CAIRO_STATUS_SUCCESS; - - _cairo_pattern_init_for_surface (&pattern, clip->surface); - - status = _cairo_surface_composite (op, - &pattern.base, - NULL, - dst, - extents->x - clip->surface_rect.x, - extents->y - clip->surface_rect.y, - 0, 0, - extents->x - dst_x, - extents->y - dst_y, - extents->width, extents->height); - - _cairo_pattern_fini (&pattern.base); - - return status; -} - -static cairo_status_t -_cairo_clip_intersect_path (cairo_clip_t *clip, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) +_cairo_clip_path_create (cairo_clip_t *clip) { cairo_clip_path_t *clip_path; - cairo_status_t status; - if (clip->mode != CAIRO_CLIP_MODE_PATH) - return CAIRO_INT_STATUS_UNSUPPORTED; - - clip_path = malloc (sizeof (cairo_clip_path_t)); - if (unlikely (clip_path == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_path_fixed_init_copy (&clip_path->path, path); - if (unlikely (status)) { - free (clip_path); - return status; + clip_path = _freed_pool_get (&clip_path_pool); + if (unlikely (clip_path == NULL)) { + clip_path = malloc (sizeof (cairo_clip_path_t)); + if (unlikely (clip_path == NULL)) + return NULL; } CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1); - clip_path->fill_rule = fill_rule; - clip_path->tolerance = tolerance; - clip_path->antialias = antialias; + + clip_path->flags = 0; + clip_path->region = NULL; + clip_path->surface = NULL; + clip_path->prev = clip->path; clip->path = clip_path; - return CAIRO_STATUS_SUCCESS; + return clip_path; } static cairo_clip_path_t * @@ -302,535 +170,643 @@ _cairo_clip_path_reference (cairo_clip_path_t *clip_path) static void _cairo_clip_path_destroy (cairo_clip_path_t *clip_path) { - if (clip_path == NULL) - return; - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count)); if (! _cairo_reference_count_dec_and_test (&clip_path->ref_count)) return; _cairo_path_fixed_fini (&clip_path->path); - _cairo_clip_path_destroy (clip_path->prev); - free (clip_path); + if (clip_path->region != NULL) + cairo_region_destroy (clip_path->region); + if (clip_path->surface != NULL) + cairo_surface_destroy (clip_path->surface); + + if (clip_path->prev != NULL) + _cairo_clip_path_destroy (clip_path->prev); + + _freed_pool_put (&clip_path_pool, clip_path); } - -static cairo_int_status_t -_cairo_clip_intersect_region (cairo_clip_t *clip, - cairo_traps_t *traps, - cairo_surface_t *target) +void +_cairo_clip_init (cairo_clip_t *clip) { - cairo_region_t *region; - cairo_int_status_t status; - - if (clip->all_clipped) - return CAIRO_STATUS_SUCCESS; - - if (clip->mode != CAIRO_CLIP_MODE_REGION) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_traps_extract_region (traps, ®ion); - if (status) - return status; - - if (clip->region) { - status = cairo_region_intersect (clip->region, region); - cairo_region_destroy (region); - } else { - clip->region = region; - } - - clip->serial = _cairo_surface_allocate_clip_serial (target); - - if (!clip->region || cairo_region_is_empty (clip->region)) - _cairo_clip_set_all_clipped (clip, target); - - return status; + clip->all_clipped = FALSE; + clip->path = NULL; } -static cairo_status_t -_cairo_clip_intersect_mask (cairo_clip_t *clip, - cairo_traps_t *traps, - cairo_antialias_t antialias, - cairo_surface_t *target) +static void +_cairo_clip_set_all_clipped (cairo_clip_t *clip) { - cairo_pattern_union_t pattern; - cairo_box_t extents; - cairo_rectangle_int_t surface_rect, target_rect; - cairo_surface_t *surface = NULL; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - if (clip->all_clipped) - return CAIRO_STATUS_SUCCESS; - - /* Represent the clip as a mask surface. We create a new surface - * the size of the intersection of the old mask surface and the - * extents of the new clip path. */ - - _cairo_traps_extents (traps, &extents); - _cairo_box_round_to_rectangle (&extents, &surface_rect); - - if (clip->surface != NULL) { - if (! _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect)) - goto DONE; + clip->all_clipped = TRUE; + if (clip->path != NULL) { + _cairo_clip_path_destroy (clip->path); + clip->path = NULL; } - - /* Intersect with the target surface rectangle so we don't use - * more memory and time than we need to. */ - status = _cairo_surface_get_extents (target, &target_rect); - if (status == CAIRO_STATUS_SUCCESS) { - if (! _cairo_rectangle_intersect (&surface_rect, &target_rect)) - goto DONE; - } - - if (surface_rect.width == 0 || surface_rect.height == 0) - goto DONE; - - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); - /* The clipping operation should ideally be something like the following to - * avoid having to do as many passes over the data - - if (clip->surface != NULL) { - _cairo_pattern_init_for_surface (&pattern.surface, clip->surface); - } else { - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); - } - status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN, - &pattern.base, - surface, - antialias, - 0, 0, - 0, 0, - surface_rect.width, - surface_rect.height, - traps->traps, - traps->num_traps); - - However this operation is not accelerated by pixman - - I believe the best possible operation would probably an unbounded SRC - operator. Using SRC we could potentially avoid having to initialize - the surface which would be ideal from an efficiency point of view. - However, CAIRO_OPERATOR_SOURCE is bounded by the trapezoid mask and - _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_SOURCE) will assert - because it assumes CAIRO_OPERATOR_SOURCE has been converted into other - operations. - */ - - surface = _cairo_surface_create_similar_solid (target, - CAIRO_CONTENT_ALPHA, - surface_rect.width, - surface_rect.height, - CAIRO_COLOR_TRANSPARENT); - if (surface->status) { - _cairo_pattern_fini (&pattern.base); - return surface->status; - } - - /* Render the new clipping path into the new mask surface. */ - - _cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y); - - status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD, - &pattern.base, - surface, - antialias, - 0, 0, - 0, 0, - surface_rect.width, - surface_rect.height, - traps->traps, - traps->num_traps); - - _cairo_pattern_fini (&pattern.base); - - if (unlikely (status)) { - cairo_surface_destroy (surface); - return status; - } - - /* If there was a clip surface already, combine it with the new - * mask surface using the IN operator, so we get the intersection - * of the old and new clipping paths. */ - - if (clip->surface != NULL) { - _cairo_pattern_init_for_surface (&pattern.surface, clip->surface); - - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, - &pattern.base, - NULL, - surface, - surface_rect.x - clip->surface_rect.x, - surface_rect.y - clip->surface_rect.y, - 0, 0, - 0, 0, - surface_rect.width, - surface_rect.height); - - _cairo_pattern_fini (&pattern.base); - - if (unlikely (status)) { - cairo_surface_destroy (surface); - return status; - } - } - - DONE: - cairo_surface_destroy (clip->surface); - clip->surface = surface; - clip->surface_rect = surface_rect; - clip->serial = _cairo_surface_allocate_clip_serial (target); - - if (surface_rect.width == 0 || surface_rect.height == 0) - _cairo_clip_set_all_clipped (clip, target); - - return status; } -static cairo_status_t -_cairo_clip_intersect_mask_using_spans (cairo_clip_t *clip, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - cairo_surface_t *target) +/* XXX consider accepting a matrix, no users yet. */ +cairo_status_t +_cairo_clip_init_rectangle (cairo_clip_t *clip, + const cairo_rectangle_int_t *rect) { - cairo_span_renderer_t *renderer = NULL; - cairo_pattern_union_t pattern; - cairo_rectangle_int_t surface_rect; - cairo_surface_t *surface = NULL; + cairo_clip_path_t *clip_path; cairo_status_t status; - cairo_operator_t op; - cairo_composite_rectangles_t rects; - if (clip->all_clipped) + _cairo_clip_init (clip); + if (rect == NULL) return CAIRO_STATUS_SUCCESS; - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); - - /* If we have a clip surface we're going to use IN to combine our - * new clip with the old clip. The ADD is done to a transparent - * surface, as that's a fast way of doing it currently. We should - * really be using SOURCE instead, but _cairo_surface_composite() - * checks that it's not called with SOURCE or DEST. */ - op = clip->surface ? CAIRO_OPERATOR_IN : CAIRO_OPERATOR_ADD; - - /* Test if the target can composite spans. We're going to assume - * this is a good indicator of whether a similar surface is going - * to be able to composite spans too. */ - if ( !_cairo_surface_check_span_renderer (op, - &pattern.base, - target, - antialias, - NULL)) - { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL; + if (rect->width == 0 || rect->height == 0) { + _cairo_clip_set_all_clipped (clip); + return CAIRO_STATUS_SUCCESS; } - status = _cairo_surface_get_extents (target, &surface_rect); - if (status) - goto BAIL; + clip_path = _cairo_clip_path_create (clip); + if (unlikely (clip_path == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); - /* We'll create a new surface the size of the intersection of the - * old mask surface and the extents of the new clip path. */ - { - cairo_rectangle_int_t extents; + _cairo_path_fixed_init (&clip_path->path); - _cairo_path_fixed_approximate_clip_extents (path, &extents); - if (! _cairo_rectangle_intersect (&surface_rect, &extents)) - goto SUCCESS; + status = _cairo_path_fixed_move_to (&clip_path->path, + _cairo_fixed_from_int (rect->x), + _cairo_fixed_from_int (rect->y)); + assert (status == CAIRO_STATUS_SUCCESS); + status = _cairo_path_fixed_rel_line_to (&clip_path->path, + _cairo_fixed_from_int (rect->width), + _cairo_fixed_from_int (0)); + assert (status == CAIRO_STATUS_SUCCESS); + status = _cairo_path_fixed_rel_line_to (&clip_path->path, + _cairo_fixed_from_int (0), + _cairo_fixed_from_int (rect->height)); + assert (status == CAIRO_STATUS_SUCCESS); + status = _cairo_path_fixed_rel_line_to (&clip_path->path, + _cairo_fixed_from_int (-rect->width), + _cairo_fixed_from_int (0)); + assert (status == CAIRO_STATUS_SUCCESS); + status = _cairo_path_fixed_close_path (&clip_path->path); + assert (status == CAIRO_STATUS_SUCCESS); - if (clip->surface != NULL && - ! _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect)) - goto SUCCESS; + clip_path->extents = *rect; + clip_path->fill_rule = CAIRO_FILL_RULE_WINDING; + clip_path->tolerance = 1; + clip_path->antialias = CAIRO_ANTIALIAS_NONE; + + /* could preallocate the region if it proves worthwhile */ + + return CAIRO_STATUS_SUCCESS; +} + +void +_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) +{ + if (other != NULL) { + clip->all_clipped = other->all_clipped; + clip->path = _cairo_clip_path_reference (other->path); + } else { + clip->all_clipped = FALSE; + clip->path = NULL; + } +} + +void +_cairo_clip_reset (cairo_clip_t *clip) +{ + clip->all_clipped = FALSE; + if (clip->path != NULL) { + _cairo_clip_path_destroy (clip->path); + clip->path = NULL; + } +} + +static cairo_status_t +_cairo_clip_intersect_path (cairo_clip_t *clip, + const cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) +{ + cairo_clip_path_t *clip_path; + cairo_status_t status; + cairo_rectangle_int_t extents; + + if (clip->path != NULL) { + if (_cairo_path_fixed_equal (&clip->path->path, path)) { + if (clip->path->fill_rule == fill_rule) { + if (path->is_rectilinear || + (tolerance == clip->path->tolerance && + antialias == clip->path->antialias)) + { + return CAIRO_STATUS_SUCCESS; + } + } + } } - /* Make the new mask surface and optionally initialise it from the - * previous clip if we have one. */ - surface = _cairo_surface_create_similar_solid (target, - CAIRO_CONTENT_ALPHA, - surface_rect.width, - surface_rect.height, - CAIRO_COLOR_TRANSPARENT); - if (surface->status) { - _cairo_pattern_fini (&pattern.base); - return surface->status; + _cairo_path_fixed_approximate_clip_extents (path, &extents); + if (extents.width == 0 || extents.height == 0) { + _cairo_clip_set_all_clipped (clip); + return CAIRO_STATUS_SUCCESS; } - if (clip->surface) { - cairo_surface_pattern_t old_clip; - _cairo_pattern_init_for_surface (&old_clip, clip->surface); - status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, - &old_clip.base, - NULL, - surface, - surface_rect.x - clip->surface_rect.x, - surface_rect.y - clip->surface_rect.y, - 0, 0, - 0, 0, - surface_rect.width, - surface_rect.height); - _cairo_pattern_fini (&old_clip.base); - if (status) - goto BAIL; + if (clip->path != NULL) { + cairo_box_t box; + + if (! _cairo_rectangle_intersect (&extents, &clip->path->extents)) { + _cairo_clip_set_all_clipped (clip); + return CAIRO_STATUS_SUCCESS; + } + + /* does this clip wholly subsume the others? */ + if (_cairo_path_fixed_is_box (path, &box)) { + if (box.p1.x <= _cairo_fixed_from_int (clip->path->extents.x) && + box.p2.x >= _cairo_fixed_from_int (clip->path->extents.x + clip->path->extents.width) && + box.p1.y <= _cairo_fixed_from_int (clip->path->extents.y) && + box.p2.y >= _cairo_fixed_from_int (clip->path->extents.y + clip->path->extents.height)) + { + return CAIRO_STATUS_SUCCESS; + } + } } - _cairo_composite_rectangles_init (&rects, - surface_rect.x, - surface_rect.y, - surface_rect.width, - surface_rect.height); - rects.dst.x = 0; - rects.dst.y = 0; + clip_path = _cairo_clip_path_create (clip); + if (unlikely (clip_path == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); - /* Render the new clipping path into the new mask surface. We've - * chosen op to either combine the new clip path with the existing - * clip mask (if there is one) or just render it. */ - status =_cairo_path_fixed_fill_using_spans (op, &pattern.base, - path, surface, - fill_rule, tolerance, - antialias, &rects); - if (status) - goto BAIL; + status = _cairo_path_fixed_init_copy (&clip_path->path, path); + if (unlikely (status)) { + clip->path = clip->path->prev; + _cairo_clip_path_destroy (clip_path); + return status; + } - SUCCESS: - if (clip->surface != NULL) - cairo_surface_destroy (clip->surface); - clip->surface = surface; - clip->surface_rect = surface_rect; - clip->serial = _cairo_surface_allocate_clip_serial (target); - surface = NULL; + clip_path->extents = extents; + clip_path->fill_rule = fill_rule; + clip_path->tolerance = tolerance; + clip_path->antialias = antialias; - if (surface_rect.width == 0 || surface_rect.height == 0) - _cairo_clip_set_all_clipped (clip, target); - - BAIL: - if (renderer) - renderer->destroy(renderer); - if (surface) - cairo_surface_destroy (surface); - _cairo_pattern_fini (&pattern.base); - return status; + return CAIRO_STATUS_SUCCESS; } cairo_status_t _cairo_clip_clip (cairo_clip_t *clip, - cairo_path_fixed_t *path, + const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, - cairo_antialias_t antialias, - cairo_surface_t *target) + cairo_antialias_t antialias) { - cairo_status_t status; - cairo_rectangle_int_t limits, extents; - cairo_traps_t traps; - cairo_box_t ignored_box; - cairo_bool_t have_limits; - if (clip->all_clipped) return CAIRO_STATUS_SUCCESS; /* catch the empty clip path */ - if (! path->has_current_point) { - _cairo_clip_set_all_clipped (clip, target); + if (_cairo_path_fixed_fill_is_empty (path)) { + _cairo_clip_set_all_clipped (clip); return CAIRO_STATUS_SUCCESS; } - status = _cairo_clip_intersect_path (clip, - path, fill_rule, tolerance, - antialias); - if (status == CAIRO_STATUS_SUCCESS) - clip->serial = _cairo_surface_allocate_clip_serial (target); - - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - /* TODO: allow ANTIALIAS_NONE when we have a mono scan converter - * again. */ - if (antialias != CAIRO_ANTIALIAS_NONE && - !_cairo_path_fixed_is_box (path, &ignored_box) && - !_cairo_path_fixed_is_region (path)) - { - status = _cairo_clip_intersect_mask_using_spans ( - clip, path, fill_rule, tolerance, antialias, target); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - _cairo_traps_init (&traps); - - /* Limit the traps to the target surface and current clip - * - so we don't add more traps than needed. */ - have_limits = FALSE; - if (clip->region != NULL) { - cairo_region_get_extents (clip->region, &limits); - have_limits = TRUE; - } - - if (clip->surface != NULL) { - if (have_limits) { - if (! _cairo_rectangle_intersect (&limits, &clip->surface_rect)) { - _cairo_clip_set_all_clipped (clip, target); - return CAIRO_STATUS_SUCCESS; - } - } else { - limits = clip->surface_rect; - have_limits = TRUE; - } - } - - status = _cairo_surface_get_extents (target, &extents); - if (status == CAIRO_STATUS_SUCCESS) { - if (have_limits) { - if (! _cairo_rectangle_intersect (&limits, &extents)) { - _cairo_clip_set_all_clipped (clip, target); - return CAIRO_STATUS_SUCCESS; - } - } else { - limits = extents; - have_limits = TRUE; - } - } - - if (have_limits) { - cairo_box_t box; - - _cairo_box_from_rectangle (&box, &limits); - _cairo_traps_limit (&traps, &box); - } - - status = _cairo_path_fixed_fill_to_traps (path, - fill_rule, - tolerance, - &traps); - if (unlikely (status)) - goto bail; - - status = _cairo_clip_intersect_region (clip, &traps, target); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto bail; - - status = _cairo_clip_intersect_mask (clip, &traps, antialias, target); - - bail: - _cairo_traps_fini (&traps); - - return status; -} - -void -_cairo_clip_translate (cairo_clip_t *clip, - cairo_fixed_t tx, - cairo_fixed_t ty) -{ - if (clip->all_clipped) - return; - - if (clip->region) { - cairo_region_translate (clip->region, - _cairo_fixed_integer_part (tx), - _cairo_fixed_integer_part (ty)); - } - - if (clip->surface) { - clip->surface_rect.x += _cairo_fixed_integer_part (tx); - clip->surface_rect.y += _cairo_fixed_integer_part (ty); - } - - if (clip->path) { - cairo_clip_path_t *clip_path = clip->path; - cairo_matrix_t matrix; - - cairo_matrix_init_translate (&matrix, - _cairo_fixed_to_double (tx), - _cairo_fixed_to_double (ty)); - - while (clip_path) { - _cairo_path_fixed_transform (&clip_path->path, &matrix); - clip_path = clip_path->prev; - } - } + return _cairo_clip_intersect_path (clip, + path, fill_rule, tolerance, + antialias); } static cairo_status_t -_cairo_clip_path_reapply_clip_path (cairo_clip_t *clip, - cairo_clip_path_t *clip_path) +_cairo_clip_path_reapply_clip_path_transform (cairo_clip_t *clip, + cairo_clip_path_t *other_path, + const cairo_matrix_t *matrix) { cairo_status_t status; + cairo_clip_path_t *clip_path; + cairo_bool_t is_empty; - if (clip_path->prev) { - status = _cairo_clip_path_reapply_clip_path (clip, clip_path->prev); - if (_cairo_status_is_error (status)) + if (other_path->prev != NULL) { + status = _cairo_clip_path_reapply_clip_path_transform (clip, + other_path->prev, + matrix); + if (unlikely (status)) return status; } - return _cairo_clip_intersect_path (clip, - &clip_path->path, - clip_path->fill_rule, - clip_path->tolerance, - clip_path->antialias); + clip_path = _cairo_clip_path_create (clip); + if (unlikely (clip_path == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + status = _cairo_path_fixed_init_copy (&clip_path->path, + &other_path->path); + if (unlikely (status)) { + _cairo_clip_path_destroy (clip_path); + return status; + } + + _cairo_path_fixed_transform (&clip_path->path, matrix); + _cairo_path_fixed_approximate_clip_extents (&clip_path->path, + &clip_path->extents); + if (clip_path->prev != NULL) { + is_empty = _cairo_rectangle_intersect (&clip_path->extents, + &clip_path->prev->extents); + } + + clip_path->fill_rule = other_path->fill_rule; + clip_path->tolerance = other_path->tolerance; + clip_path->antialias = other_path->antialias; + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_clip_path_reapply_clip_path_translate (cairo_clip_t *clip, + cairo_clip_path_t *other_path, + int tx, int ty) +{ + cairo_status_t status; + cairo_clip_path_t *clip_path; + + if (other_path->prev != NULL) { + status = _cairo_clip_path_reapply_clip_path_translate (clip, + other_path->prev, + tx, ty); + if (unlikely (status)) + return status; + } + + clip_path = _cairo_clip_path_create (clip); + if (unlikely (clip_path == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + status = _cairo_path_fixed_init_copy (&clip_path->path, + &other_path->path); + if (unlikely (status)) { + _cairo_clip_path_destroy (clip_path); + return status; + } + + _cairo_path_fixed_translate (&clip_path->path, + _cairo_fixed_from_int (tx), + _cairo_fixed_from_int (ty)); + + clip_path->fill_rule = other_path->fill_rule; + clip_path->tolerance = other_path->tolerance; + clip_path->antialias = other_path->antialias; + + clip_path->flags = other_path->flags; + if (other_path->region != NULL) { + clip_path->region = cairo_region_copy (other_path->region); + cairo_region_translate (clip_path->region, tx, ty); + } + clip_path->surface = cairo_surface_reference (other_path->surface); + + clip_path->extents = other_path->extents; + clip_path->extents.x += tx; + clip_path->extents.y += ty; + + return CAIRO_STATUS_SUCCESS; } cairo_status_t -_cairo_clip_init_deep_copy (cairo_clip_t *clip, - cairo_clip_t *other, - cairo_surface_t *target) +_cairo_clip_init_copy_transformed (cairo_clip_t *clip, + cairo_clip_t *other, + const cairo_matrix_t *matrix) +{ + cairo_status_t status = CAIRO_STATUS_SUCCESS; + int tx, ty; + + if (other == NULL) { + _cairo_clip_init (clip); + return CAIRO_STATUS_SUCCESS; + } + + if (other->all_clipped) { + _cairo_clip_init (clip); + clip->all_clipped = TRUE; + return CAIRO_STATUS_SUCCESS; + } + + if (_cairo_matrix_is_identity (matrix)) { + _cairo_clip_init_copy (clip, other); + return CAIRO_STATUS_SUCCESS; + } + + if (other->path != NULL) { + _cairo_clip_init (clip); + + /* if we only need to translate, so we can reuse the caches... */ + /* XXX we still loose the benefit of constructs when the copy is + * deleted though. Indirect clip_paths? + */ + if (_cairo_matrix_is_integer_translation (matrix, &tx, &ty)) { + status = _cairo_clip_path_reapply_clip_path_translate (clip, + other->path, + tx, ty); + } else { + status = _cairo_clip_path_reapply_clip_path_transform (clip, + other->path, + matrix); + if (clip->path->extents.width == 0 && + clip->path->extents.height == 0) + { + _cairo_clip_set_all_clipped (clip); + } + } + } + + return status; +} + +static cairo_status_t +_cairo_clip_apply_clip_path (cairo_clip_t *clip, + const cairo_clip_path_t *path) { cairo_status_t status; - _cairo_clip_init (clip, target); + if (path->prev != NULL) + status = _cairo_clip_apply_clip_path (clip, path->prev); - if (other->mode != clip->mode) { - /* We should reapply the original clip path in this case, and let - * whatever the right handling is happen */ - } else { - if (other->region) { - clip->region = cairo_region_copy (other->region); - if (unlikely ((status = cairo_region_status (clip->region)))) - goto BAIL; - } + return _cairo_clip_intersect_path (clip, + &path->path, + path->fill_rule, + path->tolerance, + path->antialias); +} - if (other->surface) { - int dx, dy; - status = _cairo_surface_clone_similar (target, other->surface, +cairo_status_t +_cairo_clip_apply_clip (cairo_clip_t *clip, + const cairo_clip_t *other) +{ + cairo_status_t status; + + if (clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + if (other->all_clipped) { + _cairo_clip_set_all_clipped (clip); + return CAIRO_STATUS_SUCCESS; + } + + status = CAIRO_STATUS_SUCCESS; + if (other->path != NULL) + status = _cairo_clip_apply_clip_path (clip, other->path); + + return status; +} + +static cairo_int_status_t +_cairo_clip_path_to_region (cairo_clip_path_t *clip_path) +{ + cairo_int_status_t status; + cairo_traps_t traps; + cairo_region_t *prev = NULL; + cairo_box_t box; + + if (clip_path->flags & + (CAIRO_CLIP_PATH_HAS_REGION | + CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED)) + { + return clip_path->flags & CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED ? + CAIRO_INT_STATUS_UNSUPPORTED : + CAIRO_STATUS_SUCCESS; + } + + if (! clip_path->path.maybe_fill_region) { + clip_path->flags |= CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED; + return CAIRO_INT_STATUS_UNSUPPORTED; + } + + /* first retrieve the region for our antecedents */ + if (clip_path->prev != NULL) { + status = _cairo_clip_path_to_region (clip_path->prev); + if (status) { + clip_path->flags |= CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED; + return status; + } + + prev = clip_path->prev->region; + } + + /* now extract the region for ourselves */ + + /* XXX fixed fill to region */ + _cairo_traps_init (&traps); + + _cairo_box_from_rectangle (&box, &clip_path->extents); + _cairo_traps_limit (&traps, &box); + + status = _cairo_path_fixed_fill_to_traps (&clip_path->path, + clip_path->fill_rule, + clip_path->tolerance, + &traps); + if (unlikely (status)) + return status; + + status = _cairo_traps_extract_region (&traps, &clip_path->region); + _cairo_traps_fini (&traps); + + if (status) { + clip_path->flags |= CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED; + return status; + } + + if (prev != NULL) { + status = cairo_region_intersect (clip_path->region, prev); + if (unlikely (status)) + return status; + } + + clip_path->flags |= CAIRO_CLIP_PATH_HAS_REGION; + return CAIRO_STATUS_SUCCESS; +} + +cairo_surface_t * +_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *target) +{ + cairo_surface_t *surface; + cairo_pattern_union_t pattern; + cairo_status_t status; + cairo_clip_path_t *clip_path = clip->path; + const cairo_rectangle_int_t *clip_extents = &clip_path->extents; + cairo_region_t *clip_region; + cairo_bool_t need_translate; + + assert (clip_path != NULL); + + if (clip_path->surface != NULL && + clip_path->surface->backend == target->backend) + { + return cairo_surface_reference (clip_path->surface); + } + + surface = _cairo_surface_create_similar_solid (target, CAIRO_CONTENT_ALPHA, - 0, - 0, - other->surface_rect.width, - other->surface_rect.height, - &dx, &dy, - &clip->surface); + clip_extents->width, + clip_extents->height, + CAIRO_COLOR_TRANSPARENT, + FALSE); + if (surface == NULL) { + if (clip_path->surface != NULL && + clip_path->surface->backend == &_cairo_image_surface_backend) + { + return cairo_surface_reference (clip_path->surface); + } + + surface = + _cairo_image_surface_create_with_content (CAIRO_CONTENT_ALPHA, + clip_extents->width, + clip_extents->height); + } + if (unlikely (surface->status)) + return surface; + + _cairo_pattern_init_solid (&pattern.solid, + CAIRO_COLOR_WHITE, + CAIRO_CONTENT_COLOR); + + status = _cairo_clip_get_region (clip, &clip_region); + if (_cairo_status_is_error (status)) + goto BAIL; + + need_translate = clip_extents->x || clip_extents->y; + if (status == CAIRO_STATUS_SUCCESS) { + if (need_translate) { + cairo_region_translate (clip_region, + -clip_extents->x, -clip_extents->y); + } + status = _cairo_surface_fill_region (surface, + CAIRO_OPERATOR_ADD, + CAIRO_COLOR_WHITE, + clip_region); + if (need_translate) { + cairo_region_translate (clip_region, + clip_extents->x, clip_extents->y); + } + if (unlikely (status)) + goto BAIL; + + goto DONE; + } else { + if (need_translate) { + _cairo_path_fixed_translate (&clip_path->path, + _cairo_fixed_from_int (-clip_extents->x), + _cairo_fixed_from_int (-clip_extents->y)); + } + status = _cairo_surface_fill (surface, + CAIRO_OPERATOR_ADD, + &pattern.base, + &clip_path->path, + clip_path->fill_rule, + clip_path->tolerance, + clip_path->antialias, + NULL); + if (need_translate) { + _cairo_path_fixed_translate (&clip_path->path, + _cairo_fixed_from_int (clip_extents->x), + _cairo_fixed_from_int (clip_extents->y)); + } + + if (unlikely (status)) + goto BAIL; + } + + while ((clip_path = clip_path->prev) != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + if (_cairo_status_is_error (status)) + goto BAIL; + + if (status == CAIRO_STATUS_SUCCESS) { + cairo_region_translate (clip_region, + -clip_extents->x, -clip_extents->y); + status = _cairo_surface_fill_region (surface, + CAIRO_OPERATOR_IN, + CAIRO_COLOR_WHITE, + clip_region); + cairo_region_translate (clip_region, + clip_extents->x, clip_extents->y); if (unlikely (status)) goto BAIL; - clip->surface_rect = other->surface_rect; + goto DONE; + } else { + if (clip_path->surface != NULL && + clip_path->surface->backend == surface->backend) + { + _cairo_pattern_init_for_surface (&pattern.surface, + clip_path->surface); + cairo_matrix_init_translate (&pattern.base.matrix, + -clip_path->extents.x + clip_extents->x, + -clip_path->extents.y + clip_extents->y); + status = _cairo_surface_paint (surface, + CAIRO_OPERATOR_IN, + &pattern.base, + NULL); - /* src offset was 0, so we expect an exact replica of the surface */ - assert (dx == 0); - assert (dy == 0); - } + _cairo_pattern_fini (&pattern.base); - if (other->path) { - status = _cairo_clip_path_reapply_clip_path (clip, other->path); - if (_cairo_status_is_error (status)) + if (unlikely (status)) + goto BAIL; + + goto DONE; + } else { + /* XXX build intermediate surfaces? */ + if (need_translate) { + _cairo_path_fixed_translate (&clip_path->path, + _cairo_fixed_from_int (-clip_extents->x), + _cairo_fixed_from_int (-clip_extents->y)); + } + status = _cairo_surface_fill (surface, + CAIRO_OPERATOR_IN, + &pattern.base, + &clip_path->path, + clip_path->fill_rule, + clip_path->tolerance, + clip_path->antialias, + NULL); + if (need_translate) { + _cairo_path_fixed_translate (&clip_path->path, + _cairo_fixed_from_int (clip_extents->x), + _cairo_fixed_from_int (clip_extents->y)); + } + } + if (unlikely (status)) goto BAIL; - } + } } - return CAIRO_STATUS_SUCCESS; +DONE: + cairo_surface_destroy (clip->path->surface); + return clip->path->surface = cairo_surface_reference (surface); BAIL: - if (clip->region) - cairo_region_destroy (clip->region); - if (clip->surface) - cairo_surface_destroy (clip->surface); + cairo_surface_destroy (surface); + return _cairo_surface_create_in_error (status); +} - return status; +const cairo_rectangle_int_t * +_cairo_clip_get_extents (const cairo_clip_t *clip) +{ + if (clip->path == NULL) + return NULL; + + return &clip->path->extents; +} + +void +_cairo_clip_drop_cache (cairo_clip_t *clip) +{ + cairo_clip_path_t *clip_path; + + if (clip->path == NULL) + return; + + clip_path = clip->path; + do { + if (clip_path->region != NULL) { + cairo_region_destroy (clip_path->region); + clip_path->region = NULL; + } + + if (clip_path->surface != NULL) { + cairo_surface_destroy (clip_path->surface); + clip_path->surface = NULL; + } + + clip_path->flags = 0; + } while ((clip_path = clip_path->prev) != NULL); } const cairo_rectangle_list_t _cairo_rectangles_nil = @@ -862,42 +838,90 @@ _cairo_clip_int_rect_to_user (cairo_gstate_t *gstate, return is_tight; } +cairo_int_status_t +_cairo_clip_get_region (cairo_clip_t *clip, + cairo_region_t **region) +{ + cairo_int_status_t status; + + *region = NULL; + if (clip->all_clipped) + return CAIRO_INT_STATUS_NOTHING_TO_DO; + + if (clip->path == NULL) + return CAIRO_STATUS_SUCCESS; + + status = _cairo_clip_path_to_region (clip->path); + if (status) + return status; + + *region = clip->path->region; + return CAIRO_STATUS_SUCCESS; +} + +static cairo_rectangle_list_t * +_cairo_rectangle_list_create_in_error (cairo_status_t status) +{ + cairo_rectangle_list_t *list; + + if (status == CAIRO_STATUS_NO_MEMORY) + return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; + if (status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) + return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; + + list = malloc (sizeof (*list)); + if (unlikely (list == NULL)) { + _cairo_error_throw (status); + return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; + } + + list->status = status; + list->rectangles = NULL; + list->num_rectangles = 0; + + return list; +} + cairo_rectangle_list_t * _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) { +#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S)); + cairo_rectangle_list_t *list; cairo_rectangle_t *rectangles = NULL; + cairo_int_status_t status; + cairo_region_t *region; int n_rects = 0; + int i; - if (clip->all_clipped) + status = _cairo_clip_get_region (clip, ®ion); + if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) { goto DONE; - - if (clip->path || clip->surface) { - _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); - return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; + } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) + } else if (unlikely (status)) { + return ERROR_LIST (status); } - if (clip->region) { - int i; - - n_rects = cairo_region_num_rectangles (clip->region); - + if (region != NULL) { + n_rects = cairo_region_num_rectangles (region); if (n_rects) { rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t)); if (unlikely (rectangles == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; + return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); } for (i = 0; i < n_rects; ++i) { cairo_rectangle_int_t clip_rect; - cairo_region_get_rectangle (clip->region, i, &clip_rect); - - if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) { - _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); + cairo_region_get_rectangle (region, i, &clip_rect); + + if (! _cairo_clip_int_rect_to_user (gstate, + &clip_rect, + &rectangles[i])) + { free (rectangles); - return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); } } } @@ -908,31 +932,31 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) rectangles = malloc(sizeof (cairo_rectangle_t)); if (unlikely (rectangles == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; + return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); } - if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), &extents) || - !_cairo_clip_int_rect_to_user(gstate, &extents, rectangles)) + if (_cairo_surface_get_extents (_cairo_gstate_get_target (gstate), + &extents) || + ! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) { - _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); free (rectangles); - return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); } } DONE: list = malloc (sizeof (cairo_rectangle_list_t)); if (unlikely (list == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); free (rectangles); - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; + return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); } list->status = CAIRO_STATUS_SUCCESS; list->rectangles = rectangles; list->num_rectangles = n_rects; return list; + +#undef ERROR_LIST } /** @@ -955,3 +979,9 @@ cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list) free (rectangle_list->rectangles); free (rectangle_list); } + +void +_cairo_clip_reset_static_data (void) +{ + _freed_pool_reset (&clip_path_pool); +} diff --git a/src/cairo-debug.c b/src/cairo-debug.c index d4548f157..4dccebeb9 100644 --- a/src/cairo-debug.c +++ b/src/cairo-debug.c @@ -75,6 +75,8 @@ cairo_debug_reset_static_data (void) _cairo_pattern_reset_static_data (); + _cairo_clip_reset_static_data (); + CAIRO_MUTEX_FINALIZE (); } diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index f7de84ca8..967b0447f 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -38,14 +38,16 @@ #include "cairoint.h" #include "cairo-directfb.h" +#include "cairo-clip-private.h" + +#include + #include #include #include #include #include -#include "cairo-clip-private.h" - /* * Rectangle works fine. * Bugs 361377, 359553, 359243 in Gnome BTS are caused @@ -68,6 +70,8 @@ */ #define DFB_SHOW_GLYPHS 1 +#define PIXMAN_invalid (pixman_format_code_t) 0 + D_DEBUG_DOMAIN (CairoDFB_Acquire, "CairoDFB/Acquire", "Cairo DirectFB Acquire"); D_DEBUG_DOMAIN (CairoDFB_Clip, "CairoDFB/Clip", "Cairo DirectFB Clipping"); @@ -78,17 +82,15 @@ D_DEBUG_DOMAIN (CairoDFB_Surface, "CairoDFB/Surface", "Cairo DirectFB Surface"); /*****************************************************************************/ typedef struct _cairo_directfb_surface { - cairo_surface_t base; - cairo_format_t format; - cairo_content_t content; + cairo_surface_t base; - IDirectFB *dfb; - IDirectFBSurface *dfbsurface; - IDirectFBSurface *tmpsurface; + pixman_format_code_t pixman_format; + cairo_bool_t supported_destination; - cairo_bool_t has_clip; - DFBRegion *clips; - int n_clips; + IDirectFB *dfb; + IDirectFBSurface *dfbsurface; + IDirectFBSurface *tmpsurface; + pixman_format_code_t tmpformat; int width; int height; @@ -119,13 +121,18 @@ static int _directfb_argb_font = 0; /*****************************************************************************/ -#define RUN_CLIPPED(surface, clip, func) {\ - if ((surface)->has_clip) {\ - int k;\ - for (k = 0; k < (surface)->n_clips; k++) {\ +#define RUN_CLIPPED(surface, clip_region, clip, func) {\ + if ((clip_region) != NULL) {\ + int n_clips = cairo_region_num_rectangles (clip_region), n; \ + for (n = 0; n < n_clips; n++) {\ if (clip) {\ - DFBRegion reg = (surface)->clips[k];\ - DFBRegion *cli = (clip);\ + DFBRegion reg, *cli = (clip); \ + cairo_rectangle_int_t rect; \ + cairo_region_get_rectangle (clip_region, n, &rect); \ + reg.x1 = rect.x; \ + reg.y1 = rect.y; \ + reg.x2 = rect.x + rect.width - 1; \ + reg.y2 = rect.y + rect.height - 1; \ if (reg.x2 < cli->x1 || reg.y2 < cli->y1 ||\ reg.x1 > cli->x2 || reg.y1 > cli->y2)\ continue;\ @@ -139,8 +146,14 @@ static int _directfb_argb_font = 0; reg.y2 = cli->y2;\ (surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®);\ } else {\ - (surface)->dfbsurface->SetClip ((surface)->dfbsurface,\ - &(surface)->clips[k]);\ + DFBRegion reg; \ + cairo_rectangle_int_t rect; \ + cairo_region_get_rectangle (clip_region, n, &rect); \ + reg.x1 = rect.x; \ + reg.y1 = rect.y; \ + reg.x2 = rect.x + rect.width - 1; \ + reg.y2 = rect.y + rect.height - 1; \ + (surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®); \ }\ func;\ }\ @@ -150,19 +163,19 @@ static int _directfb_argb_font = 0; }\ } -#define TRANSFORM_POINT2X(m, x, y, ret_x, ret_y) {\ - double _x = (x);\ - double _y = (y);\ - (ret_x) = (_x * (m).xx + (m).x0);\ - (ret_y) = (_y * (m).yy + (m).y0);\ -} +#define TRANSFORM_POINT2X(m, x, y, ret_x, ret_y) do { \ + double _x = (x); \ + double _y = (y); \ + (ret_x) = (_x * (m).xx + (m).x0); \ + (ret_y) = (_y * (m).yy + (m).y0); \ +} while (0) -#define TRANSFORM_POINT3X(m, x, y, ret_x, ret_y) {\ - double _x = (x);\ - double _y = (y);\ - (ret_x) = (_x * (m).xx + _y * (m).xy + (m).x0);\ - (ret_y) = (_x * (m).yx + _y * (m).yy + (m).y0);\ -} +#define TRANSFORM_POINT3X(m, x, y, ret_x, ret_y) do { \ + double _x = (x); \ + double _y = (y); \ + (ret_x) = (_x * (m).xx + _y * (m).xy + (m).x0); \ + (ret_y) = (_x * (m).yx + _y * (m).yy + (m).y0); \ +} while (0) /* XXX: A1 has a different bits ordering in cairo. * Probably we should drop it. @@ -200,23 +213,65 @@ _cairo_to_directfb_format (cairo_format_t format) return -1; } -static inline cairo_format_t -_directfb_to_cairo_format (DFBSurfacePixelFormat format) +static inline pixman_format_code_t +_directfb_to_pixman_format (DFBSurfacePixelFormat format) { switch (format) { - case DSPF_RGB32: - return CAIRO_FORMAT_RGB24; - case DSPF_ARGB: - return CAIRO_FORMAT_ARGB32; - case DSPF_A8: - return CAIRO_FORMAT_A8; - case DSPF_A1: - return CAIRO_FORMAT_A1; - default: - break; + case DSPF_UNKNOWN: return PIXMAN_invalid; + case DSPF_ARGB1555: return PIXMAN_a1r5g5b5; + case DSPF_RGB16: return PIXMAN_r5g6b5; + case DSPF_RGB24: return PIXMAN_r8g8b8; + case DSPF_RGB32: return PIXMAN_x8r8g8b8; + case DSPF_ARGB: return PIXMAN_a8r8g8b8; + case DSPF_A8: return PIXMAN_a8; + case DSPF_YUY2: return PIXMAN_yuy2; + case DSPF_RGB332: return PIXMAN_r3g3b2; + case DSPF_UYVY: return PIXMAN_invalid; + case DSPF_I420: return PIXMAN_invalid; + case DSPF_YV12: return PIXMAN_yv12; + case DSPF_LUT8: return PIXMAN_invalid; + case DSPF_ALUT44: return PIXMAN_invalid; + case DSPF_AiRGB: return PIXMAN_invalid; + case DSPF_A1: return PIXMAN_a1; /* bit reversed, oops */ + case DSPF_NV12: return PIXMAN_invalid; + case DSPF_NV16: return PIXMAN_invalid; + case DSPF_ARGB2554: return PIXMAN_invalid; + case DSPF_ARGB4444: return PIXMAN_a4r4g4b4; + case DSPF_NV21: return PIXMAN_invalid; + case DSPF_AYUV: return PIXMAN_invalid; + case DSPF_A4: return PIXMAN_a4; + case DSPF_ARGB1666: return PIXMAN_invalid; + case DSPF_ARGB6666: return PIXMAN_invalid; + case DSPF_RGB18: return PIXMAN_invalid; + case DSPF_LUT2: return PIXMAN_invalid; + case DSPF_RGB444: return PIXMAN_x4r4g4b4; + case DSPF_RGB555: return PIXMAN_x1r5g5b5; + case DSPF_BGR555: return PIXMAN_x1b5g5r5; } + return PIXMAN_invalid; +} - return -1; +static inline DFBSurfacePixelFormat +_directfb_from_pixman_format (pixman_format_code_t format) +{ + switch ((int) format) { + case PIXMAN_a1r5g5b5: return DSPF_ARGB1555; + case PIXMAN_r5g6b5: return DSPF_RGB16; + case PIXMAN_r8g8b8: return DSPF_RGB24; + case PIXMAN_x8r8g8b8: return DSPF_RGB32; + case PIXMAN_a8r8g8b8: return DSPF_ARGB; + case PIXMAN_a8: return DSPF_A8; + case PIXMAN_yuy2: return DSPF_YUY2; + case PIXMAN_r3g3b2: return DSPF_RGB332; + case PIXMAN_yv12: return DSPF_YV12; + case PIXMAN_a1: return DSPF_A1; /* bit reversed, oops */ + case PIXMAN_a4r4g4b4: return DSPF_ARGB4444; + case PIXMAN_a4: return DSPF_A4; + case PIXMAN_x4r4g4b4: return DSPF_RGB444; + case PIXMAN_x1r5g5b5: return DSPF_RGB555; + case PIXMAN_x1b5g5r5: return DSPF_BGR555; + default: return 0; + } } static cairo_bool_t @@ -350,17 +405,14 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface, IDirectFBSurface *buffer = NULL; DFBRectangle source_rect; cairo_surface_t *image; - cairo_format_t cairo_format; + pixman_image_t *pixman_image; + pixman_format_code_t pixman_format; cairo_status_t status; void *data; int pitch; - if (surface->format == (cairo_format_t) -1 || - (lock_flags & DSLF_WRITE && surface->has_clip)) - { - DFBSurfaceCapabilities caps; - - if (intrest_rec) { + if (surface->pixman_format == PIXMAN_invalid) { + if (intrest_rec != NULL) { source_rect.x = intrest_rec->x; source_rect.y = intrest_rec->y; source_rect.w = intrest_rec->width; @@ -372,30 +424,38 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface, &source_rect.w, &source_rect.h); } - if (surface->tmpsurface) { + if (surface->tmpsurface != NULL) { int w, h; + surface->tmpsurface->GetSize (surface->tmpsurface, &w, &h); if (w < source_rect.w || h < source_rect.h) { surface->tmpsurface->Release (surface->tmpsurface); surface->tmpsurface = NULL; + surface->tmpformat = PIXMAN_invalid; } } - cairo_format = _cairo_format_from_content (surface->content); - if (!surface->tmpsurface) { + if (surface->tmpsurface == NULL) { + DFBSurfacePixelFormat format; + D_DEBUG_AT (CairoDFB_Acquire, "Allocating buffer for surface %p.\n", surface); + format = _cairo_to_directfb_format (_cairo_format_from_content (surface->base.content)); status = - _directfb_buffer_surface_create (surface->dfb, - _cairo_to_directfb_format (cairo_format), + _directfb_buffer_surface_create (surface->dfb, format, source_rect.w, source_rect.h, &surface->tmpsurface); - if (status) + if (unlikely (status)) goto ERROR; + + surface->tmpformat = _directfb_to_pixman_format (format); } buffer = surface->tmpsurface; + pixman_format = surface->tmpformat; + /* surface->dfbsurface->GetCapabilities (surface->dfbsurface, &caps); + DFBSurfaceCapabilities caps; if (caps & DSCAPS_FLIPPING) { DFBRegion region = { .x1 = source_rect.x, .y1 = source_rect.y, .x2 = source_rect.x + source_rect.w - 1, @@ -406,7 +466,7 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface, } else { /*might be a subsurface get the offset*/ surface->dfbsurface->GetVisibleRectangle (surface->dfbsurface, &source_rect); - cairo_format = surface->format; + pixman_format = surface->pixman_format; buffer = surface->dfbsurface; } @@ -416,9 +476,16 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface, goto ERROR; } - image = cairo_image_surface_create_for_data (data, cairo_format, - source_rect.w, source_rect.h, - pitch); + pixman_image = pixman_image_create_bits (pixman_format, + source_rect.w, source_rect.h, + data, pitch); + if (pixman_image == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto ERROR; + } + + image = _cairo_image_surface_create_for_pixman_image (pixman_image, + pixman_format); status = image->status; if (status) goto ERROR; @@ -451,37 +518,27 @@ ERROR: } static cairo_surface_t * -_cairo_directfb_surface_create_similar (void *abstract_src, - cairo_content_t content, - int width, - int height) +_cairo_directfb_surface_create_internal (IDirectFB *dfb, + DFBSurfacePixelFormat format, + cairo_content_t content, + int width, + int height) { - cairo_directfb_surface_t *source = abstract_src; cairo_directfb_surface_t *surface; - cairo_format_t format; cairo_status_t status; - D_DEBUG_AT (CairoDFB_Surface, - "%s( src=%p, content=0x%x, width=%d, height=%d).\n", - __FUNCTION__, source, content, width, height); - - width = (width <= 0) ? 1 : width; - height = (height<= 0) ? 1 : height; - - format = _cairo_format_from_content (content); surface = calloc (1, sizeof (cairo_directfb_surface_t)); if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - surface->dfb = source->dfb; + surface->dfb = dfb; if (width < 8 || height < 8) { IDirectFBSurface *tmp; DFBRectangle rect = { .x=0, .y=0, .w=width, .h=height }; /* Some cards (e.g. Matrox) don't support surfaces smaller than 8x8 */ - status = _directfb_buffer_surface_create (surface->dfb, - _cairo_to_directfb_format (format), + status = _directfb_buffer_surface_create (dfb, format, MAX (width, 8), MAX (height, 8), &tmp); if (status) { @@ -492,11 +549,9 @@ _cairo_directfb_surface_create_similar (void *abstract_src, tmp->GetSubSurface (tmp, &rect, &surface->dfbsurface); tmp->Release (tmp); } else { - status = - _directfb_buffer_surface_create (surface->dfb, - _cairo_to_directfb_format (format), - width, height, - &surface->dfbsurface); + status = _directfb_buffer_surface_create (dfb, format, + width, height, + &surface->dfbsurface); if (status) { free (surface); return _cairo_surface_create_in_error (status); @@ -506,8 +561,9 @@ _cairo_directfb_surface_create_similar (void *abstract_src, _cairo_surface_init (&surface->base, &_cairo_directfb_surface_backend, content); - surface->format = format; - surface->content = content; + surface->pixman_format = _directfb_to_pixman_format (format); + surface->supported_destination = pixman_format_supported_destination (surface->pixman_format); + surface->width = width; surface->height = height; surface->local = TRUE; @@ -516,6 +572,27 @@ _cairo_directfb_surface_create_similar (void *abstract_src, return &surface->base; } +static cairo_surface_t * +_cairo_directfb_surface_create_similar (void *abstract_src, + cairo_content_t content, + int width, + int height) +{ + cairo_directfb_surface_t *other = abstract_src; + DFBSurfacePixelFormat format; + + D_DEBUG_AT (CairoDFB_Surface, + "%s( src=%p, content=0x%x, width=%d, height=%d).\n", + __FUNCTION__, other, content, width, height); + + width = (width <= 0) ? 1 : width; + height = (height<= 0) ? 1 : height; + + format = _cairo_to_directfb_format (_cairo_format_from_content (content)); + return _cairo_directfb_surface_create_internal (other->dfb, format, + content, width, height); +} + static cairo_status_t _cairo_directfb_surface_finish (void *data) { @@ -523,12 +600,6 @@ _cairo_directfb_surface_finish (void *data) D_DEBUG_AT (CairoDFB_Surface, "%s( surface=%p ).\n", __FUNCTION__, surface); - if (surface->clips) { - free (surface->clips); - surface->clips = NULL; - surface->n_clips = 0; - } - if (surface->tmpsurface) { surface->tmpsurface->Release (surface->tmpsurface); surface->tmpsurface = NULL; @@ -564,11 +635,10 @@ _cairo_directfb_surface_release_source_image (void *abstract_su cairo_image_surface_t *image, void *image_extra) { - cairo_directfb_surface_t *surface = abstract_surface; IDirectFBSurface *buffer = image_extra; D_DEBUG_AT (CairoDFB_Acquire, - "%s( surface=%p ).\n", __FUNCTION__, surface); + "%s( release=%p ).\n", __FUNCTION__, abstract_surface); buffer->Unlock (buffer); @@ -620,10 +690,10 @@ _cairo_directfb_surface_release_dest_image (void *abstract_surf .y2 = interest_rect->y + interest_rect->height - 1 }; surface->dfbsurface->SetBlittingFlags (surface->dfbsurface, DSBLIT_NOFX); - RUN_CLIPPED (surface, ®ion, - surface->dfbsurface->Blit (surface->dfbsurface, - buffer, NULL, - image_rect->x, image_rect->y)); + surface->dfbsurface->SetClip (surface->dfbsurface, ®ion); + surface->dfbsurface->Blit (surface->dfbsurface, + buffer, NULL, + image_rect->x, image_rect->y); } cairo_surface_destroy (&image->base); @@ -655,56 +725,51 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } else if (_cairo_surface_is_image (src)) { cairo_image_surface_t *image_src = (cairo_image_surface_t *) src; - unsigned char *dst, *src = image_src->data; - int pitch; - int i, j; + DFBSurfacePixelFormat format; DFBResult ret; + pixman_image_t *pixman_image; + void *data; + int pitch; + + format = _directfb_from_pixman_format (image_src->pixman_format); + if (format == 0) + return CAIRO_INT_STATUS_UNSUPPORTED; clone = (cairo_directfb_surface_t *) - _cairo_directfb_surface_create_similar (surface, - _cairo_content_from_format (image_src->format), - width, height); - if (clone == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - if (clone->base.status) + _cairo_directfb_surface_create_internal (surface->dfb, format, + image_src->base.content, + width, height); + if (unlikely (clone->base.status)) return clone->base.status; ret = clone->dfbsurface->Lock (clone->dfbsurface, - DSLF_WRITE, (void *)&dst, &pitch); + DSLF_WRITE, (void *)&data, &pitch); if (ret) { DirectFBError ("IDirectFBSurface::Lock()", ret); cairo_surface_destroy (&clone->base); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } - src += image_src->stride * src_y; - if (image_src->format == CAIRO_FORMAT_A1) { - /* A1 -> A8 */ - dst -= src_x; - for (i = 0; i < height; i++) { - for (j = src_x; j < src_x + width; j++) - dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0x00; - dst += pitch; - src += image_src->stride; - } - } else { - int len; - - if (image_src->format == CAIRO_FORMAT_A8) { - src += src_x; - len = width; - } else { - src += src_x * 4; - len = width * 4; - } - - for (i = 0; i < height; i++) { - direct_memcpy (dst, src, len); - dst += pitch; - src += image_src->stride; - } + pixman_image = pixman_image_create_bits (clone->pixman_format, + width, height, + data, pitch); + if (unlikely (pixman_image == NULL)) { + DirectFBError ("IDirectFBSurface::Lock()", ret); + cairo_surface_destroy (&clone->base); + return _cairo_error (CAIRO_STATUS_NO_MEMORY); } + pixman_image_composite (PIXMAN_OP_SRC, + image_src->pixman_image, + NULL, + pixman_image, + src_x, src_y, + 0, 0, + 0, 0, + width, height); + + pixman_image_unref (pixman_image); + clone->dfbsurface->Unlock (clone->dfbsurface); *clone_offset_x = src_x; @@ -745,8 +810,6 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst, return CAIRO_INT_STATUS_UNSUPPORTED; if (mask_pattern) { - cairo_solid_pattern_t *pattern; - return CAIRO_INT_STATUS_UNSUPPORTED; if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID) { const cairo_pattern_t *tmp; @@ -794,7 +857,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst, return CAIRO_INT_STATUS_UNSUPPORTED; } - if (src->content == CAIRO_CONTENT_COLOR) { + if ((src->base.content & CAIRO_CONTENT_ALPHA) == 0) { if (sblend == DSBF_SRCALPHA) sblend = DSBF_ONE; else if (sblend == DSBF_INVSRCALPHA) @@ -806,7 +869,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst, dblend = DSBF_ZERO; } - if (dst->content == CAIRO_CONTENT_COLOR) { + if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) { if (sblend == DSBF_DESTALPHA) sblend = DSBF_ONE; else if (sblend == DSBF_INVDESTALPHA) @@ -913,7 +976,8 @@ _cairo_directfb_surface_composite (cairo_operator_t op, int mask_x, int mask_y, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_directfb_surface_t *dst = abstract_dst; cairo_directfb_surface_t *src; @@ -930,6 +994,9 @@ _cairo_directfb_surface_composite (cairo_operator_t op, __FUNCTION__, op, src_pattern, mask_pattern, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); + if (! dst->supported_destination) + return CAIRO_INT_STATUS_UNSUPPORTED; + status = _directfb_prepare_composite (dst, src_pattern, mask_pattern, op, &src_x, &src_y, &mask_x, &mask_y, width, height, &src, &src_attr); @@ -956,7 +1023,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op, src_x += src_attr.x_offset; src_y += src_attr.y_offset; - switch (accel) { + switch ((int) accel) { case DFXL_BLIT: { DFBRectangle sr; @@ -974,11 +1041,10 @@ _cairo_directfb_surface_composite (cairo_operator_t op, if (src_attr.extend == CAIRO_EXTEND_NONE) { D_DEBUG_AT (CairoDFB_Render, "Running Blit().\n"); - RUN_CLIPPED (dst, NULL, + RUN_CLIPPED (dst, clip_region, NULL, dst->dfbsurface->Blit (dst->dfbsurface, src->dfbsurface, - &sr, - dst_x, dst_y)); + &sr, dst_x, dst_y)); } else if (src_attr.extend == CAIRO_EXTEND_REPEAT) { DFBRegion clip; @@ -989,11 +1055,10 @@ _cairo_directfb_surface_composite (cairo_operator_t op, D_DEBUG_AT (CairoDFB_Render, "Running TileBlit().\n"); - RUN_CLIPPED (dst, &clip, + RUN_CLIPPED (dst, clip_region, &clip, dst->dfbsurface->TileBlit (dst->dfbsurface, src->dfbsurface, - &sr, - dst_x, dst_y)); + &sr, dst_x, dst_y)); } break; } @@ -1020,9 +1085,10 @@ _cairo_directfb_surface_composite (cairo_operator_t op, D_DEBUG_AT (CairoDFB_Render, "Running StretchBlit().\n"); - RUN_CLIPPED (dst, NULL, + RUN_CLIPPED (dst, clip_region, NULL, dst->dfbsurface->StretchBlit (dst->dfbsurface, - src->dfbsurface, &sr, &dr)); + src->dfbsurface, + &sr, &dr)); break; } @@ -1044,29 +1110,25 @@ _cairo_directfb_surface_composite (cairo_operator_t op, src->dfbsurface->GetSize (src->dfbsurface, &w, &h); - TRANSFORM_POINT3X (src_attr.matrix, - x1, y1, v[0].x, v[0].y); + TRANSFORM_POINT3X (src_attr.matrix, x1, y1, v[0].x, v[0].y); v[0].z = 0; v[0].w = 1; v[0].s = x1 / w; v[0].t = y1 / h; - TRANSFORM_POINT3X (src_attr.matrix, - x2, y1, v[1].x, v[1].y); + TRANSFORM_POINT3X (src_attr.matrix, x2, y1, v[1].x, v[1].y); v[1].z = 0; v[1].w = 1; v[1].s = x2 / w; v[1].t = y1 / h; - TRANSFORM_POINT3X (src_attr.matrix, - x2, y2, v[2].x, v[2].y); + TRANSFORM_POINT3X (src_attr.matrix, x2, y2, v[2].x, v[2].y); v[2].z = 0; v[2].w = 1; v[2].s = x2 / w; v[2].t = y2 / h; - TRANSFORM_POINT3X (src_attr.matrix, - x1, y2, v[3].x, v[3].y); + TRANSFORM_POINT3X (src_attr.matrix, x1, y2, v[3].x, v[3].y); v[3].z = 0; v[3].w = 1; v[3].s = x1 / w; @@ -1079,9 +1141,11 @@ _cairo_directfb_surface_composite (cairo_operator_t op, D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n"); - RUN_CLIPPED (dst, &clip, + RUN_CLIPPED (dst, clip_region, &clip, dst->dfbsurface->TextureTriangles (dst->dfbsurface, - src->dfbsurface, v, NULL, 4, DTTF_FAN)); + src->dfbsurface, + v, NULL, + 4, DTTF_FAN)); break; } @@ -1092,7 +1156,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op, _directfb_finish_composite (dst, src_pattern, &src->base, &src_attr); - return status; + return CAIRO_STATUS_SUCCESS; } #endif /* DFB_COMPOSITE */ @@ -1115,8 +1179,8 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface "%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n", __FUNCTION__, dst, op, color, rects, n_rects); - if (! _cairo_operator_bounded_by_source (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (! dst->supported_destination) + return CAIRO_INT_STATUS_UNSUPPORTED; if (! _directfb_get_operator (op, &sblend, &dblend)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1132,7 +1196,7 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface else if (dblend == DSBF_INVSRCALPHA) dblend = DSBF_ZERO; } - if (dst->content == CAIRO_CONTENT_COLOR) { + if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) { if (sblend == DSBF_DESTALPHA) sblend = DSBF_ONE; else if (sblend == DSBF_INVDESTALPHA) @@ -1164,7 +1228,7 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface r[i].h = rects[i].height; } - RUN_CLIPPED (dst, NULL, + RUN_CLIPPED (dst, NULL, NULL, dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects)); return CAIRO_STATUS_SUCCESS; @@ -1182,7 +1246,8 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps) + int num_traps, + cairo_region_t *clip_region) { cairo_directfb_surface_t *dst = abstract_dst; cairo_directfb_surface_t *src; @@ -1197,6 +1262,9 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op, __FUNCTION__, op, pattern, dst, antialias, src_x, src_y, dst_x, dst_y, width, height, traps, num_traps); + if (! dst->supported_destination) + return CAIRO_INT_STATUS_UNSUPPORTED; + if (antialias != CAIRO_ANTIALIAS_NONE) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1291,7 +1359,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op, D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n"); - RUN_CLIPPED (dst, NULL, + RUN_CLIPPED (dst, clip_region, NULL, dst->dfbsurface->TextureTriangles (dst->dfbsurface, src->dfbsurface, vertex, NULL, n, @@ -1306,64 +1374,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op, } #endif /* DFB_COMPOSITE_TRAPEZOIDS */ -static cairo_int_status_t -_cairo_directfb_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - cairo_directfb_surface_t *surface = abstract_surface; - - D_DEBUG_AT (CairoDFB_Clip, - "%s( surface=%p, region=%p ).\n", - __FUNCTION__, surface, region); - - if (region) { - int n_rects; - cairo_status_t status; - int i; - - surface->has_clip = TRUE; - - n_rects = cairo_region_num_rectangles (region); - - if (n_rects == 0) - return CAIRO_STATUS_SUCCESS; - - if (surface->n_clips != n_rects) { - if (surface->clips) - free (surface->clips); - - surface->clips = _cairo_malloc_ab (n_rects, sizeof (DFBRegion)); - if (!surface->clips) { - surface->n_clips = 0; - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - surface->n_clips = n_rects; - } - - for (i = 0; i < n_rects; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - - surface->clips[i].x1 = rect.x; - surface->clips[i].y1 = rect.y; - surface->clips[i].x2 = rect.x + rect.width - 1; - surface->clips[i].y2 = rect.y + rect.height - 1; - } - } else { - surface->has_clip = FALSE; - if (surface->clips) { - free (surface->clips); - surface->clips = NULL; - surface->n_clips = 0; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t +static cairo_bool_t _cairo_directfb_abstract_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -1383,7 +1394,7 @@ _cairo_directfb_abstract_surface_get_extents (void *abstract_su rectangle->width = surface->width; rectangle->height = surface->height; - return CAIRO_STATUS_SUCCESS; + return TRUE; } #if DFB_SHOW_GLYPHS @@ -1422,6 +1433,7 @@ _directfb_destroy_font_cache (cairo_directfb_font_cache_t *cache) free (cache); } +/* XXX hook into rtree font cache from drm */ static cairo_status_t _directfb_acquire_font_cache (cairo_directfb_surface_t *surface, cairo_scaled_font_t *scaled_font, @@ -1473,6 +1485,7 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface, case CAIRO_FORMAT_A8: case CAIRO_FORMAT_ARGB32: break; + case CAIRO_FORMAT_RGB24: default: D_DEBUG_AT (CairoDFB_Font, " -> Unsupported font format %d!\n", img->format); @@ -1705,8 +1718,8 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_directfb_surface_t *dst = abstract_dst; cairo_directfb_font_cache_t *cache; @@ -1718,28 +1731,29 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst, DFBPoint points[num_glyphs]; int num; const cairo_color_t *color; - + cairo_region_t *clip_region = NULL; D_DEBUG_AT (CairoDFB_Font, "%s( dst=%p, op=%d, pattern=%p, glyphs=%p, num_glyphs=%d, scaled_font=%p ).\n", __FUNCTION__, dst, op, pattern, glyphs, num_glyphs, scaled_font); + if (! dst->supported_destination) + return CAIRO_INT_STATUS_UNSUPPORTED; + if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) return CAIRO_INT_STATUS_UNSUPPORTED; /* Fallback if we need to emulate clip regions */ - if (dst->base.clip && - (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION || - dst->base.clip->surface != NULL)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO); + if (status) + return status; } /* XXX Unbounded operators are not handled correctly */ if (! _cairo_operator_bounded_by_mask (op)) return CAIRO_INT_STATUS_UNSUPPORTED; - if (! _cairo_operator_bounded_by_source (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; if (! _directfb_get_operator (op, &sblend, &dblend) || sblend == DSBF_DESTALPHA || sblend == DSBF_INVDESTALPHA) @@ -1788,7 +1802,7 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst, D_DEBUG_AT (CairoDFB_Font, "Running BatchBlit().\n"); - RUN_CLIPPED (dst, NULL, + RUN_CLIPPED (dst, clip_region, NULL, dst->dfbsurface->BatchBlit (dst->dfbsurface, cache->dfbsurface, rects, points, num)); @@ -1835,8 +1849,6 @@ _cairo_directfb_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - _cairo_directfb_surface_set_clip_region,/* set_clip_region */ - NULL, /* intersect_clip_path */ _cairo_directfb_abstract_surface_get_extents,/* get_extents */ NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -1860,7 +1872,6 @@ _cairo_directfb_surface_backend = { #endif NULL, /* snapshot */ _cairo_directfb_surface_is_similar, - NULL /* reset */ }; @@ -1933,8 +1944,8 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface) dfbsurface->GetSize (dfbsurface, &surface->width, &surface->height); surface->dfb = dfb; surface->dfbsurface = dfbsurface; - surface->format = _directfb_to_cairo_format (format); - surface->content = _directfb_format_to_content (format); + surface->pixman_format = _directfb_to_pixman_format (format); + surface->supported_destination = pixman_format_supported_destination (surface->pixman_format); dfbsurface->GetCapabilities (dfbsurface, &caps); if (caps & DSCAPS_PREMULTIPLIED) @@ -1942,7 +1953,7 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface) _cairo_surface_init (&surface->base, &_cairo_directfb_surface_backend, - surface->content); + _directfb_format_to_content (format)); return &surface->base; } diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 6c6ff59ff..26f4a8332 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -1146,7 +1146,7 @@ _render_glyph_bitmap (FT_Face face, cairo_image_surface_t **surface) { FT_GlyphSlot glyphslot = face->glyph; - cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_status_t status; FT_Error error; /* According to the FreeType docs, glyphslot->format could be @@ -1162,7 +1162,9 @@ _render_glyph_bitmap (FT_Face face, if (error == FT_Err_Out_Of_Memory) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface); + status = _get_bitmap_surface (&glyphslot->bitmap, + FALSE, font_options, + surface); if (unlikely (status)) return status; @@ -1177,7 +1179,7 @@ _render_glyph_bitmap (FT_Face face, -glyphslot->bitmap_left, +glyphslot->bitmap_top); - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -1275,11 +1277,8 @@ _transform_glyph_bitmap (cairo_matrix_t * shape, _cairo_pattern_init_for_surface (&pattern, &(*surface)->base); cairo_pattern_set_matrix (&pattern.base, &transformed_to_original); - status = _cairo_surface_composite (CAIRO_OPERATOR_OVER, - &pattern.base, NULL, image, - 0, 0, 0, 0, 0, 0, - width, - height); + status = _cairo_surface_paint (image, CAIRO_OPERATOR_OVER, + &pattern.base, NULL); _cairo_pattern_fini (&pattern.base); @@ -1301,7 +1300,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape, cairo_surface_set_device_offset (&(*surface)->base, _cairo_lround (origin_x), _cairo_lround (origin_y)); - return status; + return CAIRO_STATUS_SUCCESS; } static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = { @@ -1390,8 +1389,8 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret) ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; } -#ifdef FC_HINT_STYLE - if (FcPatternGetInteger (pattern, +#ifdef FC_HINT_STYLE + if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) hintstyle = FC_HINT_FULL; @@ -1400,7 +1399,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret) switch (hintstyle) { case FC_HINT_NONE: - ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; + ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; break; case FC_HINT_SLIGHT: ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT; @@ -1444,14 +1443,14 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret) if (vertical_layout) ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT; - + #ifndef FC_EMBOLDEN #define FC_EMBOLDEN "embolden" #endif if (FcPatternGetBool (pattern, FC_EMBOLDEN, 0, &embolden) != FcResultMatch) embolden = FcFalse; - + if (embolden) ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN; @@ -1468,7 +1467,7 @@ _cairo_ft_options_merge (cairo_ft_options_t *options, /* clear load target mode */ load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags))); - + if (load_flags & FT_LOAD_NO_HINTING) other->base.hint_style = CAIRO_HINT_STYLE_NONE; @@ -1479,7 +1478,7 @@ _cairo_ft_options_merge (cairo_ft_options_t *options, } if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL && - (options->base.antialias == CAIRO_ANTIALIAS_DEFAULT || + (options->base.antialias == CAIRO_ANTIALIAS_DEFAULT || options->base.antialias == CAIRO_ANTIALIAS_GRAY)) { options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; options->base.subpixel_order = other->base.subpixel_order; @@ -1934,12 +1933,12 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, x2 = (metrics->horiBearingX + metrics->width + 63) & -64; y1 = (-metrics->horiBearingY) & -64; y2 = (-metrics->horiBearingY + metrics->height + 63) & -64; - + advance = ((metrics->horiAdvance + 32) & -64); - + fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor; fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor; - + fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor; fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor; @@ -1950,12 +1949,12 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, x2 = (metrics->vertBearingX + metrics->width + 63) & -64; y1 = (metrics->vertBearingY) & -64; y2 = (metrics->vertBearingY + metrics->height + 63) & -64; - + advance = ((metrics->vertAdvance + 32) & -64); - + fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor; fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor; - + fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor; fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor; @@ -1969,7 +1968,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, if (!vertical_layout) { fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor; fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor; - + if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE) fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor; else @@ -1978,7 +1977,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, } else { fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor; fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor; - + fs_metrics.x_advance = 0 * x_factor; if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE) fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor; @@ -2154,7 +2153,7 @@ static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = { _cairo_ft_scaled_glyph_init, NULL, /* text_to_glyphs */ _cairo_ft_ucs4_to_index, - NULL, /* show_glyphs */ + NULL, /* show_glyphs */ _cairo_ft_load_truetype_table, _cairo_ft_index_to_ucs4 }; @@ -2911,10 +2910,10 @@ cairo_bool_t _cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font) { cairo_ft_scaled_font_t *ft_scaled_font; - + if (!_cairo_scaled_font_is_ft (scaled_font)) return FALSE; - + ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font; if (ft_scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT) return TRUE; diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index 3d37fe091..5d8ff603c 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -56,6 +56,7 @@ typedef struct _cairo_gl_surface { int width, height; GLuint tex; /* GL texture object containing our data. */ + GLuint depth_stencil_tex; GLuint fb; /* GL framebuffer object wrapping our data. */ } cairo_gl_surface_t; diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c index 571fc9636..92c670d3e 100644 --- a/src/cairo-gl-surface.c +++ b/src/cairo-gl-surface.c @@ -312,6 +312,10 @@ _cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format, case PIXMAN_g1: case PIXMAN_yuy2: case PIXMAN_yv12: +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16) + case PIXMAN_x2r10g10b10: + case PIXMAN_a2r10g10b10: +#endif default: return CAIRO_INT_STATUS_UNSUPPORTED; } @@ -766,6 +770,8 @@ _cairo_gl_surface_finish (void *abstract_surface) glDeleteFramebuffersEXT (1, &surface->fb); glDeleteTextures (1, &surface->tex); + if (surface->depth_stencil_tex) + glDeleteTextures (1, &surface->depth_stencil_tex); if (surface->ctx->current_target == surface) surface->ctx->current_target = NULL; @@ -1264,16 +1270,20 @@ _cairo_gl_surface_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_gl_surface_t *dst = abstract_dst; cairo_surface_attributes_t *src_attributes, *mask_attributes = NULL; cairo_gl_context_t *ctx; - GLfloat vertices[4][2]; - GLfloat texcoord_src[4][2]; - GLfloat texcoord_mask[4][2]; + struct gl_point { + GLfloat x, y; + } vertices_stack[8], texcoord_src_stack[8], texcoord_mask_stack[8]; + struct gl_point *vertices = vertices_stack; + struct gl_point *texcoord_src = texcoord_src_stack; + struct gl_point *texcoord_mask = texcoord_mask_stack; cairo_status_t status; - int i; + int num_vertices, i; GLenum err; cairo_gl_composite_setup_t setup; @@ -1345,27 +1355,62 @@ _cairo_gl_surface_composite (cairo_operator_t op, } } - vertices[0][0] = dst_x; - vertices[0][1] = dst_y; - vertices[1][0] = dst_x + width; - vertices[1][1] = dst_y; - vertices[2][0] = dst_x + width; - vertices[2][1] = dst_y + height; - vertices[3][0] = dst_x; - vertices[3][1] = dst_y + height; + if (clip_region != NULL) { + int num_rectangles; + + num_rectangles = cairo_region_num_rectangles (clip_region); + if (num_rectangles * 4 > ARRAY_LENGTH (vertices_stack)) { + vertices = _cairo_malloc_ab (num_rectangles, + 4*3*sizeof (vertices[0])); + if (unlikely (vertices == NULL)) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto CONTEXT_RELEASE; + } + + texcoord_src = vertices + num_rectangles * 4; + texcoord_mask = texcoord_src + num_rectangles * 4; + } + + for (i = 0; i < num_rectangles; i++) { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (clip_region, i, &rect); + vertices[4*i + 0].x = rect.x; + vertices[4*i + 0].y = rect.y; + vertices[4*i + 1].x = rect.x + rect.width; + vertices[4*i + 1].y = rect.y; + vertices[4*i + 2].x = rect.x + rect.width; + vertices[4*i + 2].y = rect.y + rect.height; + vertices[4*i + 3].x = rect.x; + vertices[4*i + 3].y = rect.y + rect.height; + } + + num_vertices = 4 * num_rectangles; + } else { + vertices[0].x = dst_x; + vertices[0].y = dst_y; + vertices[1].x = dst_x + width; + vertices[1].y = dst_y; + vertices[2].x = dst_x + width; + vertices[2].y = dst_y + height; + vertices[3].x = dst_x; + vertices[3].y = dst_y + height; + + num_vertices = 4; + } glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, vertices); glEnableClientState (GL_VERTEX_ARRAY); if (setup.src.type == OPERAND_TEXTURE) { - for (i = 0; i < 4; i++) { + for (i = 0; i < num_vertices; i++) { double s, t; - s = vertices[i][0]; - t = vertices[i][1]; + s = vertices[i].x; + t = vertices[i].y; cairo_matrix_transform_point (&src_attributes->matrix, &s, &t); - texcoord_src[i][0] = s; - texcoord_src[i][1] = t; + texcoord_src[i].x = s; + texcoord_src[i].y = t; } glClientActiveTexture (GL_TEXTURE0); @@ -1375,14 +1420,14 @@ _cairo_gl_surface_composite (cairo_operator_t op, if (mask != NULL) { if (setup.mask.type == OPERAND_TEXTURE) { - for (i = 0; i < 4; i++) { + for (i = 0; i < num_vertices; i++) { double s, t; - s = vertices[i][0]; - t = vertices[i][1]; + s = vertices[i].x; + t = vertices[i].y; cairo_matrix_transform_point (&mask_attributes->matrix, &s, &t); - texcoord_mask[i][0] = s; - texcoord_mask[i][1] = t; + texcoord_mask[i].x = s; + texcoord_mask[i].y = t; } glClientActiveTexture (GL_TEXTURE1); @@ -1391,7 +1436,7 @@ _cairo_gl_surface_composite (cairo_operator_t op, } } - glDrawArrays (GL_TRIANGLE_FAN, 0, 4); + glDrawArrays (GL_QUADS, 0, num_vertices); glDisable (GL_BLEND); @@ -1410,13 +1455,17 @@ _cairo_gl_surface_composite (cairo_operator_t op, while ((err = glGetError ())) fprintf (stderr, "GL error 0x%08x\n", (int) err); + CONTEXT_RELEASE: _cairo_gl_context_release (ctx); _cairo_gl_operand_destroy (&setup.src); if (mask != NULL) _cairo_gl_operand_destroy (&setup.mask); - return CAIRO_STATUS_SUCCESS; + if (vertices != vertices_stack) + free (vertices); + + return status; } static cairo_int_status_t @@ -1429,7 +1478,8 @@ _cairo_gl_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps) + int num_traps, + cairo_region_t *clip_region) { cairo_gl_surface_t *dst = abstract_dst; cairo_surface_pattern_t traps_pattern; @@ -1447,7 +1497,8 @@ _cairo_gl_surface_composite_trapezoids (cairo_operator_t op, src_x, src_y, 0, 0, dst_x, dst_y, - width, height); + width, height, + clip_region); _cairo_pattern_fini (&traps_pattern.base); @@ -1737,6 +1788,7 @@ _cairo_gl_surface_span_renderer_finish (void *abstract_renderer) glDisable (GL_TEXTURE_2D); glDisable (GL_BLEND); + glDisable (GL_DEPTH_TEST); return CAIRO_STATUS_SUCCESS; } @@ -1756,27 +1808,112 @@ _cairo_gl_surface_check_span_renderer (cairo_operator_t op, return TRUE; } +static void +_cairo_gl_surface_ensure_depth_buffer (cairo_gl_surface_t *surface) +{ + if (surface->depth_stencil_tex) + return; + + glGenTextures (1, &surface->depth_stencil_tex); + glBindTexture (GL_TEXTURE_2D, surface->depth_stencil_tex); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, + surface->width, surface->height, 0, + GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL); + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_TEXTURE_2D, + surface->depth_stencil_tex, 0); + glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, + GL_STENCIL_ATTACHMENT_EXT, + GL_TEXTURE_2D, + surface->depth_stencil_tex, 0); +} + + +static cairo_status_t +_cairo_gl_surface_set_clip_region (cairo_gl_surface_t *surface, + cairo_region_t *clip_region) +{ + GLfloat vertices_stack[CAIRO_STACK_ARRAY_LENGTH(GLfloat)], *vertices; + int num_rectangles, i, n; + + if (clip_region == NULL) + return CAIRO_STATUS_SUCCESS; + + num_rectangles = cairo_region_num_rectangles (clip_region); + + vertices = vertices_stack; + if (num_rectangles * 8 > ARRAY_LENGTH (vertices_stack)) { + vertices = _cairo_malloc_ab (num_rectangles, + 4*3*sizeof (vertices[0])); + if (unlikely (vertices == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } + + for (i = n = 0; i < num_rectangles; i++) { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (clip_region, i, &rect); + vertices[n++] = rect.x; + vertices[n++] = rect.y; + vertices[n++] = rect.x + rect.width; + vertices[n++] = rect.y; + vertices[n++] = rect.x + rect.width; + vertices[n++] = rect.y + rect.height; + vertices[n++] = rect.x; + vertices[n++] = rect.y +rect. height; + } + + _cairo_gl_surface_ensure_depth_buffer (surface); + + glDisable (GL_BLEND); + glDepthFunc (GL_ALWAYS); + glEnable (GL_DEPTH_TEST); + glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + glDepthMask (GL_TRUE); + glClear (GL_DEPTH_BUFFER_BIT); + + glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, vertices); + glEnableClientState (GL_VERTEX_ARRAY); + glDrawArrays (GL_QUADS, 0, 4 * num_rectangles); + glDisableClientState (GL_VERTEX_ARRAY); + + glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthFunc (GL_EQUAL); + glDepthMask (GL_FALSE); + + if (vertices != vertices_stack) + free (vertices); + + return CAIRO_STATUS_SUCCESS; +} + static cairo_span_renderer_t * _cairo_gl_surface_create_span_renderer (cairo_operator_t op, const cairo_pattern_t *src, void *abstract_dst, cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects) + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region) { cairo_gl_surface_t *dst = abstract_dst; - cairo_gl_surface_span_renderer_t *renderer = calloc (1, sizeof (*renderer)); + cairo_gl_surface_span_renderer_t *renderer; cairo_status_t status; int width = rects->width; int height = rects->height; cairo_surface_attributes_t *src_attributes; GLenum err; - if (renderer == NULL) - return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); - if (!GLEW_ARB_vertex_buffer_object) return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED); + renderer = calloc (1, sizeof (*renderer)); + if (unlikely (renderer == NULL)) + return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); + renderer->base.destroy = _cairo_gl_surface_span_renderer_destroy; renderer->base.finish = _cairo_gl_surface_span_renderer_finish; renderer->base.render_row = @@ -1801,6 +1938,12 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op, _cairo_gl_set_destination (dst); + status = _cairo_gl_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) { + _cairo_gl_surface_span_renderer_destroy (renderer); + return _cairo_span_renderer_create_in_error (status); + } + src_attributes = &renderer->setup.src.operand.texture.attributes; status = _cairo_gl_set_operator (dst, op); @@ -1838,7 +1981,7 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op, return &renderer->base; } -static cairo_int_status_t +static cairo_bool_t _cairo_gl_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -1849,7 +1992,7 @@ _cairo_gl_surface_get_extents (void *abstract_surface, rectangle->width = surface->width; rectangle->height = surface->height; - return CAIRO_STATUS_SUCCESS; + return TRUE; } static void @@ -1888,20 +2031,21 @@ static const cairo_surface_backend_t _cairo_gl_surface_backend = { CAIRO_SURFACE_TYPE_GL, _cairo_gl_surface_create_similar, _cairo_gl_surface_finish, + _cairo_gl_surface_acquire_source_image, _cairo_gl_surface_release_source_image, _cairo_gl_surface_acquire_dest_image, _cairo_gl_surface_release_dest_image, + _cairo_gl_surface_clone_similar, _cairo_gl_surface_composite, _cairo_gl_surface_fill_rectangles, _cairo_gl_surface_composite_trapezoids, _cairo_gl_surface_create_span_renderer, _cairo_gl_surface_check_span_renderer, + NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - NULL, /* intersect_clip_path */ _cairo_gl_surface_get_extents, NULL, /* old_show_glyphs */ _cairo_gl_surface_get_font_options, diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 818812905..a649d5001 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -27,6 +27,7 @@ #include "cairoint.h" #include "cairo-glitz.h" #include "cairo-glitz-private.h" +#include "cairo-region-private.h" typedef struct _cairo_glitz_surface { cairo_surface_t base; @@ -34,6 +35,7 @@ typedef struct _cairo_glitz_surface { glitz_surface_t *surface; glitz_format_t *format; + cairo_region_t *clip_region; cairo_bool_t has_clip; glitz_box_t *clip_boxes; int num_clip_boxes; @@ -50,6 +52,7 @@ _cairo_glitz_surface_finish (void *abstract_surface) if (surface->clip_boxes) free (surface->clip_boxes); + cairo_region_destroy (surface->clip_region); glitz_surface_destroy (surface->surface); return CAIRO_STATUS_SUCCESS; @@ -106,43 +109,6 @@ _cairo_glitz_surface_create_similar (void *abstract_src, return crsurface; } -static cairo_status_t -_cairo_glitz_get_boxes_from_region (cairo_region_t *region, - glitz_box_t **boxes, - int *nboxes) -{ - pixman_box32_t *pboxes; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - int n, i; - - n = 0; - pboxes = pixman_region32_rectangles (®ion->rgn, &n); - if (n == 0) { - *nboxes = 0; - return CAIRO_STATUS_SUCCESS; - } - - if (n > *nboxes) { - *boxes = _cairo_malloc_ab (n, sizeof (glitz_box_t)); - if (*boxes == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto done; - } - } - - for (i = 0; i < n; i++) { - (*boxes)[i].x1 = pboxes[i].x1; - (*boxes)[i].y1 = pboxes[i].y1; - (*boxes)[i].x2 = pboxes[i].x2; - (*boxes)[i].y2 = pboxes[i].y2; - } - - *nboxes = n; -done: - return status; -} - static cairo_status_t _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface, cairo_rectangle_int_t *interest, @@ -463,6 +429,8 @@ _is_supported_operator (cairo_operator_t op) case CAIRO_OPERATOR_ADD: return TRUE; + default: + ASSERT_NOT_REACHED; case CAIRO_OPERATOR_SATURATE: /* nobody likes saturate, expect that it's required to do * seamless polygons! @@ -485,6 +453,7 @@ _is_supported_operator (cairo_operator_t op) return FALSE; } } + static glitz_operator_t _glitz_operator (cairo_operator_t op) { @@ -686,9 +655,9 @@ _cairo_glitz_pattern_acquire_surface (const cairo_pattern_t *pattern, } src = (cairo_glitz_surface_t *) - _cairo_surface_create_similar_scratch (&dst->base, - CAIRO_CONTENT_COLOR_ALPHA, - gradient->n_stops, 1); + _cairo_glitz_surface_create_similar (&dst->base, + CAIRO_CONTENT_COLOR_ALPHA, + gradient->n_stops, 1); if (src->base.status) { glitz_buffer_destroy (buffer); free (data); @@ -914,6 +883,77 @@ _cairo_glitz_surface_set_attributes (cairo_glitz_surface_t *surface, a->params, a->n_params); } +static cairo_status_t +_cairo_glitz_get_boxes_from_region (cairo_region_t *region, + glitz_box_t **boxes, + int *nboxes) +{ + pixman_box32_t *pboxes; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + + int n, i; + + n = 0; + pboxes = pixman_region32_rectangles (®ion->rgn, &n); + if (n == 0) { + *nboxes = 0; + return CAIRO_STATUS_SUCCESS; + } + + if (n > *nboxes) { + *boxes = _cairo_malloc_ab (n, sizeof (glitz_box_t)); + if (*boxes == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto done; + } + } + + for (i = 0; i < n; i++) { + (*boxes)[i].x1 = pboxes[i].x1; + (*boxes)[i].y1 = pboxes[i].y1; + (*boxes)[i].x2 = pboxes[i].x2; + (*boxes)[i].y2 = pboxes[i].y2; + } + + *nboxes = n; +done: + return status; +} + +static cairo_status_t +_cairo_glitz_surface_set_clip_region (void *abstract_surface, + cairo_region_t *region) +{ + cairo_glitz_surface_t *surface = abstract_surface; + + if (region == surface->clip_region) + return CAIRO_STATUS_SUCCESS; + + cairo_region_destroy (surface->clip_region); + surface->clip_region = cairo_region_reference (region); + + if (region != NULL) { + cairo_status_t status; + + status = _cairo_glitz_get_boxes_from_region (region, + &surface->clip_boxes, + &surface->num_clip_boxes); + if (status) + return status; + + glitz_surface_set_clip_region (surface->surface, + 0, 0, + surface->clip_boxes, + surface->num_clip_boxes); + surface->has_clip = TRUE; + } else { + glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0); + surface->has_clip = FALSE; + } + + return CAIRO_STATUS_SUCCESS; +} + static cairo_int_status_t _cairo_glitz_surface_composite (cairo_operator_t op, const cairo_pattern_t *src_pattern, @@ -926,7 +966,8 @@ _cairo_glitz_surface_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_glitz_surface_attributes_t src_attr, mask_attr; cairo_glitz_surface_t *dst = abstract_dst; @@ -940,6 +981,10 @@ _cairo_glitz_surface_composite (cairo_operator_t op, if (_glitz_ensure_target (dst->surface)) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_glitz_surface_set_clip_region (dst, clip_region); + if (status) + return status; + status = _cairo_glitz_pattern_acquire_surfaces (src_pattern, mask_pattern, dst, src_x, src_y, @@ -1006,7 +1051,8 @@ _cairo_glitz_surface_composite (cairo_operator_t op, mask_width, mask_height, src_x, src_y, mask_x, mask_y, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); } if (mask) @@ -1037,11 +1083,15 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, glitz_rectangle_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (glitz_rectangle_t)]; glitz_rectangle_t *glitz_rects = stack_rects; glitz_rectangle_t *current_rect; + cairo_status_t status; int i; if (! _is_supported_operator (op)) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_glitz_surface_set_clip_region (dst, NULL); + assert (status == CAIRO_STATUS_SUCCESS); + if (n_rects > ARRAY_LENGTH (stack_rects)) { glitz_rects = _cairo_malloc_ab (n_rects, sizeof (glitz_rectangle_t)); if (glitz_rects == NULL) @@ -1104,12 +1154,12 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, _cairo_surface_create_similar_solid (&dst->base, CAIRO_CONTENT_COLOR_ALPHA, 1, 1, - (cairo_color_t *) color); - if (src->base.status) - { + (cairo_color_t *) color, + FALSE); + if (src == NULL || src->base.status) { if (glitz_rects != stack_rects) free (glitz_rects); - return src->base.status; + return src ? src->base.status : CAIRO_INT_STATUS_UNSUPPORTED; } glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT); @@ -1153,7 +1203,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int n_traps) + int n_traps, + cairo_region_t *clip_region) { cairo_glitz_surface_attributes_t attributes; cairo_glitz_surface_t *dst = abstract_dst; @@ -1179,6 +1230,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, if (_glitz_ensure_target (dst->surface)) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_glitz_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + return status; + /* Convert traps to pixman traps */ if (n_traps > ARRAY_LENGTH (stack_traps)) { pixman_traps = _cairo_malloc_ab (n_traps, sizeof (pixman_trapezoid_t)); @@ -1321,7 +1376,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, n_traps, (pixman_trapezoid_t *) pixman_traps); mask = (cairo_glitz_surface_t *) - _cairo_surface_create_similar_scratch (&dst->base, + _cairo_glitz_surface_create_similar (&dst->base, CAIRO_CONTENT_ALPHA, width, height); status = mask->base.status; @@ -1378,7 +1433,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, src_x, src_y, 0, 0, dst_x, dst_y, - width, height); + width, height, + clip_region); } FAIL: @@ -1393,35 +1449,7 @@ FAIL: return status; } -static cairo_int_status_t -_cairo_glitz_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - cairo_glitz_surface_t *surface = abstract_surface; - - if (region != NULL) { - cairo_status_t status; - - status = _cairo_glitz_get_boxes_from_region (region, - &surface->clip_boxes, - &surface->num_clip_boxes); - if (status) - return status; - - glitz_surface_set_clip_region (surface->surface, - 0, 0, - surface->clip_boxes, - surface->num_clip_boxes); - surface->has_clip = TRUE; - } else { - glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0); - surface->has_clip = FALSE; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t +static cairo_bool_t _cairo_glitz_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -1432,7 +1460,7 @@ _cairo_glitz_surface_get_extents (void *abstract_surface, rectangle->width = glitz_surface_get_width (surface->surface); rectangle->height = glitz_surface_get_height (surface->surface); - return CAIRO_STATUS_SUCCESS; + return TRUE; } #define CAIRO_GLITZ_AREA_AVAILABLE 0 @@ -2035,7 +2063,8 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, unsigned int width, unsigned int height, cairo_glyph_t *glyphs, - int num_glyphs) + int num_glyphs, + cairo_region_t *clip_region) { cairo_glitz_surface_attributes_t attributes; cairo_glitz_surface_glyph_private_t *glyph_private; @@ -2078,6 +2107,10 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, if (_glitz_ensure_target (dst->surface)) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_glitz_surface_set_clip_region (dst, NULL); + if (unlikely (status)) + return status; + status = _cairo_glitz_pattern_acquire_surface (pattern, dst, src_x, src_y, width, height, @@ -2326,25 +2359,13 @@ _cairo_glitz_surface_is_similar (void *surface_a, return drawable_a == drawable_b; } -static cairo_status_t -_cairo_glitz_surface_reset (void *abstract_surface) -{ - cairo_glitz_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_glitz_surface_set_clip_region (surface, NULL); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; -} - static const cairo_surface_backend_t cairo_glitz_surface_backend = { CAIRO_SURFACE_TYPE_GLITZ, _cairo_glitz_surface_create_similar, _cairo_glitz_surface_finish, _cairo_glitz_surface_acquire_source_image, _cairo_glitz_surface_release_source_image, + _cairo_glitz_surface_acquire_dest_image, _cairo_glitz_surface_release_dest_image, _cairo_glitz_surface_clone_similar, @@ -2353,10 +2374,9 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = { _cairo_glitz_surface_composite_trapezoids, NULL, /* create_span_renderer */ NULL, /* check_span_renderer */ + NULL, /* copy_page */ NULL, /* show_page */ - _cairo_glitz_surface_set_clip_region, - NULL, /* intersect_clip_path */ _cairo_glitz_surface_get_extents, _cairo_glitz_surface_old_show_glyphs, NULL, /* get_font_options */ @@ -2373,8 +2393,6 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = { _cairo_glitz_surface_snapshot, _cairo_glitz_surface_is_similar, - - _cairo_glitz_surface_reset }; static const cairo_surface_backend_t * @@ -2424,6 +2442,7 @@ cairo_glitz_surface_create (glitz_surface_t *surface) crsurface->has_clip = FALSE; crsurface->clip_boxes = NULL; crsurface->num_clip_boxes = 0; + crsurface->clip_region = NULL; return &crsurface->base; } diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 8f206ad9a..2257db0f7 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -100,7 +100,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate, _cairo_font_options_init_default (&gstate->font_options); - _cairo_clip_init (&gstate->clip, target); + _cairo_clip_init (&gstate->clip); gstate->target = cairo_surface_reference (target); gstate->parent_target = NULL; @@ -164,14 +164,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) _cairo_font_options_init_copy (&gstate->font_options , &other->font_options); - status = _cairo_clip_init_copy (&gstate->clip, &other->clip); - if (unlikely (status)) { - _cairo_stroke_style_fini (&gstate->stroke_style); - cairo_font_face_destroy (gstate->font_face); - cairo_scaled_font_destroy (gstate->scaled_font); - cairo_scaled_font_destroy (gstate->previous_scaled_font); - return status; - } + _cairo_clip_init_copy (&gstate->clip, &other->clip); gstate->target = cairo_surface_reference (other->target); /* parent_target is always set to NULL; it's only ever set by redirect_target */ @@ -299,7 +292,7 @@ _cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist) cairo_status_t _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child) { - cairo_status_t status; + cairo_matrix_t matrix; /* If this gstate is already redirected, this is an error; we need a * new gstate to be able to redirect */ @@ -315,18 +308,15 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child) * since its ref is now owned by gstate->parent_target */ gstate->target = cairo_surface_reference (child); - _cairo_clip_reset (&gstate->clip); - status = _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child); - if (unlikely (status)) - return status; - /* The clip is in surface backend coordinates for the previous target; * translate it into the child's backend coordinates. */ - _cairo_clip_translate (&gstate->clip, - _cairo_fixed_from_double (child->device_transform.x0 - gstate->parent_target->device_transform.x0), - _cairo_fixed_from_double (child->device_transform.y0 - gstate->parent_target->device_transform.y0)); - - return CAIRO_STATUS_SUCCESS; + cairo_matrix_init_translate (&matrix, + child->device_transform.x0 - gstate->parent_target->device_transform.x0, + child->device_transform.y0 - gstate->parent_target->device_transform.y0); + _cairo_clip_reset (&gstate->clip); + return _cairo_clip_init_copy_transformed (&gstate->clip, + &gstate->next->clip, + &matrix); } /** @@ -870,43 +860,63 @@ _cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate, &gstate->ctm_inverse); } +#define _gstate_get_clip(g) ((g)->clip.path ? &(g)->clip : NULL) + +static cairo_bool_t +_clipped (const cairo_gstate_t *gstate) +{ + cairo_rectangle_int_t extents; + + if (gstate->clip.all_clipped) + return TRUE; + + if (gstate->clip.path == NULL) + return FALSE; + + if (_cairo_surface_get_extents (gstate->target, &extents)) { + if (! _cairo_rectangle_intersect (&extents, + &gstate->clip.path->extents)) + { + return TRUE; + } + } + + return FALSE; +} + cairo_status_t _cairo_gstate_paint (cairo_gstate_t *gstate) { - cairo_status_t status; cairo_pattern_union_t pattern; - if (gstate->source->status) + if (unlikely (gstate->source->status)) return gstate->source->status; - status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (unlikely (status)) - return status; + if (_clipped (gstate)) + return CAIRO_STATUS_SUCCESS; _cairo_gstate_copy_transformed_source (gstate, &pattern.base); return _cairo_surface_paint (gstate->target, gstate->op, &pattern.base, - NULL); + _gstate_get_clip (gstate)); } cairo_status_t _cairo_gstate_mask (cairo_gstate_t *gstate, cairo_pattern_t *mask) { - cairo_status_t status; cairo_pattern_union_t source_pattern, mask_pattern; - if (mask->status) + if (unlikely (mask->status)) return mask->status; - if (gstate->source->status) + if (unlikely (gstate->source->status)) return gstate->source->status; - status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (unlikely (status)) - return status; + if (_clipped (gstate)) + return CAIRO_STATUS_SUCCESS; _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask); @@ -915,24 +925,22 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, gstate->op, &source_pattern.base, &mask_pattern.base, - NULL); + _gstate_get_clip (gstate)); } cairo_status_t _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { - cairo_status_t status; cairo_pattern_union_t source_pattern; - if (gstate->source->status) + if (unlikely (gstate->source->status)) return gstate->source->status; if (gstate->stroke_style.line_width <= 0.0) return CAIRO_STATUS_SUCCESS; - status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (unlikely (status)) - return status; + if (_clipped (gstate)) + return CAIRO_STATUS_SUCCESS; _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); @@ -945,7 +953,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) &gstate->ctm_inverse, gstate->tolerance, gstate->antialias, - NULL); + _gstate_get_clip (gstate)); } cairo_status_t @@ -1009,15 +1017,26 @@ BAIL: cairo_status_t _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { - cairo_status_t status; cairo_pattern_union_t pattern; - if (gstate->source->status) + if (unlikely (gstate->source->status)) return gstate->source->status; - status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (unlikely (status)) - return status; + if (_clipped (gstate)) + return CAIRO_STATUS_SUCCESS; + + if (_cairo_path_fixed_fill_is_empty (path)) { + if (_cairo_operator_bounded_by_mask (gstate->op)) + return CAIRO_STATUS_SUCCESS; + + _cairo_pattern_init_solid (&pattern.solid, + CAIRO_COLOR_TRANSPARENT, + CAIRO_CONTENT_COLOR_ALPHA); + return _cairo_surface_paint (gstate->target, + CAIRO_OPERATOR_CLEAR, + &pattern.base, + _gstate_get_clip (gstate)); + } _cairo_gstate_copy_transformed_source (gstate, &pattern.base); @@ -1028,23 +1047,56 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) gstate->fill_rule, gstate->tolerance, gstate->antialias, - NULL); + _gstate_get_clip (gstate)); } -void +cairo_bool_t _cairo_gstate_in_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path, double x, - double y, - cairo_bool_t *inside_ret) + double y) { _cairo_gstate_user_to_backend (gstate, &x, &y); - _cairo_path_fixed_in_fill (path, - gstate->fill_rule, - gstate->tolerance, - x, y, - inside_ret); + return _cairo_path_fixed_in_fill (path, + gstate->fill_rule, + gstate->tolerance, + x, y); +} + +cairo_bool_t +_cairo_gstate_in_clip (cairo_gstate_t *gstate, + double x, + double y) +{ + cairo_clip_path_t *clip_path; + + if (gstate->clip.all_clipped) + return FALSE; + + clip_path = gstate->clip.path; + if (clip_path == NULL) + return TRUE; + + _cairo_gstate_user_to_backend (gstate, &x, &y); + + if (x < clip_path->extents.x || + x >= clip_path->extents.x + clip_path->extents.width || + y < clip_path->extents.y || + y >= clip_path->extents.y + clip_path->extents.height) + { + return FALSE; + } + + do { + if (! _cairo_path_fixed_in_fill (&clip_path->path, + clip_path->fill_rule, + clip_path->tolerance, + x, y)) + return FALSE; + } while ((clip_path = clip_path->prev) != NULL); + + return TRUE; } cairo_status_t @@ -1179,26 +1231,31 @@ cairo_status_t _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { return _cairo_clip_clip (&gstate->clip, - path, gstate->fill_rule, gstate->tolerance, - gstate->antialias, gstate->target); + path, gstate->fill_rule, + gstate->tolerance, gstate->antialias); } -static cairo_status_t +static cairo_bool_t _cairo_gstate_int_clip_extents (cairo_gstate_t *gstate, cairo_rectangle_int_t *extents) { - cairo_status_t status; + const cairo_rectangle_int_t *clip_extents; + cairo_bool_t is_bounded; - status = _cairo_surface_get_extents (gstate->target, extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (gstate->target, extents); - status = _cairo_clip_intersect_to_rectangle (&gstate->clip, extents); + clip_extents = _cairo_clip_get_extents (&gstate->clip); + if (clip_extents != NULL) { + cairo_bool_t is_empty; - return status; + is_empty = _cairo_rectangle_intersect (extents, clip_extents); + is_bounded = TRUE; + } + + return is_bounded; } -cairo_status_t +cairo_bool_t _cairo_gstate_clip_extents (cairo_gstate_t *gstate, double *x1, double *y1, @@ -1207,11 +1264,9 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate, { cairo_rectangle_int_t extents; double px1, py1, px2, py2; - cairo_status_t status; - status = _cairo_gstate_int_clip_extents (gstate, &extents); - if (unlikely (status)) - return status; + if (! _cairo_gstate_int_clip_extents (gstate, &extents)) + return FALSE; px1 = extents.x; py1 = extents.y; @@ -1231,7 +1286,7 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate, if (y2) *y2 = py2; - return CAIRO_STATUS_SUCCESS; + return TRUE; } cairo_rectangle_list_t* @@ -1576,12 +1631,11 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, cairo_text_cluster_t *transformed_clusters; cairo_status_t status; - if (gstate->source->status) + if (unlikely (gstate->source->status)) return gstate->source->status; - status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (unlikely (status)) - return status; + if (_clipped (gstate)) + return CAIRO_STATUS_SUCCESS; status = _cairo_gstate_ensure_scaled_font (gstate); if (unlikely (status)) @@ -1635,7 +1689,8 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, * * Needless to say, do this only if show_text_glyphs is not available. */ if (cairo_surface_has_show_text_glyphs (gstate->target) || - _cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240) { + _cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240) + { status = _cairo_surface_show_text_glyphs (gstate->target, gstate->op, &source_pattern.base, @@ -1643,8 +1698,11 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, transformed_glyphs, num_glyphs, transformed_clusters, num_clusters, cluster_flags, - gstate->scaled_font, NULL); - } else { + gstate->scaled_font, + _gstate_get_clip (gstate)); + } + else + { cairo_path_fixed_t path; _cairo_path_fixed_init (&path); @@ -1653,14 +1711,16 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, transformed_glyphs, num_glyphs, &path); - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_surface_fill (gstate->target, - gstate->op, - &source_pattern.base, - &path, - CAIRO_FILL_RULE_WINDING, - gstate->tolerance, - gstate->scaled_font->options.antialias, NULL); + if (status == CAIRO_STATUS_SUCCESS) { + status = _cairo_surface_fill (gstate->target, + gstate->op, + &source_pattern.base, + &path, + CAIRO_FILL_RULE_WINDING, + gstate->tolerance, + gstate->scaled_font->options.antialias, + _gstate_get_clip (gstate)); + } _cairo_path_fixed_fini (&path); } @@ -1765,17 +1825,12 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate, cairo_matrix_t *device_transform = &gstate->target->device_transform; cairo_bool_t drop = FALSE; double x1 = 0, x2 = 0, y1 = 0, y2 = 0; - cairo_status_t status; if (num_transformed_glyphs != NULL) { cairo_rectangle_int_t surface_extents; drop = TRUE; - status = _cairo_gstate_int_clip_extents (gstate, &surface_extents); - if (_cairo_status_is_error (status)) - return status; - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + if (! _cairo_gstate_int_clip_extents (gstate, &surface_extents)) { drop = FALSE; /* unbounded surface */ } else { double scale10 = 10 * _cairo_scaled_font_get_max_scale (gstate->scaled_font); diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 278654af1..c7ceb2621 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -37,6 +37,9 @@ #include "cairoint.h" +#include "cairo-clip-private.h" +#include "cairo-region-private.h" + static cairo_format_t _cairo_format_from_pixman_format (pixman_format_code_t pixman_format) { @@ -63,6 +66,14 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format) #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9) case PIXMAN_x2b10g10r10: case PIXMAN_a2b10g10r10: +#endif +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,14,1) + case PIXMAN_b8g8r8x8: + case PIXMAN_b8g8r8a8: +#endif +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16) + case PIXMAN_x2r10g10b10: + case PIXMAN_a2r10g10b10: #endif default: return CAIRO_FORMAT_INVALID; @@ -87,6 +98,12 @@ _cairo_content_from_pixman_format (pixman_format_code_t pixman_format) case PIXMAN_a1b1g1r1: #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9) case PIXMAN_a2b10g10r10: +#endif +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,14,1) + case PIXMAN_b8g8r8a8: +#endif +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16) + case PIXMAN_a2r10g10b10: #endif return CAIRO_CONTENT_COLOR_ALPHA; case PIXMAN_x8r8g8b8: @@ -112,6 +129,12 @@ _cairo_content_from_pixman_format (pixman_format_code_t pixman_format) case PIXMAN_yv12: #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9) case PIXMAN_x2b10g10r10: +#endif +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,14,1) + case PIXMAN_b8g8r8x8: +#endif +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16) + case PIXMAN_x2r10g10b10: #endif return CAIRO_CONTENT_COLOR; case PIXMAN_a8: @@ -143,7 +166,6 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, surface->format = _cairo_format_from_pixman_format (pixman_format); surface->data = (unsigned char *) pixman_image_get_data (pixman_image); surface->owns_data = FALSE; - surface->has_clip = FALSE; surface->transparency = CAIRO_IMAGE_UNKNOWN; surface->width = pixman_image_get_width (pixman_image); @@ -151,6 +173,8 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, surface->stride = pixman_image_get_stride (pixman_image); surface->depth = pixman_image_get_depth (pixman_image); + surface->clip_region = NULL; + return &surface->base; } @@ -725,6 +749,8 @@ _cairo_image_surface_finish (void *abstract_surface) surface->data = NULL; } + cairo_region_destroy (surface->clip_region); + return CAIRO_STATUS_SUCCESS; } @@ -974,25 +1000,52 @@ _pixman_operator (cairo_operator_t op) } } +static cairo_status_t +_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface, + cairo_region_t *region) +{ + if (region == surface->clip_region) + return CAIRO_STATUS_SUCCESS; + + if (cairo_region_equal (surface->clip_region, region)) + return CAIRO_STATUS_SUCCESS; + + cairo_region_destroy (surface->clip_region); + surface->clip_region = cairo_region_reference (region); + + if (! pixman_image_set_clip_region32 (surface->pixman_image, + region ? ®ion->rgn : NULL)) + { + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } + + return CAIRO_STATUS_SUCCESS; +} + static cairo_int_status_t -_cairo_image_surface_composite (cairo_operator_t op, +_cairo_image_surface_composite (cairo_operator_t op, const cairo_pattern_t *src_pattern, const cairo_pattern_t *mask_pattern, void *abstract_dst, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - unsigned int width, - unsigned int height) + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height, + cairo_region_t *clip_region) { - cairo_surface_attributes_t src_attr, mask_attr; + cairo_surface_attributes_t src_attr, mask_attr; cairo_image_surface_t *dst = abstract_dst; cairo_image_surface_t *src; cairo_image_surface_t *mask; - cairo_int_status_t status; + cairo_int_status_t status; + + status = _cairo_image_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + return status; status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern, &dst->base, @@ -1013,8 +1066,7 @@ _cairo_image_surface_composite (cairo_operator_t op, if (unlikely (status)) goto CLEANUP_SURFACES; - if (mask) - { + if (mask) { status = _cairo_image_surface_set_attributes (mask, &mask_attr, dst_x + width / 2., dst_y + height / 2.); @@ -1031,9 +1083,7 @@ _cairo_image_surface_composite (cairo_operator_t op, mask_y + mask_attr.y_offset, dst_x, dst_y, width, height); - } - else - { + } else { pixman_image_composite (_pixman_operator (op), src->pixman_image, NULL, @@ -1045,7 +1095,7 @@ _cairo_image_surface_composite (cairo_operator_t op, width, height); } - if (! _cairo_operator_bounded_by_source (op)) + if (! _cairo_operator_bounded_by_source (op)) { status = _cairo_surface_composite_fixup_unbounded (&dst->base, &src_attr, src->width, src->height, mask ? &mask_attr : NULL, @@ -1053,7 +1103,9 @@ _cairo_image_surface_composite (cairo_operator_t op, mask ? mask->height : 0, src_x, src_y, mask_x, mask_y, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); + } CLEANUP_SURFACES: if (mask) @@ -1078,7 +1130,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, pixman_rectangle16_t *pixman_rects = stack_rects; int i; - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; + cairo_int_status_t status; if (CAIRO_INJECT_FAULT ()) return _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -1088,6 +1140,9 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, pixman_color.blue = color->blue_short; pixman_color.alpha = color->alpha_short; + status = _cairo_image_surface_set_clip_region (surface, NULL); + assert (status == CAIRO_STATUS_SUCCESS); + if (num_rects > ARRAY_LENGTH (stack_rects)) { pixman_rects = _cairo_malloc_ab (num_rects, sizeof (pixman_rectangle16_t)); if (unlikely (pixman_rects == NULL)) @@ -1101,7 +1156,8 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, pixman_rects[i].height = rects[i].height; } - /* XXX: pixman_fill_rectangles() should be implemented */ + /* XXX: pixman_fill_region() should be implemented */ + status = CAIRO_STATUS_SUCCESS; if (! pixman_image_fill_rectangles (_pixman_operator (op), surface->pixman_image, &pixman_color, @@ -1165,7 +1221,8 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps) + int num_traps, + cairo_region_t *clip_region) { cairo_surface_attributes_t attributes; cairo_image_surface_t *dst = abstract_dst; @@ -1186,22 +1243,26 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, * contained within the surface is bounded by [dst_x,dst_y,width,height]; * the Cairo core code passes bounds based on the trapezoid extents. * - * Currently the check surface->has_clip is needed for correct + * Currently the check clip_region == NULL is needed for correct * functioning, since pixman_add_trapezoids() doesn't obey the * surface clip, which is a libpixman bug , but there's no harm in * falling through to the general case when the surface is clipped * since libpixman would have to generate an intermediate mask anyways. */ if (op == CAIRO_OPERATOR_ADD && + clip_region == NULL && _cairo_pattern_is_opaque_solid (pattern) && dst->base.content == CAIRO_CONTENT_ALPHA && - ! dst->has_clip && antialias != CAIRO_ANTIALIAS_NONE) { _pixman_add_trapezoids (dst->pixman_image, 0, 0, traps, num_traps); return CAIRO_STATUS_SUCCESS; } + status = _cairo_image_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + return status; + status = _cairo_pattern_acquire_surface (pattern, &dst->base, CAIRO_CONTENT_COLOR_ALPHA, src_x, src_y, width, height, @@ -1238,14 +1299,16 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, pixman_image_unref (mask); - if (! _cairo_operator_bounded_by_mask (op)) + if (! _cairo_operator_bounded_by_mask (op)) { status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base, &attributes, src->width, src->height, width, height, src_x, src_y, 0, 0, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); + } CLEANUP_SOURCE: _cairo_pattern_release_surface (pattern, &src->base, &attributes); @@ -1382,7 +1445,7 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer) rects->dst.x, rects->dst.y, width, height); - if (! _cairo_operator_bounded_by_mask (renderer->op)) + if (! _cairo_operator_bounded_by_mask (renderer->op)) { status = _cairo_surface_composite_shape_fixup_unbounded ( &dst->base, src_attributes, @@ -1391,7 +1454,9 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer) rects->src.x, rects->src.y, 0, 0, /* mask.x, mask.y */ rects->dst.x, rects->dst.y, - rects->width, rects->height); + rects->width, rects->height, + dst->clip_region); + } } if (status != CAIRO_STATUS_SUCCESS) return _cairo_span_renderer_set_error (abstract_renderer, @@ -1406,12 +1471,12 @@ _cairo_image_surface_check_span_renderer (cairo_operator_t op, cairo_antialias_t antialias, const cairo_composite_rectangles_t *rects) { + return TRUE; (void) op; (void) pattern; (void) abstract_dst; (void) antialias; (void) rects; - return TRUE; } static cairo_span_renderer_t * @@ -1419,22 +1484,25 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op, const cairo_pattern_t *pattern, void *abstract_dst, cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects) + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region) { cairo_image_surface_t *dst = abstract_dst; - cairo_image_surface_span_renderer_t *renderer - = calloc(1, sizeof(*renderer)); + cairo_image_surface_span_renderer_t *renderer = calloc(1, sizeof(*renderer)); cairo_status_t status; int width = rects->width; int height = rects->height; + status = _cairo_image_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + return _cairo_span_renderer_create_in_error (status); + if (renderer == NULL) return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); renderer->base.destroy = _cairo_image_surface_span_renderer_destroy; renderer->base.finish = _cairo_image_surface_span_renderer_finish; - renderer->base.render_row = - _cairo_image_surface_span_renderer_render_row; + renderer->base.render_row = _cairo_image_surface_span_renderer_render_row; renderer->op = op; renderer->pattern = pattern; renderer->antialias = antialias; @@ -1475,21 +1543,7 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op, return &renderer->base; } -cairo_int_status_t -_cairo_image_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface; - - if (! pixman_image_set_clip_region32 (surface->pixman_image, region? ®ion->rgn : NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - surface->has_clip = region != NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t +static cairo_bool_t _cairo_image_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -1500,7 +1554,7 @@ _cairo_image_surface_get_extents (void *abstract_surface, rectangle->width = surface->width; rectangle->height = surface->height; - return CAIRO_STATUS_SUCCESS; + return TRUE; } static void @@ -1512,18 +1566,6 @@ _cairo_image_surface_get_font_options (void *abstract_surface, cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON); } -static cairo_status_t -_cairo_image_surface_reset (void *abstract_surface) -{ - cairo_image_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_image_surface_set_clip_region (surface, NULL); - assert (status == CAIRO_STATUS_SUCCESS); - - return CAIRO_STATUS_SUCCESS; -} - /** * _cairo_surface_is_image: * @surface: a #cairo_surface_t @@ -1554,8 +1596,6 @@ const cairo_surface_backend_t _cairo_image_surface_backend = { _cairo_image_surface_check_span_renderer, NULL, /* copy_page */ NULL, /* show_page */ - _cairo_image_surface_set_clip_region, - NULL, /* intersect_clip_path */ _cairo_image_surface_get_extents, NULL, /* old_show_glyphs */ _cairo_image_surface_get_font_options, @@ -1571,8 +1611,6 @@ const cairo_surface_backend_t _cairo_image_surface_backend = { NULL, /* show_glyphs */ NULL, /* snapshot */ NULL, /* is_similar */ - - _cairo_image_surface_reset }; /* A convenience function for when one needs to coerce an image @@ -1600,7 +1638,8 @@ _cairo_image_surface_coerce (cairo_image_surface_t *surface, _cairo_pattern_init_for_surface (&pattern, &surface->base); status = _cairo_surface_paint (&clone->base, CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); + &pattern.base, + NULL); _cairo_pattern_fini (&pattern.base); if (unlikely (status)) { diff --git a/src/cairo-meta-surface-private.h b/src/cairo-meta-surface-private.h index f0c95c19c..edfb20c35 100644 --- a/src/cairo-meta-surface-private.h +++ b/src/cairo-meta-surface-private.h @@ -39,6 +39,7 @@ #include "cairoint.h" #include "cairo-path-fixed-private.h" +#include "cairo-clip-private.h" typedef enum { /* The 5 basic drawing operations. */ @@ -47,15 +48,6 @@ typedef enum { CAIRO_COMMAND_STROKE, CAIRO_COMMAND_FILL, CAIRO_COMMAND_SHOW_TEXT_GLYPHS, - - /* Other junk. For most of these, we should be able to assert that - * they never get called except as part of fallbacks for the 5 - * basic drawing operations (which we implement already so the - * fallbacks should never get triggered). So the plan is to - * eliminate as many of these as possible. */ - - CAIRO_COMMAND_INTERSECT_CLIP_PATH - } cairo_command_type_t; typedef enum { @@ -67,25 +59,23 @@ typedef enum { typedef struct _cairo_command_header { cairo_command_type_t type; cairo_meta_region_type_t region; - cairo_rectangle_int_t extents; + cairo_operator_t op; + cairo_clip_t clip; } cairo_command_header_t; typedef struct _cairo_command_paint { cairo_command_header_t header; - cairo_operator_t op; cairo_pattern_union_t source; } cairo_command_paint_t; typedef struct _cairo_command_mask { cairo_command_header_t header; - cairo_operator_t op; cairo_pattern_union_t source; cairo_pattern_union_t mask; } cairo_command_mask_t; typedef struct _cairo_command_stroke { cairo_command_header_t header; - cairo_operator_t op; cairo_pattern_union_t source; cairo_path_fixed_t path; cairo_stroke_style_t style; @@ -97,7 +87,6 @@ typedef struct _cairo_command_stroke { typedef struct _cairo_command_fill { cairo_command_header_t header; - cairo_operator_t op; cairo_pattern_union_t source; cairo_path_fixed_t path; cairo_fill_rule_t fill_rule; @@ -107,7 +96,6 @@ typedef struct _cairo_command_fill { typedef struct _cairo_command_show_text_glyphs { cairo_command_header_t header; - cairo_operator_t op; cairo_pattern_union_t source; char *utf8; int utf8_len; @@ -119,27 +107,14 @@ typedef struct _cairo_command_show_text_glyphs { cairo_scaled_font_t *scaled_font; } cairo_command_show_text_glyphs_t; -typedef struct _cairo_command_intersect_clip_path { - cairo_command_header_t header; - cairo_path_fixed_t *path_pointer; - cairo_path_fixed_t path; - cairo_fill_rule_t fill_rule; - double tolerance; - cairo_antialias_t antialias; -} cairo_command_intersect_clip_path_t; - typedef union _cairo_command { cairo_command_header_t header; - /* The 5 basic drawing operations. */ cairo_command_paint_t paint; cairo_command_mask_t mask; cairo_command_stroke_t stroke; cairo_command_fill_t fill; cairo_command_show_text_glyphs_t show_text_glyphs; - - /* The other junk. */ - cairo_command_intersect_clip_path_t intersect_clip_path; } cairo_command_t; typedef struct _cairo_meta_surface { @@ -150,14 +125,15 @@ typedef struct _cairo_meta_surface { /* A meta-surface is logically unbounded, but when used as a * source we need to render it to an image, so we need a size at * which to create that image. */ - double width_pixels; - double height_pixels; + cairo_rectangle_t extents_pixels; cairo_rectangle_int_t extents; + cairo_bool_t unbounded; + + cairo_clip_t clip; cairo_array_t commands; cairo_surface_t *commands_owner; - cairo_bool_t is_clipped; int replay_start_idx; } cairo_meta_surface_t; @@ -181,6 +157,11 @@ _cairo_meta_surface_replay_region (cairo_surface_t *surface, cairo_surface_t *target, cairo_meta_region_type_t region); +cairo_private cairo_status_t +_cairo_meta_surface_get_bbox (cairo_meta_surface_t *meta, + cairo_box_t *bbox, + const cairo_matrix_t *transform); + cairo_private cairo_bool_t _cairo_surface_is_meta (const cairo_surface_t *surface); diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index 4fb2722cd..f091a59fe 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -50,6 +50,12 @@ * that would have been obtained if the original operations applied to * the meta surface had instead been applied to the target surface. * + * A meta surface is logically unbounded, i.e. it has no implicit constraint + * on the size of the drawing surface. However, in practice this is rarely + * useful as you wish to replay against a particular target surface with + * known bounds. For this case, it is more efficient to specify the target + * extents to the meta surface upon creation. + * * The recording phase of the meta surface is careful to snapshot all * necessary objects (paths, patterns, etc.), in order to achieve * accurate replay. The efficiency of the meta surface could be @@ -58,10 +64,13 @@ * copy-on-write implementation for _cairo_surface_snapshot. */ +/* XXX Rename to recording surface */ + #include "cairoint.h" #include "cairo-analysis-surface-private.h" #include "cairo-meta-surface-private.h" #include "cairo-clip-private.h" +#include "cairo-surface-wrapper-private.h" typedef enum { CAIRO_META_REPLAY, @@ -82,8 +91,8 @@ static const cairo_surface_backend_t cairo_meta_surface_backend; /** * cairo_meta_surface_create: * @content: the content of the meta surface - * @width_pixels: width of the surface, in pixels - * @height_pixels: height of the surface, in pixels + * @extents_pixels: the extents to record in pixels, can be %NULL to record + * unbounded operations. * * Creates a meta-surface which can be used to record all drawing operations * at the highest level (that is, the level of paint, mask, stroke, fill @@ -105,50 +114,45 @@ static const cairo_surface_backend_t cairo_meta_surface_backend; * Since 1.10 **/ cairo_surface_t * -cairo_meta_surface_create (cairo_content_t content, - double width_pixels, - double height_pixels) +cairo_meta_surface_create (cairo_content_t content, + const cairo_rectangle_t *extents) { cairo_meta_surface_t *meta; + cairo_status_t status; meta = malloc (sizeof (cairo_meta_surface_t)); if (unlikely (meta == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - _cairo_surface_init (&meta->base, &cairo_meta_surface_backend, - content); + _cairo_surface_init (&meta->base, &cairo_meta_surface_backend, content); meta->content = content; - meta->width_pixels = width_pixels; - meta->height_pixels = height_pixels; /* unbounded -> 'infinite' extents */ - if (width_pixels < 0) { - meta->extents.x = CAIRO_RECT_INT_MIN; - meta->extents.width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; - } else { - meta->extents.x = 0; - if (ceil (width_pixels) > CAIRO_RECT_INT_MAX) - meta->extents.width = CAIRO_RECT_INT_MAX; - else - meta->extents.width = ceil (width_pixels); - } + if (extents != NULL) { + meta->extents_pixels = *extents; - if (height_pixels < 0) { - meta->extents.y = CAIRO_RECT_INT_MIN; - meta->extents.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; + /* XXX check for overflow */ + meta->extents.x = floor (extents->x); + meta->extents.y = floor (extents->y); + meta->extents.width = ceil (extents->x + extents->width) - meta->extents.x; + meta->extents.height = ceil (extents->y + extents->height) - meta->extents.y; + + status = _cairo_clip_init_rectangle (&meta->clip, &meta->extents); + if (unlikely (status)) { + free (meta); + return _cairo_surface_create_in_error (status); + } + + meta->unbounded = FALSE; } else { - meta->extents.y = 0; - if (ceil (height_pixels) > CAIRO_RECT_INT_MAX) - meta->extents.height = CAIRO_RECT_INT_MAX; - else - meta->extents.height = ceil (height_pixels); + meta->unbounded = TRUE; + _cairo_clip_init (&meta->clip); } _cairo_array_init (&meta->commands, sizeof (cairo_command_t *)); meta->commands_owner = NULL; - meta->is_clipped = FALSE; meta->replay_start_idx = 0; return &meta->base; @@ -161,14 +165,17 @@ _cairo_meta_surface_create_similar (void *abstract_surface, int width, int height) { - return cairo_meta_surface_create (content, width, height); + cairo_rectangle_t extents; + extents.x = extents.y = 0; + extents.width = width; + extents.height = height; + return cairo_meta_surface_create (content, &extents); } static cairo_status_t _cairo_meta_surface_finish (void *abstract_surface) { cairo_meta_surface_t *meta = abstract_surface; - cairo_command_t *command; cairo_command_t **elements; int i, num_elements; @@ -180,11 +187,11 @@ _cairo_meta_surface_finish (void *abstract_surface) num_elements = meta->commands.num_elements; elements = _cairo_array_index (&meta->commands, 0); for (i = 0; i < num_elements; i++) { - command = elements[i]; + cairo_command_t *command = elements[i]; + + _cairo_clip_reset (&command->header.clip); + switch (command->header.type) { - - /* 5 basic drawing operations */ - case CAIRO_COMMAND_PAINT: _cairo_pattern_fini_snapshot (&command->paint.source.base); free (command); @@ -218,19 +225,13 @@ _cairo_meta_surface_finish (void *abstract_surface) free (command); break; - /* Other junk. */ - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: - if (command->intersect_clip_path.path_pointer) - _cairo_path_fixed_fini (&command->intersect_clip_path.path); - free (command); - break; - default: ASSERT_NOT_REACHED; } } _cairo_array_fini (&meta->commands); + _cairo_clip_reset (&meta->clip); return CAIRO_STATUS_SUCCESS; } @@ -254,8 +255,12 @@ _cairo_meta_surface_acquire_source_image (void *abstract_surface, } image = _cairo_image_surface_create_with_content (surface->content, - ceil (surface->width_pixels), - ceil (surface->height_pixels)); + surface->extents.width, + surface->extents.height); + + cairo_surface_set_device_offset (image, + -surface->extents.x, + -surface->extents.y); status = cairo_meta_surface_replay (&surface->base, image); if (unlikely (status)) { @@ -282,21 +287,30 @@ _cairo_meta_surface_release_source_image (void *abstract_surface, cairo_surface_destroy (&image->base); } -static void -_draw_command_init (cairo_command_header_t *command, - cairo_command_type_t type, - cairo_meta_surface_t *meta) +static cairo_status_t +_command_init (cairo_meta_surface_t *meta, + cairo_command_header_t *command, + cairo_command_type_t type, + cairo_operator_t op, + cairo_clip_t *clip) { + cairo_status_t status = CAIRO_STATUS_SUCCESS; + command->type = type; + command->op = op; command->region = CAIRO_META_REGION_ALL; - command->extents = meta->extents; + _cairo_clip_init_copy (&command->clip, clip); + if (meta->clip.path != NULL) + status = _cairo_clip_apply_clip (&command->clip, &meta->clip); + + return status; } static cairo_int_status_t -_cairo_meta_surface_paint (void *abstract_surface, - cairo_operator_t op, +_cairo_meta_surface_paint (void *abstract_surface, + cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; @@ -306,8 +320,10 @@ _cairo_meta_surface_paint (void *abstract_surface, if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - _draw_command_init (&command->header, CAIRO_COMMAND_PAINT, meta); - command->op = op; + status = _command_init (meta, + &command->header, CAIRO_COMMAND_PAINT, op, clip); + if (unlikely (status)) + goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) @@ -320,7 +336,7 @@ _cairo_meta_surface_paint (void *abstract_surface, /* An optimisation that takes care to not replay what was done * before surface is cleared. We don't erase recorded commands * since we may have earlier snapshots of this surface. */ - if (op == CAIRO_OPERATOR_CLEAR && !meta->is_clipped) + if (op == CAIRO_OPERATOR_CLEAR && clip == NULL) meta->replay_start_idx = meta->commands.num_elements; return CAIRO_STATUS_SUCCESS; @@ -337,7 +353,7 @@ _cairo_meta_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; @@ -347,8 +363,10 @@ _cairo_meta_surface_mask (void *abstract_surface, if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - _draw_command_init (&command->header, CAIRO_COMMAND_MASK, meta); - command->op = op; + status = _command_init (meta, + &command->header, CAIRO_COMMAND_MASK, op, clip); + if (unlikely (status)) + goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) @@ -383,7 +401,7 @@ _cairo_meta_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; @@ -393,8 +411,10 @@ _cairo_meta_surface_stroke (void *abstract_surface, if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - _draw_command_init (&command->header, CAIRO_COMMAND_STROKE, meta); - command->op = op; + status = _command_init (meta, + &command->header, CAIRO_COMMAND_STROKE, op, clip); + if (unlikely (status)) + goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) @@ -438,7 +458,7 @@ _cairo_meta_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; @@ -448,8 +468,10 @@ _cairo_meta_surface_fill (void *abstract_surface, if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - _draw_command_init (&command->header, CAIRO_COMMAND_FILL, meta); - command->op = op; + status =_command_init (meta, + &command->header, CAIRO_COMMAND_FILL, op, clip); + if (unlikely (status)) + goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) @@ -496,7 +518,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_meta_surface_t *meta = abstract_surface; @@ -506,8 +528,11 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - _draw_command_init (&command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS, meta); - command->op = op; + status = _command_init (meta, + &command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS, + op, clip); + if (unlikely (status)) + goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->source.base, source); if (unlikely (status)) @@ -594,82 +619,31 @@ _cairo_meta_surface_snapshot (void *abstract_other) _cairo_surface_init (&meta->base, &cairo_meta_surface_backend, other->base.content); - meta->width_pixels = other->width_pixels; - meta->height_pixels = other->height_pixels; + meta->extents_pixels = other->extents_pixels; meta->extents = other->extents; + meta->unbounded = other->unbounded; meta->replay_start_idx = other->replay_start_idx; meta->content = other->content; _cairo_array_init_snapshot (&meta->commands, &other->commands); meta->commands_owner = cairo_surface_reference (&other->base); + _cairo_clip_init_copy (&meta->clip, &other->clip); + return &meta->base; } -static cairo_int_status_t -_cairo_meta_surface_intersect_clip_path (void *dst, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_meta_surface_t *meta = dst; - cairo_command_intersect_clip_path_t *command; - cairo_status_t status; - - command = malloc (sizeof (cairo_command_intersect_clip_path_t)); - if (unlikely (command == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH; - command->header.region = CAIRO_META_REGION_ALL; - - if (path) { - status = _cairo_path_fixed_init_copy (&command->path, path); - if (unlikely (status)) { - free (command); - return status; - } - command->path_pointer = &command->path; - meta->is_clipped = TRUE; - } else { - command->path_pointer = NULL; - meta->is_clipped = FALSE; - } - command->fill_rule = fill_rule; - command->tolerance = tolerance; - command->antialias = antialias; - - status = _cairo_array_append (&meta->commands, &command); - if (unlikely (status)) { - if (path) - _cairo_path_fixed_fini (&command->path); - free (command); - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -/* Currently, we're using as the "size" of a meta surface the largest - * surface size against which the meta-surface is expected to be - * replayed, (as passed in to cairo_meta_surface_create()). - */ -static cairo_int_status_t +static cairo_bool_t _cairo_meta_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { cairo_meta_surface_t *surface = abstract_surface; - if (surface->width_pixels < 0 || surface->height_pixels < 0) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (surface->unbounded) + return FALSE; - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = ceil (surface->width_pixels); - rectangle->height = ceil (surface->height_pixels); - - return CAIRO_STATUS_SUCCESS; + *rectangle = surface->extents; + return TRUE; } /** @@ -702,8 +676,6 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - _cairo_meta_surface_intersect_clip_path, _cairo_meta_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -726,7 +698,6 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = { _cairo_meta_surface_snapshot, NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ @@ -735,32 +706,12 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = { _cairo_meta_surface_show_text_glyphs }; -static cairo_path_fixed_t * -_cairo_command_get_path (cairo_command_t *command) -{ - switch (command->header.type) { - case CAIRO_COMMAND_PAINT: - case CAIRO_COMMAND_MASK: - case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: - return NULL; - case CAIRO_COMMAND_STROKE: - return &command->stroke.path; - case CAIRO_COMMAND_FILL: - return &command->fill.path; - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: - return command->intersect_clip_path.path_pointer; - } - - ASSERT_NOT_REACHED; - return NULL; -} - cairo_int_status_t _cairo_meta_surface_get_path (cairo_surface_t *surface, cairo_path_fixed_t *path) { cairo_meta_surface_t *meta; - cairo_command_t *command, **elements; + cairo_command_t **elements; int i, num_elements; cairo_int_status_t status; @@ -773,12 +724,11 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface, num_elements = meta->commands.num_elements; elements = _cairo_array_index (&meta->commands, 0); for (i = meta->replay_start_idx; i < num_elements; i++) { - command = elements[i]; + cairo_command_t *command = elements[i]; switch (command->header.type) { case CAIRO_COMMAND_PAINT: case CAIRO_COMMAND_MASK: - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: status = CAIRO_INT_STATUS_UNSUPPORTED; break; @@ -804,7 +754,9 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface, } case CAIRO_COMMAND_FILL: { - status = _cairo_path_fixed_append (path, &command->fill.path, CAIRO_DIRECTION_FORWARD); + status = _cairo_path_fixed_append (path, + &command->fill.path, CAIRO_DIRECTION_FORWARD, + 0, 0); break; } case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: @@ -827,6 +779,7 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface, return _cairo_surface_set_error (surface, status); } +#define _clip(c) ((c)->header.clip.path ? &(c)->header.clip : NULL) static cairo_status_t _cairo_meta_surface_replay_internal (cairo_surface_t *surface, cairo_surface_t *target, @@ -834,209 +787,155 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, cairo_meta_region_type_t region) { cairo_meta_surface_t *meta; - cairo_command_t *command, **elements; + cairo_command_t **elements; int i, num_elements; - cairo_int_status_t status, status2; - cairo_clip_t clip, *old_clip; - cairo_bool_t has_device_transform = _cairo_surface_has_device_transform (target); - cairo_matrix_t *device_transform = &target->device_transform; - cairo_path_fixed_t path_copy, *dev_path; + cairo_int_status_t status; + cairo_surface_wrapper_t wrapper; - if (surface->status) + if (unlikely (surface->status)) return surface->status; - if (target->status) + if (unlikely (target->status)) return _cairo_surface_set_error (surface, target->status); + _cairo_surface_wrapper_init (&wrapper, target); + meta = (cairo_meta_surface_t *) surface; status = CAIRO_STATUS_SUCCESS; - _cairo_clip_init (&clip, target); - old_clip = _cairo_surface_get_clip (target); - num_elements = meta->commands.num_elements; elements = _cairo_array_index (&meta->commands, 0); for (i = meta->replay_start_idx; i < num_elements; i++) { - command = elements[i]; + cairo_command_t *command = elements[i]; if (type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL) { if (command->header.region != region) continue; } - /* For all commands except intersect_clip_path, we have to - * ensure the current clip gets set on the surface. */ - if (command->header.type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) { - status = _cairo_surface_set_clip (target, &clip); - if (unlikely (status)) - break; - } - - dev_path = _cairo_command_get_path (command); - if (dev_path && has_device_transform) { - status = _cairo_path_fixed_init_copy (&path_copy, dev_path); - if (unlikely (status)) - break; - _cairo_path_fixed_transform (&path_copy, device_transform); - dev_path = &path_copy; - } - switch (command->header.type) { case CAIRO_COMMAND_PAINT: - status = _cairo_surface_paint (target, - command->paint.op, - &command->paint.source.base, &command->header.extents); + status = _cairo_surface_wrapper_paint (&wrapper, + command->header.op, + &command->paint.source.base, + _clip (command)); break; + case CAIRO_COMMAND_MASK: - status = _cairo_surface_mask (target, - command->mask.op, - &command->mask.source.base, - &command->mask.mask.base, &command->header.extents); + status = _cairo_surface_wrapper_mask (&wrapper, + command->header.op, + &command->mask.source.base, + &command->mask.mask.base, + _clip (command)); break; + case CAIRO_COMMAND_STROKE: { - cairo_matrix_t dev_ctm = command->stroke.ctm; - cairo_matrix_t dev_ctm_inverse = command->stroke.ctm_inverse; - - if (has_device_transform) { - cairo_matrix_multiply (&dev_ctm, &dev_ctm, device_transform); - cairo_matrix_multiply (&dev_ctm_inverse, - &target->device_transform_inverse, - &dev_ctm_inverse); - } - - status = _cairo_surface_stroke (target, - command->stroke.op, - &command->stroke.source.base, - dev_path, - &command->stroke.style, - &dev_ctm, - &dev_ctm_inverse, - command->stroke.tolerance, - command->stroke.antialias, &command->header.extents); + status = _cairo_surface_wrapper_stroke (&wrapper, + command->header.op, + &command->stroke.source.base, + &command->stroke.path, + &command->stroke.style, + &command->stroke.ctm, + &command->stroke.ctm_inverse, + command->stroke.tolerance, + command->stroke.antialias, + _clip (command)); break; } case CAIRO_COMMAND_FILL: { cairo_command_t *stroke_command; - if (type != CAIRO_META_CREATE_REGIONS) - stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL; - else - stroke_command = NULL; + stroke_command = NULL; + if (type != CAIRO_META_CREATE_REGIONS && i < num_elements - 1) + stroke_command = elements[i + 1]; if (stroke_command != NULL && - type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL) + type == CAIRO_META_REPLAY && + region != CAIRO_META_REGION_ALL) { if (stroke_command->header.region != region) stroke_command = NULL; } + if (stroke_command != NULL && stroke_command->header.type == CAIRO_COMMAND_STROKE && - _cairo_path_fixed_is_equal (dev_path, _cairo_command_get_path (stroke_command))) { - cairo_matrix_t dev_ctm; - cairo_matrix_t dev_ctm_inverse; - - dev_ctm = stroke_command->stroke.ctm; - dev_ctm_inverse = stroke_command->stroke.ctm_inverse; - - if (has_device_transform) { - cairo_matrix_multiply (&dev_ctm, &dev_ctm, device_transform); - cairo_matrix_multiply (&dev_ctm_inverse, - &surface->device_transform_inverse, - &dev_ctm_inverse); - } - - status = _cairo_surface_fill_stroke (target, - command->fill.op, - &command->fill.source.base, - command->fill.fill_rule, - command->fill.tolerance, - command->fill.antialias, - dev_path, - stroke_command->stroke.op, - &stroke_command->stroke.source.base, - &stroke_command->stroke.style, - &dev_ctm, - &dev_ctm_inverse, - stroke_command->stroke.tolerance, - stroke_command->stroke.antialias, - &stroke_command->header.extents); + _cairo_path_fixed_is_equal (&command->fill.path, + &stroke_command->stroke.path)) + { + status = _cairo_surface_wrapper_fill_stroke (&wrapper, + command->header.op, + &command->fill.source.base, + command->fill.fill_rule, + command->fill.tolerance, + command->fill.antialias, + &command->fill.path, + stroke_command->header.op, + &stroke_command->stroke.source.base, + &stroke_command->stroke.style, + &stroke_command->stroke.ctm, + &stroke_command->stroke.ctm_inverse, + stroke_command->stroke.tolerance, + stroke_command->stroke.antialias, + _clip (command)); i++; - } else - status = _cairo_surface_fill (target, - command->fill.op, - &command->fill.source.base, - dev_path, - command->fill.fill_rule, - command->fill.tolerance, - command->fill.antialias, &command->header.extents); + } + else + { + status = _cairo_surface_wrapper_fill (&wrapper, + command->header.op, + &command->fill.source.base, + &command->fill.path, + command->fill.fill_rule, + command->fill.tolerance, + command->fill.antialias, + _clip (command)); + } break; } case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: { cairo_glyph_t *glyphs = command->show_text_glyphs.glyphs; - cairo_glyph_t *dev_glyphs; - int i, num_glyphs = command->show_text_glyphs.num_glyphs; + cairo_glyph_t *glyphs_copy; + int num_glyphs = command->show_text_glyphs.num_glyphs; /* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed * to modify the glyph array that's passed in. We must always * copy the array before handing it to the backend. */ - dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (unlikely (dev_glyphs == NULL)) { + glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); + if (unlikely (glyphs_copy == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); break; } - if (has_device_transform) { - for (i = 0; i < num_glyphs; i++) { - dev_glyphs[i] = glyphs[i]; - cairo_matrix_transform_point (device_transform, - &dev_glyphs[i].x, - &dev_glyphs[i].y); - } - } else { - memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); - } + memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); - status = _cairo_surface_show_text_glyphs (target, - command->show_text_glyphs.op, - &command->show_text_glyphs.source.base, - command->show_text_glyphs.utf8, command->show_text_glyphs.utf8_len, - dev_glyphs, num_glyphs, - command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters, - command->show_text_glyphs.cluster_flags, - command->show_text_glyphs.scaled_font, &command->header.extents); - - free (dev_glyphs); + status = _cairo_surface_wrapper_show_text_glyphs (&wrapper, + command->header.op, + &command->show_text_glyphs.source.base, + command->show_text_glyphs.utf8, command->show_text_glyphs.utf8_len, + glyphs_copy, num_glyphs, + command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters, + command->show_text_glyphs.cluster_flags, + command->show_text_glyphs.scaled_font, + _clip (command)); + free (glyphs_copy); break; } - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: - /* XXX Meta surface clipping is broken and requires some - * cairo-gstate.c rewriting. Work around it for now. */ - if (dev_path == NULL) - _cairo_clip_reset (&clip); - else - status = _cairo_clip_clip (&clip, dev_path, - command->intersect_clip_path.fill_rule, - command->intersect_clip_path.tolerance, - command->intersect_clip_path.antialias, - target); - break; default: ASSERT_NOT_REACHED; } - if (dev_path == &path_copy) - _cairo_path_fixed_fini (&path_copy); - if (type == CAIRO_META_CREATE_REGIONS) { if (status == CAIRO_STATUS_SUCCESS) { command->header.region = CAIRO_META_REGION_NATIVE; } else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) { command->header.region = CAIRO_META_REGION_IMAGE_FALLBACK; status = CAIRO_STATUS_SUCCESS; + } else { + assert (_cairo_status_is_error (status)); } } @@ -1044,10 +943,14 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, break; } - _cairo_clip_reset (&clip); - status2 = _cairo_surface_set_clip (target, old_clip); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; + /* free up any caches */ + for (i = meta->replay_start_idx; i < num_elements; i++) { + cairo_command_t *command = elements[i]; + + _cairo_clip_drop_cache (&command->header.clip); + } + + _cairo_surface_wrapper_fini (&wrapper); return _cairo_surface_set_error (surface, status); } @@ -1104,6 +1007,33 @@ _cairo_meta_surface_replay_region (cairo_surface_t *surface, region); } +static cairo_status_t +_meta_surface_get_ink_bbox (cairo_meta_surface_t *surface, + cairo_box_t *bbox, + const cairo_matrix_t *transform) +{ + cairo_surface_t *null_surface; + cairo_surface_t *analysis_surface; + cairo_status_t status; + + null_surface = _cairo_null_surface_create (surface->content); + analysis_surface = _cairo_analysis_surface_create (null_surface); + cairo_surface_destroy (null_surface); + + status = analysis_surface->status; + if (unlikely (status)) + return status; + + if (transform != NULL) + _cairo_analysis_surface_set_ctm (analysis_surface, transform); + + status = cairo_meta_surface_replay (&surface->base, analysis_surface); + _cairo_analysis_surface_get_bounding_box (analysis_surface, bbox); + cairo_surface_destroy (analysis_surface); + + return status; +} + /** * cairo_meta_surface_ink_extents: * @surface: a #cairo_meta_surface_t @@ -1114,7 +1044,7 @@ _cairo_meta_surface_replay_region (cairo_surface_t *surface, * * Measures the extents of the operations stored within the meta-surface. * This is useful to compute the required size of an image surface (or - * equivalent) into which to replay the full sequence of drawing operaitions. + * equivalent) into which to replay the full sequence of drawing operations. * * Since: 1.10 **/ @@ -1125,8 +1055,6 @@ cairo_meta_surface_ink_extents (cairo_surface_t *surface, double *width, double *height) { - cairo_surface_t *null_surface; - cairo_surface_t *analysis_surface; cairo_status_t status; cairo_box_t bbox; @@ -1137,17 +1065,11 @@ cairo_meta_surface_ink_extents (cairo_surface_t *surface, goto DONE; } - null_surface = _cairo_null_surface_create (CAIRO_CONTENT_COLOR_ALPHA); - analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1); - cairo_surface_destroy (null_surface); - - status = analysis_surface->status; + status = _meta_surface_get_ink_bbox ((cairo_meta_surface_t *) surface, + &bbox, + NULL); if (unlikely (status)) - goto DONE; - - status = cairo_meta_surface_replay (surface, analysis_surface); - _cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox); - cairo_surface_destroy (analysis_surface); + status = _cairo_surface_set_error (surface, status); DONE: if (x0) @@ -1159,3 +1081,19 @@ DONE: if (height) *height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y); } + +cairo_status_t +_cairo_meta_surface_get_bbox (cairo_meta_surface_t *surface, + cairo_box_t *bbox, + const cairo_matrix_t *transform) +{ + if (! surface->unbounded) { + _cairo_box_from_rectangle (bbox, &surface->extents); + if (transform != NULL) + _cairo_matrix_transform_bounding_box_fixed (transform, bbox, NULL); + + return CAIRO_STATUS_SUCCESS; + } + + return _meta_surface_get_ink_bbox (surface, bbox, transform); +} diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c index 82bab3bea..3fda0b4f6 100644 --- a/src/cairo-os2-surface.c +++ b/src/cairo-os2-surface.c @@ -716,26 +716,18 @@ _cairo_os2_surface_release_dest_image (void *abstract_surface DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); } -static cairo_int_status_t +static cairo_bool_t _cairo_os2_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { cairo_os2_surface_t *local_os2_surface; - local_os2_surface = (cairo_os2_surface_t *) abstract_surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - rectangle->x = 0; rectangle->y = 0; rectangle->width = local_os2_surface->bitmap_info.cx; rectangle->height = local_os2_surface->bitmap_info.cy; - return CAIRO_STATUS_SUCCESS; + return TRUE; } /** @@ -1327,8 +1319,6 @@ static const cairo_surface_backend_t cairo_os2_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - NULL, /* intersect_clip_path */ _cairo_os2_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ diff --git a/src/cairo-paginated-private.h b/src/cairo-paginated-private.h index 5cb2e48b6..0841a2b19 100644 --- a/src/cairo-paginated-private.h +++ b/src/cairo-paginated-private.h @@ -149,8 +149,6 @@ struct _cairo_paginated_surface_backend { cairo_private cairo_surface_t * _cairo_paginated_surface_create (cairo_surface_t *target, cairo_content_t content, - int width, - int height, const cairo_paginated_surface_backend_t *backend); cairo_private cairo_surface_t * diff --git a/src/cairo-paginated-surface-private.h b/src/cairo-paginated-surface-private.h index b406cac15..6c1307272 100644 --- a/src/cairo-paginated-surface-private.h +++ b/src/cairo-paginated-surface-private.h @@ -48,14 +48,6 @@ typedef struct _cairo_paginated_surface { cairo_content_t content; - /* XXX: These shouldn't actually exist. We inherit this ugliness - * from _cairo_meta_surface_create. The width/height parameters - * from that function also should not exist. The fix that will - * allow us to remove all of these is to fix acquire_source_image - * to pass an interest rectangle. */ - int width; - int height; - /* Paginated-surface specific functions for the target */ const cairo_paginated_surface_backend_t *backend; @@ -66,7 +58,6 @@ typedef struct _cairo_paginated_surface { int page_num; cairo_bool_t page_is_blank; - } cairo_paginated_surface_t; #endif /* CAIRO_PAGINATED_SURFACE_H */ diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index 033df35af..23443a5d2 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -60,17 +60,36 @@ _cairo_paginated_surface_create_similar (void *abstract_surface, int width, int height) { - cairo_paginated_surface_t *surface = abstract_surface; - return cairo_surface_create_similar (surface->target, content, - width, height); + cairo_rectangle_t rect; + rect.x = rect.y = 0.; + rect.width = width; + rect.height = height; + return cairo_meta_surface_create (content, &rect); +} + +static cairo_surface_t * +_create_meta_surface_for_target (cairo_surface_t *target, + cairo_content_t content) +{ + cairo_rectangle_int_t rect; + + if (_cairo_surface_get_extents (target, &rect)) { + cairo_rectangle_t meta_extents; + + meta_extents.x = rect.x; + meta_extents.y = rect.y; + meta_extents.width = rect.width; + meta_extents.height = rect.height; + + return cairo_meta_surface_create (content, &meta_extents); + } else { + return cairo_meta_surface_create (content, NULL); + } } -/* XXX The integer width,height here should be doubles and all uses updated */ cairo_surface_t * _cairo_paginated_surface_create (cairo_surface_t *target, cairo_content_t content, - int width, - int height, const cairo_paginated_surface_backend_t *backend) { cairo_paginated_surface_t *surface; @@ -87,18 +106,15 @@ _cairo_paginated_surface_create (cairo_surface_t *target, /* Override surface->base.type with target's type so we don't leak * evidence of the paginated wrapper out to the user. */ - surface->base.type = cairo_surface_get_type (target); + surface->base.type = target->type; surface->target = cairo_surface_reference (target); surface->content = content; - surface->width = width; - surface->height = height; - surface->backend = backend; - surface->meta = cairo_meta_surface_create (content, width, height); - status = cairo_surface_status (surface->meta); + surface->meta = _create_meta_surface_for_target (target, content); + status = surface->meta->status; if (unlikely (status)) goto FAIL_CLEANUP_SURFACE; @@ -132,31 +148,6 @@ _cairo_paginated_surface_get_target (cairo_surface_t *surface) return paginated_surface->target; } -cairo_status_t -_cairo_paginated_surface_set_size (cairo_surface_t *surface, - int width, - int height) -{ - cairo_paginated_surface_t *paginated_surface; - cairo_status_t status; - - assert (_cairo_surface_is_paginated (surface)); - - paginated_surface = (cairo_paginated_surface_t *) surface; - - paginated_surface->width = width; - paginated_surface->height = height; - - cairo_surface_destroy (paginated_surface->meta); - paginated_surface->meta = cairo_meta_surface_create (paginated_surface->content, - width, height); - status = cairo_surface_status (paginated_surface->meta); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - return CAIRO_STATUS_SUCCESS; -} - static cairo_status_t _cairo_paginated_surface_finish (void *abstract_surface) { @@ -168,18 +159,11 @@ _cairo_paginated_surface_finish (void *abstract_surface) status = cairo_surface_status (abstract_surface); } - if (status == CAIRO_STATUS_SUCCESS) { - cairo_surface_finish (surface->target); - status = cairo_surface_status (surface->target); - } - - if (status == CAIRO_STATUS_SUCCESS) { - cairo_surface_finish (surface->meta); - status = cairo_surface_status (surface->meta); - } - cairo_surface_destroy (surface->target); + cairo_surface_finish (surface->meta); + if (status == CAIRO_STATUS_SUCCESS) + status = cairo_surface_status (surface->meta); cairo_surface_destroy (surface->meta); return status; @@ -210,13 +194,14 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface, void **image_extra) { cairo_paginated_surface_t *surface = abstract_surface; + cairo_bool_t is_bounded; cairo_surface_t *image; cairo_status_t status; cairo_rectangle_int_t extents; - status = _cairo_surface_get_extents (surface->target, &extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (surface->target, &extents); + if (! is_bounded) + return CAIRO_INT_STATUS_UNSUPPORTED; image = _cairo_paginated_surface_create_image_surface (surface, extents.width, @@ -248,11 +233,11 @@ _paint_fallback_image (cairo_paginated_surface_t *surface, { double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution; double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution; - cairo_matrix_t matrix; int x, y, width, height; cairo_status_t status; cairo_surface_t *image; cairo_surface_pattern_t pattern; + cairo_clip_t clip; x = rect->x; y = rect->y; @@ -271,15 +256,21 @@ _paint_fallback_image (cairo_paginated_surface_t *surface, goto CLEANUP_IMAGE; _cairo_pattern_init_for_surface (&pattern, image); - cairo_matrix_init (&matrix, x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale); - cairo_pattern_set_matrix (&pattern.base, &matrix); + cairo_matrix_init (&pattern.base.matrix, + x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale); /* the fallback should be rendered at native resolution, so disable * filtering (if possible) to avoid introducing potential artifacts. */ pattern.base.filter = CAIRO_FILTER_NEAREST; + status = _cairo_clip_init_rectangle (&clip, rect); + if (unlikely (status)) + goto CLEANUP_IMAGE; + status = _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); + &pattern.base, &clip); + + _cairo_clip_reset (&clip); _cairo_pattern_fini (&pattern.base); CLEANUP_IMAGE: @@ -295,12 +286,11 @@ _paint_page (cairo_paginated_surface_t *surface) cairo_status_t status; cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback; - if (surface->target->status) + if (unlikely (surface->target->status)) return surface->target->status; - analysis = _cairo_analysis_surface_create (surface->target, - surface->width, surface->height); - if (analysis->status) + analysis = _cairo_analysis_surface_create (surface->target); + if (unlikely (analysis->status)) return _cairo_surface_set_error (surface->target, analysis->status); surface->backend->set_paginated_mode (surface->target, @@ -365,16 +355,19 @@ _paint_page (cairo_paginated_surface_t *surface) } if (has_page_fallback) { - cairo_rectangle_int_t rect; + cairo_rectangle_int_t extents; + cairo_bool_t is_bounded; surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_FALLBACK); - rect.x = 0; - rect.y = 0; - rect.width = surface->width; - rect.height = surface->height; - status = _paint_fallback_image (surface, &rect); + is_bounded = _cairo_surface_get_extents (surface->target, &extents); + if (! is_bounded) { + status = CAIRO_INT_STATUS_UNSUPPORTED; + goto FAIL; + } + + status = _paint_fallback_image (surface, &extents); if (unlikely (status)) goto FAIL; } @@ -386,15 +379,6 @@ _paint_page (cairo_paginated_surface_t *surface) surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_FALLBACK); - /* Reset clip region before drawing the fall back images */ - status = _cairo_surface_intersect_clip_path (surface->target, - NULL, - CAIRO_FILL_RULE_WINDING, - CAIRO_GSTATE_TOLERANCE_DEFAULT, - CAIRO_ANTIALIAS_DEFAULT); - if (unlikely (status)) - goto FAIL; - region = _cairo_analysis_surface_get_unsupported (analysis); num_rects = cairo_region_num_rectangles (region); @@ -402,9 +386,7 @@ _paint_page (cairo_paginated_surface_t *surface) cairo_rectangle_int_t rect; cairo_region_get_rectangle (region, i, &rect); - status = _paint_fallback_image (surface, &rect); - if (unlikely (status)) goto FAIL; } @@ -445,7 +427,7 @@ _cairo_paginated_surface_copy_page (void *abstract_surface) surface->page_num++; - /* XXX: It might make sense to add some suport here for calling + /* XXX: It might make sense to add some support here for calling * cairo_surface_copy_page on the target surface. It would be an * optimization for the output, but the interaction with image * fallbacks gets tricky. For now, we just let the target see a @@ -471,20 +453,19 @@ _cairo_paginated_surface_show_page (void *abstract_surface) return status; cairo_surface_show_page (surface->target); - status = cairo_surface_status (surface->target); + status = surface->target->status; if (unlikely (status)) return status; - status = cairo_surface_status (surface->meta); + status = surface->meta->status; if (unlikely (status)) return status; cairo_surface_destroy (surface->meta); - surface->meta = cairo_meta_surface_create (surface->content, - surface->width, - surface->height); - status = cairo_surface_status (surface->meta); + surface->meta = _create_meta_surface_for_target (surface->target, + surface->content); + status = surface->meta->status; if (unlikely (status)) return status; @@ -494,21 +475,7 @@ _cairo_paginated_surface_show_page (void *abstract_surface) return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_cairo_paginated_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_intersect_clip_path (surface->meta, - path, fill_rule, - tolerance, antialias); -} - -static cairo_int_status_t +static cairo_bool_t _cairo_paginated_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -530,7 +497,7 @@ static cairo_int_status_t _cairo_paginated_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_paginated_surface_t *surface = abstract_surface; @@ -540,7 +507,7 @@ _cairo_paginated_surface_paint (void *abstract_surface, surface->page_is_blank = FALSE; - return _cairo_surface_paint (surface->meta, op, source, NULL); + return _cairo_surface_paint (surface->meta, op, source, clip); } static cairo_int_status_t @@ -548,11 +515,17 @@ _cairo_paginated_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_paginated_surface_t *surface = abstract_surface; - return _cairo_surface_mask (surface->meta, op, source, mask, NULL); + /* Optimize away erasing of nothing. */ + if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR) + return CAIRO_STATUS_SUCCESS; + + surface->page_is_blank = FALSE; + + return _cairo_surface_mask (surface->meta, op, source, mask, clip); } static cairo_int_status_t @@ -565,7 +538,7 @@ _cairo_paginated_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_paginated_surface_t *surface = abstract_surface; @@ -578,7 +551,8 @@ _cairo_paginated_surface_stroke (void *abstract_surface, return _cairo_surface_stroke (surface->meta, op, source, path, style, ctm, ctm_inverse, - tolerance, antialias, NULL); + tolerance, antialias, + clip); } static cairo_int_status_t @@ -589,7 +563,7 @@ _cairo_paginated_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_paginated_surface_t *surface = abstract_surface; @@ -601,7 +575,8 @@ _cairo_paginated_surface_fill (void *abstract_surface, return _cairo_surface_fill (surface->meta, op, source, path, fill_rule, - tolerance, antialias, NULL); + tolerance, antialias, + clip); } static cairo_bool_t @@ -614,20 +589,19 @@ _cairo_paginated_surface_has_show_text_glyphs (void *abstract_surface) static cairo_int_status_t _cairo_paginated_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, + cairo_operator_t op, + const cairo_pattern_t *source, + const char *utf8, + int utf8_len, + cairo_glyph_t *glyphs, + int num_glyphs, + const cairo_text_cluster_t *clusters, + int num_clusters, + cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_paginated_surface_t *surface = abstract_surface; - cairo_int_status_t status; /* Optimize away erasing of nothing. */ if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR) @@ -635,24 +609,13 @@ _cairo_paginated_surface_show_text_glyphs (void *abstract_surface, surface->page_is_blank = FALSE; - /* Since this is a "wrapping" surface, we're calling back into - * _cairo_surface_show_text_glyphs from within a call to the same. - * Since _cairo_surface_show_text_glyphs acquires a mutex, we release - * and re-acquire the mutex around this nested call. - * - * Yes, this is ugly, but we consider it pragmatic as compared to - * adding locking code to all 18 surface-backend-specific - * show_glyphs functions, (which would get less testing and likely - * lead to bugs). - */ - status = _cairo_surface_show_text_glyphs (surface->meta, op, source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font, NULL); - - return status; + return _cairo_surface_show_text_glyphs (surface->meta, op, source, + utf8, utf8_len, + glyphs, num_glyphs, + clusters, num_clusters, + cluster_flags, + scaled_font, + clip); } static cairo_surface_t * @@ -679,8 +642,6 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = { NULL, /* check_span_renderer */ _cairo_paginated_surface_copy_page, _cairo_paginated_surface_show_page, - NULL, /* set_clip_region */ - _cairo_paginated_surface_intersect_clip_path, _cairo_paginated_surface_get_extents, NULL, /* old_show_glyphs */ _cairo_paginated_surface_get_font_options, @@ -695,7 +656,6 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = { NULL, /* show_glyphs */ _cairo_paginated_surface_snapshot, NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ diff --git a/src/cairo-path-bounds.c b/src/cairo-path-bounds.c index 1fadd84dd..1a3cdf06b 100644 --- a/src/cairo-path-bounds.c +++ b/src/cairo-path-bounds.c @@ -173,7 +173,7 @@ _cairo_path_bounder_close_path (void *closure) * the control points of the curves, not the flattened path). */ void -_cairo_path_fixed_approximate_clip_extents (cairo_path_fixed_t *path, +_cairo_path_fixed_approximate_clip_extents (const cairo_path_fixed_t *path, cairo_rectangle_int_t *extents) { cairo_path_bounder_t bounder; @@ -203,7 +203,7 @@ _cairo_path_fixed_approximate_clip_extents (cairo_path_fixed_t *path, * Bezier, but we continue to ignore winding. */ void -_cairo_path_fixed_approximate_fill_extents (cairo_path_fixed_t *path, +_cairo_path_fixed_approximate_fill_extents (const cairo_path_fixed_t *path, cairo_rectangle_int_t *extents) { cairo_path_bounder_t bounder; @@ -229,9 +229,37 @@ _cairo_path_fixed_approximate_fill_extents (cairo_path_fixed_t *path, _cairo_path_bounder_fini (&bounder); } +void +_cairo_path_fixed_fill_extents (const cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_rectangle_int_t *extents) +{ + cairo_path_bounder_t bounder; + cairo_status_t status; + + _cairo_path_bounder_init (&bounder); + + status = _cairo_path_fixed_interpret_flat (path, CAIRO_DIRECTION_FORWARD, + _cairo_path_bounder_move_to, + _cairo_path_bounder_line_to, + _cairo_path_bounder_close_path, + &bounder, tolerance); + assert (status == CAIRO_STATUS_SUCCESS); + + if (bounder.has_point) { + _cairo_box_round_to_rectangle (&bounder.extents, extents); + } else { + extents->x = extents->y = 0; + extents->width = extents->height = 0; + } + + _cairo_path_bounder_fini (&bounder); +} + /* Adjusts the fill extents (above) by the device-space pen. */ void -_cairo_path_fixed_approximate_stroke_extents (cairo_path_fixed_t *path, +_cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path, cairo_stroke_style_t *style, const cairo_matrix_t *ctm, cairo_rectangle_int_t *extents) @@ -268,8 +296,37 @@ _cairo_path_fixed_approximate_stroke_extents (cairo_path_fixed_t *path, _cairo_path_bounder_fini (&bounder); } +cairo_status_t +_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t *path, + cairo_stroke_style_t *stroke_style, + const cairo_matrix_t *ctm, + const cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_rectangle_int_t *extents) +{ + cairo_traps_t traps; + cairo_box_t bbox; + cairo_status_t status; + + _cairo_traps_init (&traps); + + status = _cairo_path_fixed_stroke_to_traps (path, + stroke_style, + ctm, + ctm_inverse, + tolerance, + &traps); + + _cairo_traps_extents (&traps, &bbox); + _cairo_traps_fini (&traps); + + _cairo_box_round_to_rectangle (&bbox, extents); + + return status; +} + void -_cairo_path_fixed_bounds (cairo_path_fixed_t *path, +_cairo_path_fixed_bounds (const cairo_path_fixed_t *path, double *x1, double *y1, double *x2, double *y2) { diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index 9569c9e90..123da96e2 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -125,12 +125,12 @@ _cairo_filler_close_path (void *closure) } static cairo_int_status_t -_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path, +_cairo_path_fixed_fill_rectangle (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, cairo_traps_t *traps); cairo_status_t -_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, +_cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_traps_t *traps) @@ -138,6 +138,8 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_filler_t filler; + traps->maybe_region = path->maybe_fill_region; + /* Before we do anything else, we use a special-case filler for * a device-axis aligned rectangle if possible. */ status = _cairo_path_fixed_fill_rectangle (path, fill_rule, traps); @@ -181,12 +183,15 @@ BAIL: * this function will return %CAIRO_INT_STATUS_UNSUPPORTED. */ static cairo_int_status_t -_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path, +_cairo_path_fixed_fill_rectangle (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, cairo_traps_t *traps) { cairo_box_t box; + if (! path->is_rectilinear) + return CAIRO_INT_STATUS_UNSUPPORTED; + if (_cairo_path_fixed_is_box (path, &box)) { if (box.p1.x > box.p2.x) { cairo_fixed_t t; diff --git a/src/cairo-path-fixed-private.h b/src/cairo-path-fixed-private.h index 6bd09f765..1ef7cddaf 100644 --- a/src/cairo-path-fixed-private.h +++ b/src/cairo-path-fixed-private.h @@ -81,12 +81,26 @@ struct _cairo_path_fixed { cairo_point_t current_point; unsigned int has_current_point : 1; unsigned int has_curve_to : 1; - unsigned int is_box : 1; - unsigned int is_region : 1; + unsigned int is_rectilinear : 1; + unsigned int maybe_fill_region : 1; + unsigned int is_empty_fill : 1; cairo_path_buf_fixed_t buf; }; + +cairo_private void +_cairo_path_fixed_translate (cairo_path_fixed_t *path, + cairo_fixed_t offx, + cairo_fixed_t offy); + +cairo_private cairo_status_t +_cairo_path_fixed_append (cairo_path_fixed_t *path, + const cairo_path_fixed_t *other, + cairo_direction_t dir, + cairo_fixed_t tx, + cairo_fixed_t ty); + cairo_private unsigned long _cairo_path_fixed_hash (const cairo_path_fixed_t *path); @@ -98,14 +112,14 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a, const cairo_path_fixed_t *b); typedef struct _cairo_path_fixed_iter { - cairo_path_buf_t *buf; + const cairo_path_buf_t *buf; unsigned int n_op; unsigned int n_point; } cairo_path_fixed_iter_t; cairo_private void _cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter, - cairo_path_fixed_t *path); + const cairo_path_fixed_t *path); cairo_private cairo_bool_t _cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter, @@ -115,13 +129,19 @@ cairo_private cairo_bool_t _cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter); static inline cairo_bool_t -_cairo_path_fixed_is_region (cairo_path_fixed_t *path) +_cairo_path_fixed_fill_is_empty (const cairo_path_fixed_t *path) +{ + return path->is_empty_fill; +} + +static inline cairo_bool_t +_cairo_path_fixed_maybe_fill_region (const cairo_path_fixed_t *path) { #if WATCH_PATH - fprintf (stderr, "_cairo_path_fixed_is_region () = %s\n", - path->is_region ? "true" : "false"); + fprintf (stderr, "_cairo_path_fixed_maybe_fill_region () = %s\n", + path->maybe_fill_region ? "true" : "false"); #endif - return path->is_region; + return path->maybe_fill_region; } #endif /* CAIRO_PATH_FIXED_PRIVATE_H */ diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c index 0a550399c..9819353b3 100644 --- a/src/cairo-path-fixed.c +++ b/src/cairo-path-fixed.c @@ -96,25 +96,32 @@ _cairo_path_fixed_init (cairo_path_fixed_t *path) path->last_move_point = path->current_point; path->has_current_point = FALSE; path->has_curve_to = FALSE; - path->is_region = TRUE; - path->is_box = TRUE; + path->is_rectilinear = TRUE; + path->maybe_fill_region = TRUE; + path->is_empty_fill = TRUE; } cairo_status_t _cairo_path_fixed_init_copy (cairo_path_fixed_t *path, - cairo_path_fixed_t *other) + const cairo_path_fixed_t *other) { cairo_path_buf_t *buf, *other_buf; unsigned int num_points, num_ops, buf_size; - _cairo_path_fixed_init (path); + VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t))); + + cairo_list_init (&path->buf.base.link); + + path->buf.base.op = path->buf.op; + path->buf.base.points = path->buf.points; path->current_point = other->current_point; - path->has_current_point = other->has_current_point; path->last_move_point = other->last_move_point; + path->has_current_point = other->has_current_point; path->has_curve_to = other->has_curve_to; - path->is_box = other->is_box; - path->is_region = other->is_region; + path->is_rectilinear = other->is_rectilinear; + path->maybe_fill_region = other->maybe_fill_region; + path->is_empty_fill = other->is_empty_fill; path->buf.base.num_ops = other->buf.base.num_ops; path->buf.base.num_points = other->buf.base.num_points; @@ -214,9 +221,10 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a, return TRUE; /* use the flags to quickly differentiate based on contents */ - if (a->has_curve_to != b->has_curve_to || - a->is_region != b->is_region || - a->is_box != b->is_box) + if (a->is_empty_fill != b->is_empty_fill || + a->has_curve_to != b->has_curve_to || + a->maybe_fill_region != b->maybe_fill_region || + a->is_rectilinear != b->is_rectilinear) { return FALSE; } @@ -378,15 +386,16 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path, if (unlikely (status)) return status; - if (path->has_current_point && path->is_box) { + if (path->has_current_point && path->is_rectilinear) { /* a move-to is first an implicit close */ - path->is_box = path->current_point.x == path->last_move_point.x || - path->current_point.y == path->last_move_point.y; - path->is_region &= path->is_box; + path->is_rectilinear = path->current_point.x == path->last_move_point.x || + path->current_point.y == path->last_move_point.y; + path->maybe_fill_region &= path->is_rectilinear; } - if (path->is_region) { - path->is_region = _cairo_fixed_is_integer (x) && - _cairo_fixed_is_integer (y); + if (path->maybe_fill_region) { + path->maybe_fill_region = + _cairo_fixed_is_integer (path->last_move_point.x) && + _cairo_fixed_is_integer (path->last_move_point.y); } } @@ -437,14 +446,18 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path, status = _cairo_path_fixed_move_to (path, point.x, point.y); } else { status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1); - if (path->is_box) { - path->is_box = path->current_point.x == x || - path->current_point.y == y; - path->is_region &= path->is_box; + if (path->is_rectilinear) { + path->is_rectilinear = path->current_point.x == x || + path->current_point.y == y; + path->maybe_fill_region &= path->is_rectilinear; } - if (path->is_region) { - path->is_region = _cairo_fixed_is_integer (x) && - _cairo_fixed_is_integer (y); + if (path->maybe_fill_region) { + path->maybe_fill_region = _cairo_fixed_is_integer (x) && + _cairo_fixed_is_integer (y); + } + if (path->is_empty_fill) { + path->is_empty_fill = path->current_point.x == x && + path->current_point.y == y; } } @@ -495,9 +508,10 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path, path->current_point = point[2]; path->has_current_point = TRUE; + path->is_empty_fill = FALSE; path->has_curve_to = TRUE; - path->is_box = FALSE; - path->is_region = FALSE; + path->is_rectilinear = FALSE; + path->maybe_fill_region = FALSE; return CAIRO_STATUS_SUCCESS; } @@ -732,49 +746,77 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path, return CAIRO_STATUS_SUCCESS; } +typedef struct _cairo_path_fixed_append_closure { + cairo_point_t offset; + cairo_path_fixed_t *path; +} cairo_path_fixed_append_closure_t; + static cairo_status_t -_append_move_to (void *closure, +_append_move_to (void *abstract_closure, const cairo_point_t *point) { - return _cairo_path_fixed_move_to (closure, point->x, point->y); + cairo_path_fixed_append_closure_t *closure = abstract_closure; + + return _cairo_path_fixed_move_to (closure->path, + point->x + closure->offset.x, + point->y + closure->offset.y); } static cairo_status_t -_append_line_to (void *closure, +_append_line_to (void *abstract_closure, const cairo_point_t *point) { - return _cairo_path_fixed_line_to (closure, point->x, point->y); + cairo_path_fixed_append_closure_t *closure = abstract_closure; + + return _cairo_path_fixed_line_to (closure->path, + point->x + closure->offset.x, + point->y + closure->offset.y); } static cairo_status_t -_append_curve_to (void *closure, +_append_curve_to (void *abstract_closure, const cairo_point_t *p0, const cairo_point_t *p1, const cairo_point_t *p2) { - return _cairo_path_fixed_curve_to (closure, - p0->x, p0->y, - p1->x, p1->y, - p2->x, p2->y); + cairo_path_fixed_append_closure_t *closure = abstract_closure; + + return _cairo_path_fixed_curve_to (closure->path, + p0->x + closure->offset.x, + p0->y + closure->offset.y, + p1->x + closure->offset.x, + p1->y + closure->offset.y, + p2->x + closure->offset.x, + p2->y + closure->offset.y); } static cairo_status_t -_append_close_path (void *closure) +_append_close_path (void *abstract_closure) { - return _cairo_path_fixed_close_path (closure); + cairo_path_fixed_append_closure_t *closure = abstract_closure; + + return _cairo_path_fixed_close_path (closure->path); } cairo_status_t -_cairo_path_fixed_append (cairo_path_fixed_t *path, - const cairo_path_fixed_t *other, - cairo_direction_t dir) +_cairo_path_fixed_append (cairo_path_fixed_t *path, + const cairo_path_fixed_t *other, + cairo_direction_t dir, + cairo_fixed_t tx, + cairo_fixed_t ty) { + cairo_path_fixed_append_closure_t closure; + + closure.path = path; + closure.offset.x = tx; + closure.offset.y = ty; + return _cairo_path_fixed_interpret (other, dir, _append_move_to, _append_line_to, _append_curve_to, _append_close_path, - path); + &closure); } static void @@ -787,6 +829,13 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path, cairo_path_buf_t *buf; unsigned int i; + if (path->maybe_fill_region) { + path->maybe_fill_region = _cairo_fixed_is_integer (offx) && + _cairo_fixed_is_integer (offy) && + _cairo_fixed_is_integer (scalex) && + _cairo_fixed_is_integer (scaley); + } + cairo_path_foreach_buf_start (buf, path) { for (i = 0; i < buf->num_points; i++) { if (scalex != CAIRO_FIXED_ONE) @@ -800,6 +849,36 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path, } cairo_path_foreach_buf_end (buf, path); } +void +_cairo_path_fixed_translate (cairo_path_fixed_t *path, + cairo_fixed_t offx, + cairo_fixed_t offy) +{ + cairo_path_buf_t *buf; + unsigned int i; + + if (offx == 0 && offy == 0) + return; + + if (path->maybe_fill_region && + ! (_cairo_fixed_is_integer (offx) && _cairo_fixed_is_integer (offy))) + { + path->maybe_fill_region = FALSE; + } + + path->last_move_point.x += offx; + path->last_move_point.y += offx; + path->current_point.x += offx; + path->current_point.y += offx; + + cairo_path_foreach_buf_start (buf, path) { + for (i = 0; i < buf->num_points; i++) { + buf->points[i].x += offx; + buf->points[i].y += offy; + } + } cairo_path_foreach_buf_end (buf, path); +} + /** * _cairo_path_fixed_transform: * @path: a #cairo_path_fixed_t to be transformed @@ -811,12 +890,14 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path, **/ void _cairo_path_fixed_transform (cairo_path_fixed_t *path, - cairo_matrix_t *matrix) + const cairo_matrix_t *matrix) { cairo_path_buf_t *buf; unsigned int i; double dx, dy; + /* XXX current_point, last_move_to */ + if (matrix->yx == 0.0 && matrix->xy == 0.0) { /* Fast path for the common case of scale+transform */ _cairo_path_fixed_offset_and_scale (path, @@ -827,6 +908,7 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path, return; } + path->maybe_fill_region = FALSE; cairo_path_foreach_buf_start (buf, path) { for (i = 0; i < buf->num_points; i++) { dx = _cairo_fixed_to_double (buf->points[i].x); @@ -841,20 +923,22 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path, } cairo_bool_t -_cairo_path_fixed_is_equal (cairo_path_fixed_t *path, - cairo_path_fixed_t *other) +_cairo_path_fixed_is_equal (const cairo_path_fixed_t *path, + const cairo_path_fixed_t *other) { - cairo_path_buf_t *path_buf, *other_buf; + const cairo_path_buf_t *path_buf, *other_buf; if (path->current_point.x != other->current_point.x || path->current_point.y != other->current_point.y || path->has_current_point != other->has_current_point || path->has_curve_to != other->has_curve_to || - path->is_box != other->is_box || - path->is_region != other->is_region || + path->is_rectilinear != other->is_rectilinear || + path->maybe_fill_region != other->maybe_fill_region || path->last_move_point.x != other->last_move_point.x || path->last_move_point.y != other->last_move_point.y) + { return FALSE; + } other_buf = cairo_path_head (other); cairo_path_foreach_buf_start (path_buf, path) { @@ -970,25 +1054,16 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path, &flattener); } -cairo_bool_t -_cairo_path_fixed_is_empty (cairo_path_fixed_t *path) -{ - if (cairo_path_head (path)->num_ops == 0) - return TRUE; - - return FALSE; -} - /* * Check whether the given path contains a single rectangle. */ cairo_bool_t -_cairo_path_fixed_is_box (cairo_path_fixed_t *path, +_cairo_path_fixed_is_box (const cairo_path_fixed_t *path, cairo_box_t *box) { - cairo_path_buf_t *buf = cairo_path_head (path); + const cairo_path_buf_t *buf = cairo_path_head (path); - if (! path->is_box) + if (! path->is_rectilinear) return FALSE; /* Do we have the right number of ops? */ @@ -1058,12 +1133,12 @@ _cairo_path_fixed_is_box (cairo_path_fixed_t *path, * */ cairo_bool_t -_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path, +_cairo_path_fixed_is_rectangle (const cairo_path_fixed_t *path, cairo_box_t *box) { - cairo_path_buf_t *buf; + const cairo_path_buf_t *buf; - if (!_cairo_path_fixed_is_box (path, box)) + if (! _cairo_path_fixed_is_box (path, box)) return FALSE; buf = cairo_path_head (path); @@ -1075,7 +1150,7 @@ _cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path, void _cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter, - cairo_path_fixed_t *path) + const cairo_path_fixed_t *path) { iter->buf = cairo_path_head (path); iter->n_op = 0; diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c index 24f43ca5e..2fa865054 100644 --- a/src/cairo-path-in-fill.c +++ b/src/cairo-path-in-fill.c @@ -38,10 +38,10 @@ typedef struct cairo_in_fill { double tolerance; + cairo_bool_t on_edge; int winding; cairo_fixed_t x, y; - cairo_bool_t on_edge; cairo_bool_t has_current_point; cairo_point_t current_point; @@ -54,12 +54,12 @@ _cairo_in_fill_init (cairo_in_fill_t *in_fill, double x, double y) { + in_fill->on_edge = FALSE; in_fill->winding = 0; in_fill->tolerance = tolerance; in_fill->x = _cairo_fixed_from_double (x); in_fill->y = _cairo_fixed_from_double (y); - in_fill->on_edge = FALSE; in_fill->has_current_point = FALSE; in_fill->current_point.x = 0; @@ -142,7 +142,7 @@ _cairo_in_fill_add_edge (cairo_in_fill_t *in_fill, return; if ((p1->x <= in_fill->x && p2->x <= in_fill->x) || - edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) <= 0) + edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) < 0) { in_fill->winding += dir; } @@ -243,16 +243,19 @@ _cairo_in_fill_close_path (void *closure) return CAIRO_STATUS_SUCCESS; } -void -_cairo_path_fixed_in_fill (cairo_path_fixed_t *path, +cairo_bool_t +_cairo_path_fixed_in_fill (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, double x, - double y, - cairo_bool_t *is_inside) + double y) { cairo_in_fill_t in_fill; cairo_status_t status; + cairo_bool_t is_inside; + + if (path->is_empty_fill) + return FALSE; _cairo_in_fill_init (&in_fill, tolerance, x, y); @@ -268,19 +271,21 @@ _cairo_path_fixed_in_fill (cairo_path_fixed_t *path, _cairo_in_fill_close_path (&in_fill); if (in_fill.on_edge) { - *is_inside = TRUE; + is_inside = TRUE; } else switch (fill_rule) { case CAIRO_FILL_RULE_EVEN_ODD: - *is_inside = in_fill.winding & 1; + is_inside = in_fill.winding & 1; break; case CAIRO_FILL_RULE_WINDING: - *is_inside = in_fill.winding != 0; + is_inside = in_fill.winding != 0; break; default: ASSERT_NOT_REACHED; - *is_inside = FALSE; + is_inside = FALSE; break; } _cairo_in_fill_fini (&in_fill); + + return is_inside; } diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 79bf09b0b..4fa4ce5ac 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -1140,13 +1140,13 @@ _cairo_stroker_close_path (void *closure) } static cairo_int_status_t -_cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path, +_cairo_path_fixed_stroke_rectilinear (const cairo_path_fixed_t *path, cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, cairo_traps_t *traps); cairo_status_t -_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, +_cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path, cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, @@ -1737,7 +1737,7 @@ _cairo_rectilinear_stroker_close_path (void *closure) } static cairo_int_status_t -_cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path, +_cairo_path_fixed_stroke_rectilinear (const cairo_path_fixed_t *path, cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, cairo_traps_t *traps) @@ -1755,7 +1755,7 @@ _cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path, * UNSUPPORTED from _cairo_rectilinear_stroker_line_to if any * non-rectilinear line_to is encountered. */ - if (path->has_curve_to) + if (! path->is_rectilinear) return CAIRO_INT_STATUS_UNSUPPORTED; if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER) return CAIRO_INT_STATUS_UNSUPPORTED; diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 9fe94ad4e..6eabaa405 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -1686,10 +1686,6 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt pattern, dst)) { - status = _cairo_surface_reset (solid_surface_cache.cache[i].surface); - if (unlikely (status)) - goto UNLOCK; - goto DONE; } @@ -1698,10 +1694,6 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt pattern, dst)) { - status = _cairo_surface_reset (solid_surface_cache.cache[i].surface); - if (unlikely (status)) - goto UNLOCK; - goto DONE; } } @@ -1717,11 +1709,6 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt dst)) { /* Reuse the surface instead of evicting */ - - status = _cairo_surface_reset (surface); - if (unlikely (status)) - goto EVICT; - status = _cairo_surface_repaint_solid_pattern_surface (dst, surface, pattern); if (unlikely (status)) goto EVICT; @@ -1738,14 +1725,21 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt if (surface == NULL) { /* Not cached, need to create new */ surface = _cairo_surface_create_solid_pattern_surface (dst, pattern); - if (surface->status) { + if (surface == NULL) { + status = CAIRO_INT_STATUS_UNSUPPORTED; + goto UNLOCK; + } + if (unlikely (surface->status)) { status = surface->status; goto UNLOCK; } - if (! _cairo_surface_is_similar (surface, dst, pattern->content)) { - /* in the rare event of a substitute surface being returned (e.g. - * malloc failure) don't cache the fallback surface */ + if (unlikely (! _cairo_surface_is_similar (surface, + dst, pattern->content))) + { + /* In the rare event of a substitute surface being returned, + * don't cache the fallback. + */ *out = surface; goto NOCACHE; } @@ -1953,6 +1947,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat double pad; cairo_bool_t is_identity; cairo_bool_t is_empty; + cairo_bool_t is_bounded; cairo_int_status_t status; surface = cairo_surface_reference (pattern->surface); @@ -2010,9 +2005,8 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat cairo_surface_t *src; int w, h; - status = _cairo_surface_get_extents (surface, &extents); - if (unlikely (status)) - goto BAIL; + is_bounded = _cairo_surface_get_extents (surface, &extents); + assert (is_bounded); status = _cairo_surface_clone_similar (dst, surface, content, extents.x, extents.y, @@ -2045,8 +2039,13 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat } cairo_surface_destroy (surface); - surface = cairo_surface_create_similar (dst, dst->content, w, h); - if (surface->status) { + surface = _cairo_surface_create_similar_solid (dst, + dst->content, w, h, + CAIRO_COLOR_TRANSPARENT, + FALSE); + if (surface == NULL) + return CAIRO_INT_STATUS_UNSUPPORTED; + if (unlikely (surface->status)) { cairo_surface_destroy (src); return surface->status; } @@ -2092,10 +2091,6 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat attr->extend = CAIRO_EXTEND_REPEAT; } - status = _cairo_surface_get_extents (surface, &extents); - if (unlikely (status)) - goto BAIL; - /* We first transform the rectangle to the coordinate space of the * source surface so that we only need to clone that portion of the * surface that will be read. @@ -2118,36 +2113,38 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat sampled_area.x += tx; sampled_area.y += ty; - if (attr->extend != CAIRO_EXTEND_REPEAT) { - /* Never acquire a larger area than the source itself */ - is_empty = _cairo_rectangle_intersect (&extents, &sampled_area); - } else { - int trim = 0; + if ( _cairo_surface_get_extents (surface, &extents)) { + if (attr->extend != CAIRO_EXTEND_REPEAT) { + /* Never acquire a larger area than the source itself */ + is_empty = _cairo_rectangle_intersect (&extents, &sampled_area); + } else { + int trim = 0; - if (sampled_area.x >= extents.x && - sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width) - { - /* source is horizontally contained within extents, trim */ - extents.x = sampled_area.x; - extents.width = sampled_area.width; - trim |= 0x1; + if (sampled_area.x >= extents.x && + sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width) + { + /* source is horizontally contained within extents, trim */ + extents.x = sampled_area.x; + extents.width = sampled_area.width; + trim |= 0x1; + } + + if (sampled_area.y >= extents.y && + sampled_area.y + (int) sampled_area.height <= extents.y + (int) extents.height) + { + /* source is vertically contained within extents, trim */ + extents.y = sampled_area.y; + extents.height = sampled_area.height; + trim |= 0x2; + } + + if (trim == 0x3) { + /* source is wholly contained within extents, drop the REPEAT */ + attr->extend = CAIRO_EXTEND_NONE; + } + + is_empty = extents.width == 0 || extents.height == 0; } - - if (sampled_area.y >= extents.y && - sampled_area.y + (int) sampled_area.height <= extents.y + (int) extents.height) - { - /* source is vertically contained within extents, trim */ - extents.y = sampled_area.y; - extents.height = sampled_area.height; - trim |= 0x2; - } - - if (trim == 0x3) { - /* source is wholly contained within extents, drop the REPEAT */ - attr->extend = CAIRO_EXTEND_NONE; - } - - is_empty = extents.width == 0 || extents.height == 0; } /* XXX can we use is_empty? */ @@ -2237,7 +2234,7 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern, { cairo_status_t status; - if (pattern->status) { + if (unlikely (pattern->status)) { *surface_out = NULL; return pattern->status; } @@ -2371,9 +2368,9 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, cairo_int_status_t status; cairo_pattern_union_t src_tmp; - if (src->status) + if (unlikely (src->status)) return src->status; - if (mask && mask->status) + if (unlikely (mask != NULL && mask->status)) return mask->status; /* If src and mask are both solid, then the mask alpha can be @@ -2441,7 +2438,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, * "infinite" extents, though it would be possible to optimize these * with a little more work. **/ -cairo_status_t +void _cairo_pattern_get_extents (const cairo_pattern_t *pattern, cairo_rectangle_int_t *extents) { @@ -2457,11 +2454,8 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern, double x1, y1, x2, y2; double pad; - status = _cairo_surface_get_extents (surface, &surface_extents); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) + if (! _cairo_surface_get_extents (surface, &surface_extents)) goto UNBOUNDED; - if (unlikely (status)) - return status; /* The filter can effectively enlarge the extents of the * pattern, so extend as necessary. @@ -2497,8 +2491,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern, extents->x = x1; extents->width = x2 - x1; extents->y = y1; extents->height = y2 - y1; - - return CAIRO_STATUS_SUCCESS; + return; } /* XXX: We could optimize gradients with pattern->extend of NONE @@ -2508,12 +2501,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern, UNBOUNDED: /* unbounded patterns -> 'infinite' extents */ - extents->x = CAIRO_RECT_INT_MIN; - extents->y = CAIRO_RECT_INT_MIN; - extents->width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; - extents->height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; - - return CAIRO_STATUS_SUCCESS; + _cairo_unbounded_rectangle_init (extents); } @@ -2749,6 +2737,9 @@ _cairo_pattern_equal (const cairo_pattern_t *a, const cairo_pattern_t *b) if (a->status || b->status) return FALSE; + if (a == b) + return TRUE; + if (a->type != b->type) return FALSE; diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h index 2e7d2445d..5c28f70ca 100644 --- a/src/cairo-pdf-surface-private.h +++ b/src/cairo-pdf-surface-private.h @@ -45,6 +45,7 @@ #include "cairo-pdf.h" #include "cairo-surface-private.h" +#include "cairo-surface-clipper-private.h" #include "cairo-pdf-operators-private.h" #include "cairo-path-fixed-private.h" @@ -174,6 +175,8 @@ struct _cairo_pdf_surface { cairo_bool_t is_knockout; } group_stream; + cairo_surface_clipper_t clipper; + cairo_pdf_operators_t pdf_operators; cairo_paginated_mode_t paginated_mode; cairo_bool_t select_pattern_gstate_saved; diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 0e5c84031..8cd46723e 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -50,6 +50,7 @@ #include "cairo-output-stream-private.h" #include "cairo-paginated-private.h" #include "cairo-scaled-font-subsets-private.h" +#include "cairo-surface-clipper-private.h" #include "cairo-type3-glyph-surface-private.h" #include @@ -243,6 +244,34 @@ _cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface, &surface->cairo_to_pdf); } +static cairo_status_t +_cairo_pdf_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) +{ + cairo_pdf_surface_t *surface = cairo_container_of (clipper, + cairo_pdf_surface_t, + clipper); + cairo_int_status_t status; + + status = _cairo_pdf_operators_flush (&surface->pdf_operators); + if (unlikely (status)) + return status; + + if (path == NULL) { + _cairo_output_stream_printf (surface->output, "Q q\n"); + + surface->current_pattern_is_solid_color = FALSE; + _cairo_pdf_operators_reset (&surface->pdf_operators); + + return CAIRO_STATUS_SUCCESS; + } + + return _cairo_pdf_operators_clip (&surface->pdf_operators, path, fill_rule); +} + static cairo_surface_t * _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, double width, @@ -313,6 +342,9 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, surface->current_operator = CAIRO_OPERATOR_OVER; surface->header_emitted = FALSE; + _cairo_surface_clipper_init (&surface->clipper, + _cairo_pdf_surface_clipper_intersect_clip_path); + _cairo_pdf_operators_init (&surface->pdf_operators, surface->output, &surface->cairo_to_pdf, @@ -325,7 +357,6 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, surface->paginated_surface = _cairo_paginated_surface_create ( &surface->base, CAIRO_CONTENT_COLOR_ALPHA, - width, height, &cairo_pdf_surface_paginated_backend); status = surface->paginated_surface->status; @@ -572,11 +603,6 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface, _cairo_pdf_surface_set_size_internal (pdf_surface, width_in_points, height_in_points); - status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface, - width_in_points, - height_in_points); - if (unlikely (status)) - status = _cairo_surface_set_error (surface, status); } static void @@ -981,9 +1007,9 @@ _get_jpx_image_info (cairo_surface_t *source, static cairo_int_status_t _get_jpeg_image_info (cairo_surface_t *source, - cairo_image_info_t *info, - const unsigned char **mime_data, - unsigned int *mime_data_length) + cairo_image_info_t *info, + const unsigned char **mime_data, + unsigned int *mime_data_length) { cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG, mime_data, mime_data_length); @@ -998,52 +1024,48 @@ _get_source_surface_size (cairo_surface_t *source, int *width, int *height) { - cairo_image_surface_t *image; - void *image_extra; cairo_status_t status; + cairo_rectangle_int_t extents; cairo_image_info_t info; const unsigned char *mime_data; unsigned int mime_data_length; if (_cairo_surface_is_meta (source)) { - cairo_rectangle_int_t extents; + cairo_meta_surface_t *meta_surface = (cairo_meta_surface_t *) source; + cairo_box_t bbox; - status = _cairo_surface_get_extents (source, &extents); + status = _cairo_meta_surface_get_bbox (meta_surface, &bbox, NULL); if (unlikely (status)) return status; + _cairo_box_round_to_rectangle (&bbox, &extents); + *width = extents.width; *height = extents.height; - - return status; + return CAIRO_STATUS_SUCCESS; } status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length); - if (status == CAIRO_STATUS_SUCCESS) { + if (status != CAIRO_INT_STATUS_UNSUPPORTED) { *width = info.width; *height = info.height; - } else if (_cairo_status_is_error (status)) { return status; } status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length); - if (status == CAIRO_STATUS_SUCCESS) { + if (status != CAIRO_INT_STATUS_UNSUPPORTED) { *width = info.width; *height = info.height; - } else if (_cairo_status_is_error (status)) { return status; } - status = _cairo_surface_acquire_source_image (source, &image, &image_extra); - if (unlikely (status)) - return status; + if (! _cairo_surface_get_extents (source, &extents)) + return CAIRO_INT_STATUS_UNSUPPORTED; - *width = image->width; - *height = image->height; + *width = extents.width; + *height = extents.height; - _cairo_surface_release_source_image (source, image, image_extra); - - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -1123,7 +1145,7 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface, static cairo_status_t _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface, const cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents, + cairo_clip_t *clip, cairo_pdf_resource_t *pattern_res, cairo_pdf_resource_t *gstate_res) { @@ -1182,8 +1204,8 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface, pdf_pattern.width = surface->width; pdf_pattern.height = surface->height; - if (extents) { - pdf_pattern.extents = *extents; + if (clip != NULL) { + pdf_pattern.extents = clip->path->extents; } else { pdf_pattern.extents.x = 0; pdf_pattern.extents.y = 0; @@ -1540,15 +1562,6 @@ _cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface) return _cairo_output_stream_get_status (surface->output); } -static cairo_surface_t * -_cairo_pdf_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - return cairo_meta_surface_create (content, width, height); -} - static void _cairo_pdf_source_surface_entry_pluck (void *entry, void *closure) { @@ -1653,6 +1666,8 @@ _cairo_pdf_surface_finish (void *abstract_surface) surface->font_subsets = NULL; } + _cairo_surface_clipper_reset (&surface->clipper); + return status; } @@ -2090,7 +2105,7 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface, return status; pad_image = &image->base; - if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD) { + if (pattern->base.extend == CAIRO_EXTEND_PAD) { cairo_box_t box; cairo_rectangle_int_t rect; cairo_surface_pattern_t pad_pattern; @@ -2121,7 +2136,8 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface, 0, 0, 0, 0, rect.width, - rect.height); + rect.height, + NULL); _cairo_pattern_fini (&pad_pattern.base); if (unlikely (status)) goto BAIL; @@ -2173,19 +2189,18 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, { double old_width, old_height; cairo_paginated_mode_t old_paginated_mode; - cairo_clip_t *old_clip; cairo_rectangle_int_t meta_extents; + cairo_bool_t is_bounded; cairo_status_t status; int alpha = 0; - status = _cairo_surface_get_extents (meta_surface, &meta_extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (meta_surface, &meta_extents); + assert (is_bounded); old_width = surface->width; old_height = surface->height; old_paginated_mode = surface->paginated_mode; - old_clip = _cairo_surface_get_clip (&surface->base); + _cairo_pdf_surface_set_size_internal (surface, meta_extents.width, meta_extents.height); @@ -2217,10 +2232,6 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, if (unlikely (status)) return status; - status = _cairo_surface_set_clip (&surface->base, old_clip); - if (unlikely (status)) - return status; - status = _cairo_pdf_surface_close_content_stream (surface); _cairo_pdf_surface_set_size_internal (surface, @@ -2264,7 +2275,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, int bbox_x, bbox_y; char draw_surface[200]; - if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD && + if (pattern->base.extend == CAIRO_EXTEND_PAD && ! _cairo_surface_is_meta (pattern->surface)) { status = _cairo_pdf_surface_emit_padded_image_surface (surface, @@ -3249,7 +3260,7 @@ _cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface, return CAIRO_STATUS_SUCCESS; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -3405,7 +3416,7 @@ _cairo_pdf_surface_show_page (void *abstract_surface) return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t +static cairo_bool_t _cairo_pdf_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -3421,32 +3432,7 @@ _cairo_pdf_surface_get_extents (void *abstract_surface, rectangle->width = (int) ceil (surface->width); rectangle->height = (int) ceil (surface->height); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - if (path == NULL) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "Q q\n"); - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_pdf_operators_clip (&surface->pdf_operators, path, fill_rule); + return TRUE; } static void @@ -5227,7 +5213,7 @@ static cairo_int_status_t _cairo_pdf_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_pdf_surface_t *surface = abstract_surface; cairo_status_t status; @@ -5244,17 +5230,21 @@ _cairo_pdf_surface_paint (void *abstract_surface, assert (_cairo_pdf_surface_operation_supported (surface, op, source)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip, &pattern_res, &gstate_res); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) + if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO)) return CAIRO_STATUS_SUCCESS; if (unlikely (status)) return status; status = _cairo_pdf_surface_select_operator (surface, op); - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { @@ -5292,7 +5282,8 @@ _cairo_pdf_surface_paint (void *abstract_surface, gstate_res.id, group->group_res.id); } else { - status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE); + status = _cairo_pdf_surface_select_pattern (surface, source, + pattern_res, FALSE); if (unlikely (status)) return status; @@ -5313,7 +5304,7 @@ _cairo_pdf_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_pdf_surface_t *surface = abstract_surface; cairo_pdf_smask_group_t *group; @@ -5341,6 +5332,10 @@ _cairo_pdf_surface_mask (void *abstract_surface, assert (_cairo_pdf_surface_operation_supported (surface, op, source)); assert (_cairo_pdf_surface_operation_supported (surface, op, mask)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + group = _cairo_pdf_surface_create_smask_group (surface); if (unlikely (group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -5381,7 +5376,7 @@ _cairo_pdf_surface_mask (void *abstract_surface, return status; status = _cairo_pdf_surface_select_operator (surface, op); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -5402,7 +5397,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_pdf_surface_t *surface = abstract_surface; cairo_status_t status; @@ -5414,17 +5409,21 @@ _cairo_pdf_surface_stroke (void *abstract_surface, assert (_cairo_pdf_surface_operation_supported (surface, op, source)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip, &pattern_res, &gstate_res); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) + if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO)) return CAIRO_STATUS_SUCCESS; if (unlikely (status)) return status; status = _cairo_pdf_surface_select_operator (surface, op); - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { @@ -5499,7 +5498,7 @@ _cairo_pdf_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_pdf_surface_t *surface = abstract_surface; cairo_status_t status; @@ -5516,17 +5515,21 @@ _cairo_pdf_surface_fill (void *abstract_surface, assert (_cairo_pdf_surface_operation_supported (surface, op, source)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip, &pattern_res, &gstate_res); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) + if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO)) return CAIRO_STATUS_SUCCESS; if (unlikely (status)) return status; status = _cairo_pdf_surface_select_operator (surface, op); - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { @@ -5604,7 +5607,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, cairo_matrix_t *stroke_ctm_inverse, double stroke_tolerance, cairo_antialias_t stroke_antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_pdf_surface_t *surface = abstract_surface; cairo_status_t status; @@ -5632,14 +5635,18 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, if (fill_op != stroke_op) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + status = _cairo_pdf_surface_select_operator (surface, fill_op); - if (status) + if (unlikely (status)) return status; fill_pattern_res.id = 0; gstate_res.id = 0; status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source, - extents, + clip, &fill_pattern_res, &gstate_res); if (unlikely (status)) @@ -5651,7 +5658,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, gstate_res.id = 0; status = _cairo_pdf_surface_add_pdf_pattern (surface, stroke_source, - extents, + clip, &stroke_pattern_res, &gstate_res); if (unlikely (status)) @@ -5705,7 +5712,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_pdf_surface_t *surface = abstract_surface; cairo_status_t status; @@ -5717,17 +5724,21 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, assert (_cairo_pdf_surface_operation_supported (surface, op, source)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + pattern_res.id = 0; gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents, + status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip, &pattern_res, &gstate_res); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) + if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO)) return CAIRO_STATUS_SUCCESS; if (unlikely (status)) return status; status = _cairo_pdf_surface_select_operator (surface, op); - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { @@ -5840,7 +5851,7 @@ _cairo_pdf_surface_set_paginated_mode (void *abstract_surface, static const cairo_surface_backend_t cairo_pdf_surface_backend = { CAIRO_SURFACE_TYPE_PDF, - _cairo_pdf_surface_create_similar, + NULL, /* create similar: handled by wrapper */ _cairo_pdf_surface_finish, NULL, /* acquire_source_image */ NULL, /* release_source_image */ @@ -5854,8 +5865,6 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = { NULL, /* check_span_renderer */ NULL, /* _cairo_pdf_surface_copy_page */ _cairo_pdf_surface_show_page, - NULL, /* set_clip_region */ - _cairo_pdf_surface_intersect_clip_path, _cairo_pdf_surface_get_extents, NULL, /* old_show_glyphs */ _cairo_pdf_surface_get_font_options, @@ -5874,7 +5883,6 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = { NULL, /* snapshot */ NULL, /* is_compatible */ - NULL, /* reset */ _cairo_pdf_surface_fill_stroke, NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ diff --git a/src/cairo-ps-surface-private.h b/src/cairo-ps-surface-private.h index 8567aff5c..e892103b5 100644 --- a/src/cairo-ps-surface-private.h +++ b/src/cairo-ps-surface-private.h @@ -44,6 +44,7 @@ #include "cairo-ps.h" #include "cairo-surface-private.h" +#include "cairo-surface-clipper-private.h" #include "cairo-pdf-operators-private.h" #include @@ -65,6 +66,7 @@ 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_matrix_t cairo_to_ps; @@ -97,6 +99,8 @@ typedef struct cairo_ps_surface { cairo_ps_level_t ps_level; cairo_ps_level_t ps_level_used; + cairo_surface_clipper_t clipper; + cairo_pdf_operators_t pdf_operators; cairo_surface_t *paginated_surface; } cairo_ps_surface_t; diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index cfe730cbc..a577d40f3 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -61,6 +61,7 @@ #include "cairo-scaled-font-subsets-private.h" #include "cairo-paginated-private.h" #include "cairo-meta-surface-private.h" +#include "cairo-surface-clipper-private.h" #include "cairo-output-stream-private.h" #include "cairo-type3-glyph-surface-private.h" #include "cairo-image-info-private.h" @@ -73,6 +74,13 @@ #define DEBUG_PS 0 +#if DEBUG_PS +#define DEBUG_FALLBACK(s) \ + fprintf (stderr, "%s::%d -- %s\n", __FUNCTION__, __LINE__, (s)) +#else +#define DEBUG_FALLBACK(s) +#endif + #ifndef HAVE_CTIME_R #define ctime_r(T, BUF) ctime (T) #endif @@ -700,6 +708,74 @@ _cairo_ps_surface_emit_footer (cairo_ps_surface_t *surface) "%%%%EOF\n"); } +static cairo_bool_t +_path_covers_bbox (cairo_ps_surface_t *surface, + cairo_path_fixed_t *path) +{ + cairo_box_t box; + + if (_cairo_path_fixed_is_rectangle (path, &box)) { + cairo_rectangle_int_t rect; + + _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) + { + return TRUE; + } + } + } + + return FALSE; +} + +static cairo_status_t +_cairo_ps_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) +{ + cairo_ps_surface_t *surface = cairo_container_of (clipper, + cairo_ps_surface_t, + clipper); + cairo_output_stream_t *stream = surface->stream; + cairo_status_t status; + + assert (surface->paginated_mode != CAIRO_PAGINATED_MODE_ANALYZE); + +#if DEBUG_PS + _cairo_output_stream_printf (stream, + "%% _cairo_ps_surface_intersect_clip_path\n"); +#endif + + if (path == NULL) { + status = _cairo_pdf_operators_flush (&surface->pdf_operators); + if (unlikely (status)) + return status; + + _cairo_output_stream_printf (stream, "Q q\n"); + + surface->current_pattern_is_solid_color = FALSE; + _cairo_pdf_operators_reset (&surface->pdf_operators); + + return CAIRO_STATUS_SUCCESS; + } + + if (_path_covers_bbox (surface, path)) + return CAIRO_STATUS_SUCCESS; + + return _cairo_pdf_operators_clip (&surface->pdf_operators, + path, + fill_rule); +} + + static cairo_surface_t * _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, double width, @@ -756,6 +832,9 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, surface->use_string_datasource = FALSE; surface->current_pattern_is_solid_color = FALSE; + _cairo_surface_clipper_init (&surface->clipper, + _cairo_ps_surface_clipper_intersect_clip_path); + _cairo_pdf_operators_init (&surface->pdf_operators, surface->stream, &surface->cairo_to_ps, @@ -771,7 +850,6 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, surface->paginated_surface = _cairo_paginated_surface_create ( &surface->base, CAIRO_CONTENT_COLOR_ALPHA, - width, height, &cairo_ps_surface_paginated_backend); status = surface->paginated_surface->status; if (status == CAIRO_STATUS_SUCCESS) { @@ -1083,11 +1161,6 @@ cairo_ps_surface_set_size (cairo_surface_t *surface, cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, -1, 0, height_in_points); _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, - width_in_points, - height_in_points); - if (unlikely (status)) - status = _cairo_surface_set_error (surface, status); } /** @@ -1288,15 +1361,6 @@ cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface) } } -static cairo_surface_t * -_cairo_ps_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - return cairo_meta_surface_create (content, width, height); -} - static cairo_status_t _cairo_ps_surface_finish (void *abstract_surface) { @@ -1346,6 +1410,8 @@ CLEANUP: free (comments[i]); _cairo_array_fini (&surface->dsc_page_setup_comments); + _cairo_surface_clipper_reset (&surface->clipper); + return status; } @@ -1369,8 +1435,11 @@ _cairo_ps_surface_end_page (cairo_ps_surface_t *surface) if (unlikely (status)) return status; - _cairo_output_stream_printf (surface->stream, - "Q\n"); + if (surface->clipper.clip.path != NULL) { + _cairo_output_stream_printf (surface->stream, "Q Q\n"); + _cairo_surface_clipper_reset (&surface->clipper); + } else + _cairo_output_stream_printf (surface->stream, "Q\n"); return CAIRO_STATUS_SUCCESS; } @@ -1448,8 +1517,6 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t static cairo_bool_t surface_pattern_supported (const cairo_surface_pattern_t *pattern) { - cairo_extend_t extend; - if (_cairo_surface_is_meta (pattern->surface)) return TRUE; @@ -1465,24 +1532,7 @@ surface_pattern_supported (const cairo_surface_pattern_t *pattern) return FALSE; */ - /* Cast away the const, trusting get_extend not to muck with it. - * And I really wish I had a way to cast away just the const, and - * not potentially coerce this pointer to an incorrect type at the - * same time. :-( - */ - extend = cairo_pattern_get_extend ((cairo_pattern_t*)&pattern->base); - switch (extend) { - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_REPEAT: - case CAIRO_EXTEND_REFLECT: - /* There's no point returning FALSE for EXTEND_PAD, as the image - * surface does not currently implement it either */ - case CAIRO_EXTEND_PAD: - return TRUE; - } - - ASSERT_NOT_REACHED; - return FALSE; + return TRUE; } static cairo_bool_t @@ -1567,10 +1617,11 @@ _cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface, } if (! pattern_supported (surface, pattern)) + { return CAIRO_INT_STATUS_UNSUPPORTED; + } - if (!(op == CAIRO_OPERATOR_SOURCE || - op == CAIRO_OPERATOR_OVER)) + if (! (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER)) return CAIRO_INT_STATUS_UNSUPPORTED; if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { @@ -1596,7 +1647,6 @@ _cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface, * render stage and we blend the transparency into the white * background to convert the pattern to opaque. */ - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern; @@ -1606,8 +1656,8 @@ _cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface, if (_cairo_pattern_is_opaque (pattern)) return CAIRO_STATUS_SUCCESS; - else - return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; + + return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; } static cairo_bool_t @@ -1824,7 +1874,8 @@ _cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t *surface, 0, 0, 0, 0, image->width, - image->height); + image->height, + NULL); if (unlikely (status)) goto fail; @@ -2109,6 +2160,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, data_compressed, data_compressed_size, FALSE); + _cairo_output_stream_printf (surface->stream, "\n"); } else { status = CAIRO_STATUS_SUCCESS; } @@ -2221,31 +2273,31 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface, double old_width, old_height; cairo_matrix_t old_cairo_to_ps; cairo_content_t old_content; - cairo_clip_t *old_clip; - cairo_rectangle_int_t meta_extents; + cairo_box_t bbox; cairo_status_t status; - status = _cairo_surface_get_extents (meta_surface, &meta_extents); - if (unlikely (status)) - return status; - old_content = surface->content; old_width = surface->width; old_height = surface->height; old_cairo_to_ps = surface->cairo_to_ps; - old_clip = _cairo_surface_get_clip (&surface->base); - surface->width = meta_extents.width; - surface->height = meta_extents.height; + + status = + _cairo_meta_surface_get_bbox ((cairo_meta_surface_t *) meta_surface, + &bbox, + NULL); + if (unlikely (status)) + return status; + + /* XXX is this still necessary? */ + surface->width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x); + surface->height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y); + surface->current_pattern_is_solid_color = FALSE; _cairo_pdf_operators_reset (&surface->pdf_operators); cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height); _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, &surface->cairo_to_ps); - _cairo_output_stream_printf (surface->stream, - " q\n" - " 0 0 %f %f rectclip\n", - surface->width, - surface->height); + _cairo_output_stream_printf (surface->stream, " q\n"); if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) { surface->content = CAIRO_CONTENT_COLOR; @@ -2265,17 +2317,13 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface, if (unlikely (status)) return status; - _cairo_output_stream_printf (surface->stream, - " Q\n"); + _cairo_output_stream_printf (surface->stream, " Q\n"); surface->content = old_content; surface->width = old_width; surface->height = old_height; surface->current_pattern_is_solid_color = FALSE; _cairo_pdf_operators_reset (&surface->pdf_operators); surface->cairo_to_ps = old_cairo_to_ps; - status = _cairo_surface_set_clip (&surface->base, old_clip); - if (unlikely (status)) - return status; _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, &surface->cairo_to_ps); @@ -2331,11 +2379,11 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface, cairo_rectangle_int_t *extents, int *width, int *height, - int *origin_x, - int *origin_y) + int *origin_x, + int *origin_y) { cairo_status_t status; - cairo_surface_t *pad_image; + cairo_surface_t *pad_image; int x = 0; int y = 0; @@ -2343,15 +2391,18 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface, surface->image = NULL; if (_cairo_surface_is_meta (pattern->surface)) { - cairo_surface_t *meta_surface = pattern->surface; - cairo_rectangle_int_t pattern_extents; + cairo_meta_surface_t *meta_surface = (cairo_meta_surface_t *) pattern->surface; + cairo_box_t bbox; + cairo_rectangle_int_t extents; - status = _cairo_surface_get_extents (meta_surface, &pattern_extents); + status = _cairo_meta_surface_get_bbox (meta_surface, &bbox, NULL); if (unlikely (status)) return status; - *width = pattern_extents.width; - *height = pattern_extents.height; + _cairo_box_round_to_rectangle (&bbox, &extents); + *width = extents.width; + *height =extents.height; + return CAIRO_STATUS_SUCCESS; } else { status = _cairo_surface_acquire_source_image (pattern->surface, &surface->acquired_image, @@ -2391,7 +2442,8 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface, 0, 0, 0, 0, rect.width, - rect.height); + rect.height, + NULL); _cairo_pattern_fini (&pad_pattern.base); if (unlikely (status)) { if (pad_image != &surface->acquired_image->base) @@ -2406,13 +2458,11 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface, *height = surface->image->height; *origin_x = x; *origin_y = y; + return CAIRO_STATUS_SUCCESS; } - return CAIRO_STATUS_SUCCESS; - BAIL: _cairo_ps_surface_release_surface (surface, pattern); - return status; } @@ -2428,10 +2478,9 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t *surface, if (_cairo_surface_is_meta (pattern->surface)) { cairo_surface_t *meta_surface = pattern->surface; - status = _cairo_ps_surface_emit_meta_surface (surface, - meta_surface); + status = _cairo_ps_surface_emit_meta_surface (surface, meta_surface); } else { - if (cairo_pattern_get_extend (&pattern->base) != CAIRO_EXTEND_PAD) { + if (pattern->base.extend != CAIRO_EXTEND_PAD) { status = _cairo_ps_surface_emit_jpeg_image (surface, pattern->surface, width, height); if (status != CAIRO_INT_STATUS_UNSUPPORTED) @@ -2540,7 +2589,6 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, int pattern_height = 0; /* squelch bogus compiler warning */ double xstep, ystep; cairo_matrix_t cairo_p2d, ps_p2d; - cairo_rectangle_int_t surface_extents; cairo_bool_t old_use_string_datasource; int origin_x = 0; int origin_y = 0; @@ -2550,12 +2598,6 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, /* cairo_pattern_set_matrix ensures the matrix is invertible */ assert (status == CAIRO_STATUS_SUCCESS); - ps_p2d = surface->cairo_to_ps; - cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d); - cairo_matrix_translate (&ps_p2d, -origin_x, -origin_y); - cairo_matrix_translate (&ps_p2d, 0.0, pattern_height); - cairo_matrix_scale (&ps_p2d, 1.0, -1.0); - status = _cairo_ps_surface_acquire_surface (surface, pattern, extents, @@ -2669,17 +2711,13 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, _cairo_output_stream_printf (surface->stream, ">>\n"); - status = _cairo_surface_get_extents (&surface->base, &surface_extents); - if (unlikely (status)) - return status; - cairo_p2d = pattern->base.matrix; status = cairo_matrix_invert (&cairo_p2d); /* cairo_pattern_set_matrix ensures the matrix is invertible */ assert (status == CAIRO_STATUS_SUCCESS); cairo_matrix_init_identity (&ps_p2d); - cairo_matrix_translate (&ps_p2d, 0.0, surface_extents.height); + 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); @@ -3163,43 +3201,7 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_cairo_ps_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_output_stream_t *stream = surface->stream; - cairo_status_t status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_STATUS_SUCCESS; - -#if DEBUG_PS - _cairo_output_stream_printf (stream, - "%% _cairo_ps_surface_intersect_clip_path\n"); -#endif - - if (path == NULL) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (stream, "Q q\n"); - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_pdf_operators_clip (&surface->pdf_operators, - path, - fill_rule); -} - -static cairo_int_status_t +static cairo_bool_t _cairo_ps_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -3215,7 +3217,7 @@ _cairo_ps_surface_get_extents (void *abstract_surface, rectangle->width = (int) ceil (surface->width); rectangle->height = (int) ceil (surface->height); - return CAIRO_STATUS_SUCCESS; + return TRUE; } static void @@ -3229,11 +3231,26 @@ _cairo_ps_surface_get_font_options (void *abstract_surface, cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY); } +static cairo_bool_t +_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip) +{ + const cairo_rectangle_int_t *clip_extents; + + clip_extents = NULL; + if (clip != NULL) + clip_extents = _cairo_clip_get_extents (clip); + + if (clip_extents != NULL) + return _cairo_rectangle_intersect (extents, clip_extents); + + return TRUE; +} + static cairo_int_status_t _cairo_ps_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *paint_extents) + cairo_clip_t *clip) { cairo_ps_surface_t *surface = abstract_surface; cairo_output_stream_t *stream = surface->stream; @@ -3250,11 +3267,11 @@ _cairo_ps_surface_paint (void *abstract_surface, "%% _cairo_ps_surface_paint\n"); #endif - status = _cairo_surface_get_extents (&surface->base, &extents); - if (unlikely (status)) - return status; + extents = surface->page_bbox; + if (! _rectangle_intersect_clip (&extents, clip)) + return CAIRO_STATUS_SUCCESS; - status = _cairo_pdf_operators_flush (&surface->pdf_operators); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); if (unlikely (status)) return status; @@ -3262,28 +3279,25 @@ _cairo_ps_surface_paint (void *abstract_surface, (source->extend == CAIRO_EXTEND_NONE || source->extend == CAIRO_EXTEND_PAD)) { - _cairo_output_stream_printf (stream, "q 0 0 %d %d rectclip\n", - extents.width, - extents.height); - + _cairo_output_stream_printf (stream, "q\n"); status = _cairo_ps_surface_paint_surface (surface, (cairo_surface_pattern_t *) source, - paint_extents, op); + &extents, op); if (unlikely (status)) return status; _cairo_output_stream_printf (stream, "Q\n"); } else { - status = _cairo_ps_surface_emit_pattern (surface, source, paint_extents, op); + status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; if (unlikely (status)) return status; - _cairo_output_stream_printf (stream, "0 0 %d %d rectfill\n", - extents.width, - extents.height); + _cairo_output_stream_printf (stream, "%d %d %d %d rectfill\n", + extents.x, extents.y, + extents.width, extents.height); } return CAIRO_STATUS_SUCCESS; @@ -3299,10 +3313,11 @@ _cairo_ps_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_ps_surface_t *surface = abstract_surface; cairo_int_status_t status; + cairo_rectangle_int_t extents; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_ps_surface_analyze_operation (surface, op, source); @@ -3314,7 +3329,15 @@ _cairo_ps_surface_stroke (void *abstract_surface, "%% _cairo_ps_surface_stroke\n"); #endif - status = _cairo_ps_surface_emit_pattern (surface, source, extents, op); + extents = surface->page_bbox; + if (! _rectangle_intersect_clip (&extents, clip)) + return CAIRO_STATUS_SUCCESS; + + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + + status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; @@ -3336,10 +3359,11 @@ _cairo_ps_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_ps_surface_t *surface = abstract_surface; cairo_int_status_t status; + cairo_rectangle_int_t extents; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_ps_surface_analyze_operation (surface, op, source); @@ -3351,14 +3375,22 @@ _cairo_ps_surface_fill (void *abstract_surface, "%% _cairo_ps_surface_fill\n"); #endif + extents = surface->page_bbox; + if (! _rectangle_intersect_clip (&extents, clip)) + return CAIRO_STATUS_SUCCESS; + + status = _cairo_pdf_operators_flush (&surface->pdf_operators); + if (unlikely (status)) + return status; + + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + if (source->type == CAIRO_PATTERN_TYPE_SURFACE && (source->extend == CAIRO_EXTEND_NONE || source->extend == CAIRO_EXTEND_PAD)) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - _cairo_output_stream_printf (surface->stream, "q\n"); status = _cairo_pdf_operators_clip (&surface->pdf_operators, @@ -3369,14 +3401,14 @@ _cairo_ps_surface_fill (void *abstract_surface, status = _cairo_ps_surface_paint_surface (surface, (cairo_surface_pattern_t *) source, - extents, op); + &extents, op); if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, "Q\n"); _cairo_pdf_operators_reset (&surface->pdf_operators); } else { - status = _cairo_ps_surface_emit_pattern (surface, source, extents, op); + status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; @@ -3398,11 +3430,12 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_ps_surface_t *surface = abstract_surface; cairo_status_t status; + cairo_rectangle_int_t extents; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return _cairo_ps_surface_analyze_operation (surface, op, source); @@ -3417,7 +3450,15 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, if (num_glyphs <= 0) return CAIRO_STATUS_SUCCESS; - status = _cairo_ps_surface_emit_pattern (surface, source, extents, op); + extents = surface->page_bbox; + if (! _rectangle_intersect_clip (&extents, clip)) + return CAIRO_STATUS_SUCCESS; + + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + + status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; @@ -3439,6 +3480,11 @@ _cairo_ps_surface_set_paginated_mode (void *abstract_surface, cairo_ps_surface_t *surface = abstract_surface; surface->paginated_mode = paginated_mode; + + if (surface->clipper.clip.path != NULL) { + _cairo_output_stream_printf (surface->stream, "Q\n"); + _cairo_surface_clipper_reset (&surface->clipper); + } } static cairo_int_status_t @@ -3462,6 +3508,11 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface, y2 = (int) ceil (surface->height); } + surface->page_bbox.x = x1; + surface->page_bbox.y = y1; + surface->page_bbox.width = x2 - x1; + surface->page_bbox.height = y2 - y1; + _cairo_output_stream_printf (surface->stream, "%%%%Page: %d %d\n", surface->num_pages, @@ -3486,7 +3537,11 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface, _cairo_output_stream_printf (surface->stream, "%%%%EndPageSetup\n" - "q\n"); + "q %d %d %d %d rectclip q\n", + surface->page_bbox.x, + surface->page_bbox.y, + surface->page_bbox.width, + surface->page_bbox.height); if (surface->num_pages == 1) { surface->bbox_x1 = x1; @@ -3517,7 +3572,7 @@ _cairo_ps_surface_supports_fine_grained_fallbacks (void *abstract_surface) static const cairo_surface_backend_t cairo_ps_surface_backend = { CAIRO_SURFACE_TYPE_PS, - _cairo_ps_surface_create_similar, + NULL, /* create similar: handled by wrapper */ _cairo_ps_surface_finish, NULL, /* acquire_source_image */ NULL, /* release_source_image */ @@ -3531,8 +3586,6 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = { NULL, /* check_span_renderer */ NULL, /* cairo_ps_surface_copy_page */ _cairo_ps_surface_show_page, - NULL, /* set_clip_region */ - _cairo_ps_surface_intersect_clip_path, _cairo_ps_surface_get_extents, NULL, /* old_show_glyphs */ _cairo_ps_surface_get_font_options, diff --git a/src/cairo-qt-surface.cpp b/src/cairo-qt-surface.cpp index 70f6d1a7a..a0d573da6 100644 --- a/src/cairo-qt-surface.cpp +++ b/src/cairo-qt-surface.cpp @@ -39,6 +39,9 @@ #include "cairoint.h" #include "cairo-types-private.h" +#include "cairo-clip-private.h" +#include "cairo-surface-clipper-private.h" +#include "cairo-region-private.h" #include "cairo-qt.h" @@ -65,6 +68,8 @@ #include +#define ENABLE_FAST_FILL 1 /* Enable workaround slow regional Qt paths */ + #if 0 #define D(x) x static const char * @@ -104,14 +109,9 @@ _opstr (cairo_operator_t op) #define DOT_LENGTH 1.0 #define DASH_LENGTH 3.0 -typedef struct { +struct cairo_qt_surface_t { cairo_surface_t base; - bool has_clipping; - // if this is true, calls to intersect_clip_path won't - // update the clip_bounds rect - bool no_update_clip_bounds; - cairo_bool_t supports_porter_duff; #if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE @@ -131,11 +131,10 @@ typedef struct { QRect window; - - QRect clip_bounds; + cairo_surface_clipper_t clipper; cairo_surface_t *image_equiv; -} cairo_qt_surface_t; +}; /* Will be true if we ever try to create a QPixmap and end * up with one without an alpha channel. @@ -186,6 +185,21 @@ _qpainter_compositionmode_from_cairo_op (cairo_operator_t op) default: case CAIRO_OPERATOR_ADD: case CAIRO_OPERATOR_SATURATE: + case CAIRO_OPERATOR_MULTIPLY: + case CAIRO_OPERATOR_SCREEN: + case CAIRO_OPERATOR_OVERLAY: + case CAIRO_OPERATOR_DARKEN: + case CAIRO_OPERATOR_LIGHTEN: + case CAIRO_OPERATOR_COLOR_DODGE: + case CAIRO_OPERATOR_COLOR_BURN: + case CAIRO_OPERATOR_HARD_LIGHT: + case CAIRO_OPERATOR_SOFT_LIGHT: + case CAIRO_OPERATOR_DIFFERENCE: + case CAIRO_OPERATOR_EXCLUSION: + case CAIRO_OPERATOR_HSL_HUE: + case CAIRO_OPERATOR_HSL_SATURATION: + case CAIRO_OPERATOR_HSL_COLOR: + case CAIRO_OPERATOR_HSL_LUMINOSITY: ASSERT_NOT_REACHED; } } @@ -211,12 +225,27 @@ _op_is_supported (cairo_qt_surface_t *qs, cairo_operator_t op) case CAIRO_OPERATOR_XOR: return TRUE; - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - return FALSE; - default: ASSERT_NOT_REACHED; + case CAIRO_OPERATOR_ADD: + case CAIRO_OPERATOR_SATURATE: + case CAIRO_OPERATOR_MULTIPLY: + case CAIRO_OPERATOR_SCREEN: + case CAIRO_OPERATOR_OVERLAY: + case CAIRO_OPERATOR_DARKEN: + case CAIRO_OPERATOR_LIGHTEN: + case CAIRO_OPERATOR_COLOR_DODGE: + case CAIRO_OPERATOR_COLOR_BURN: + case CAIRO_OPERATOR_HARD_LIGHT: + case CAIRO_OPERATOR_SOFT_LIGHT: + case CAIRO_OPERATOR_DIFFERENCE: + case CAIRO_OPERATOR_EXCLUSION: + case CAIRO_OPERATOR_HSL_HUE: + case CAIRO_OPERATOR_HSL_SATURATION: + case CAIRO_OPERATOR_HSL_COLOR: + case CAIRO_OPERATOR_HSL_LUMINOSITY: + return FALSE; + } } else { return op == CAIRO_OPERATOR_OVER; @@ -458,6 +487,8 @@ _cairo_qt_surface_finish (void *abstract_surface) if (qs->image_equiv) cairo_surface_destroy (qs->image_equiv); + _cairo_surface_clipper_reset (&qs->clipper); + #if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE if (qs->xlib_equiv) cairo_surface_destroy (qs->xlib_equiv); @@ -655,7 +686,7 @@ _cairo_qt_surface_clone_similar (void *abstract_surface, return (cairo_status_t) CAIRO_INT_STATUS_UNSUPPORTED; } -static cairo_int_status_t +static cairo_bool_t _cairo_qt_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *extents) { @@ -666,25 +697,40 @@ _cairo_qt_surface_get_extents (void *abstract_surface, extents->width = qs->window.width(); extents->height = qs->window.height(); - return CAIRO_INT_STATUS_SUCCESS; + return TRUE; } -static cairo_int_status_t -_cairo_qt_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) +static cairo_status_t +_cairo_qt_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) { - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; + cairo_qt_surface_t *qs = cairo_container_of (clipper, + cairo_qt_surface_t, + clipper); + QPainterPath qpath; + cairo_status_t status; - D(fprintf(stderr, "q[%p] intersect_clip_path %s\n", abstract_surface, path ? "(path)" : "(clear)")); + // XXX Antialiasing is ignored + status = _cairo_quartz_cairo_path_to_qpainterpath (path, + &qpath, + fill_rule); + if (unlikely (status)) + return status; - if (!qs->p) - return CAIRO_INT_STATUS_UNSUPPORTED; + qs->p->setClipPath (qpath, Qt::IntersectClip); + return CAIRO_STATUS_SUCCESS; +} - if (path == NULL) { - //fprintf (stderr, "clip clear\n"); +static void +_cairo_qt_surface_set_clip_region (cairo_qt_surface_t *qs, + cairo_region_t *clip_region) +{ + _cairo_surface_clipper_reset (&qs->clipper); + + if (clip_region == NULL) { // How the clip path is reset depends on whether we own p or not if (qs->pixmap || qs->image) { // we own p @@ -693,10 +739,38 @@ _cairo_qt_surface_intersect_clip_path (void *abstract_surface, qs->p->restore (); qs->p->save (); } + } else { + QRegion qr; + int num_rects = cairo_region_num_rectangles (clip_region); + for (int i = 0; i < num_rects; ++i) { + cairo_rectangle_int_t rect; - if (!qs->no_update_clip_bounds) { - qs->clip_bounds.setRect(0, 0, 0, 0); - qs->has_clipping = false; + cairo_region_get_rectangle (clip_region, i, &rect); + + QRect r(rect.x, rect.y, rect.width, rect.height); + qr = qr.unite(r); + } + + qs->p->setClipRegion (qr, Qt::IntersectClip); + } +} + +static cairo_int_status_t +_cairo_qt_surface_set_clip (cairo_qt_surface_t *qs, + cairo_clip_t *clip) +{ + + D(fprintf(stderr, "q[%p] intersect_clip_path %s\n", abstract_surface, path ? "(path)" : "(clear)")); + + if (clip == NULL) { + _cairo_surface_clipper_reset (&qs->clipper); + // How the clip path is reset depends on whether we own p or not + if (qs->pixmap || qs->image) { + // we own p + qs->p->setClipping (false); + } else { + qs->p->restore (); + qs->p->save (); } return CAIRO_INT_STATUS_SUCCESS; @@ -711,125 +785,21 @@ _cairo_qt_surface_intersect_clip_path (void *abstract_surface, // we do a bunch of work here to try to get rectangles or regions // down to Qt for clipping. - QRect clip_bounds; + cairo_region_t *clip_region = NULL; - // First check if it's an integer-aligned single rectangle - cairo_box_t box; - if (_cairo_path_fixed_is_box (path, &box) && - _cairo_fixed_is_integer (box.p1.x) && - _cairo_fixed_is_integer (box.p1.y) && - _cairo_fixed_is_integer (box.p2.x) && - _cairo_fixed_is_integer (box.p2.y)) - { - QRect r(_cairo_fixed_integer_part(box.p1.x), - _cairo_fixed_integer_part(box.p1.y), - _cairo_fixed_integer_part(box.p2.x - box.p1.x), - _cairo_fixed_integer_part(box.p2.y - box.p1.y)); - - r = r.normalized(); - - clip_bounds = r; - - qs->p->setClipRect (r, Qt::IntersectClip); - } else { - // Then if it's not an integer-aligned rectangle, check - // if we can extract a region (a set of rectangles) out. - // We use cairo to convert the path to traps. - - cairo_traps_t traps; - cairo_int_status_t status; - cairo_region_t *region = NULL; - - _cairo_traps_init (&traps); + cairo_int_status_t status; + status = _cairo_clip_get_region (clip, &clip_region); + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + // We weren't able to extract a region from the traps. + // Just hand the path down to QPainter. status = (cairo_int_status_t) - _cairo_path_fixed_fill_to_traps (path, - fill_rule, tolerance, &traps); - if (status) { - _cairo_traps_fini (&traps); - return status; - } - - status = _cairo_traps_extract_region (&traps, ®ion); - _cairo_traps_fini (&traps); - - if (_cairo_status_is_error ((cairo_status_t) status)) - return status; - - if (status == CAIRO_INT_STATUS_SUCCESS) { -#if 0 - cairo_box_int_t *boxes; - int n_boxes; - - QRegion qr; - - _cairo_region_get_boxes (®ion, &n_boxes, &boxes); - - for (int i = 0; i < n_boxes; i++) { - QRect r(boxes[i].p1.x, - boxes[i].p1.y, - boxes[i].p2.x - boxes[i].p1.x, - boxes[i].p2.y - boxes[i].p1.y); - - if (i == 0) - clip_bounds = r; - else - clip_bounds = clip_bounds.united(r); - - qr = qr.unite(r); - } - _cairo_region_boxes_fini (®ion, boxes); -#else - int n_boxes; - - QRegion qr; - - n_boxes = cairo_region_num_rectangles (region); - for (int i = 0; i < n_boxes; ++i) { - cairo_rectangle_int_t box; - cairo_region_get_rectangle (region, i, &box); - QRect r(box.x, box.y, box.width, box.height); - - if (0 == i) - clip_bounds = r; - else - clip_bounds = clip_bounds.united(r); - - qr = qr.unite(r); - } -#endif - _cairo_region_fini (region); - - qs->p->setClipRegion (qr, Qt::IntersectClip); - } else { - // We weren't able to extract a region from the traps. - // Just hand the path down to QPainter. - QPainterPath qpath; - cairo_status_t status; - - status = _cairo_quartz_cairo_path_to_qpainterpath (path, - &qpath, - fill_rule); - assert (status == CAIRO_STATUS_SUCCESS); - - clip_bounds = qpath.boundingRect().toAlignedRect(); - - // XXX Antialiasing is ignored - qs->p->setClipPath (qpath, Qt::IntersectClip); - } + _cairo_surface_clipper_set_clip (&qs->clipper, clip); + } else if (status == CAIRO_INT_STATUS_SUCCESS) { + _cairo_qt_surface_set_clip_region (qs, clip_region); + status = CAIRO_INT_STATUS_SUCCESS; } - if (!qs->no_update_clip_bounds) { - clip_bounds = qs->p->worldTransform().mapRect(clip_bounds); - - if (qs->has_clipping) { - qs->clip_bounds = qs->clip_bounds.intersect(clip_bounds); - } else { - qs->clip_bounds = clip_bounds; - qs->has_clipping = true; - } - } - - return CAIRO_INT_STATUS_SUCCESS; + return status; } /** @@ -1156,10 +1126,12 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs, double tolerance = 0.0, cairo_antialias_t antialias = CAIRO_ANTIALIAS_NONE) { +#if ENABLE_FAST_FILL QImage *qsSrc_image = NULL; QPixmap *qsSrc_pixmap = NULL; std::auto_ptr qsSrc_image_d; + if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) source; if (spattern->surface->type == CAIRO_SURFACE_TYPE_QT) { @@ -1190,7 +1162,6 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs, } QMatrix sourceMatrix = _qmatrix_from_cairo_matrix (source->matrix); - cairo_int_status_t status; // We can draw this faster by clipping and calling drawImage/drawPixmap. // Use our own clipping function so that we can get the @@ -1201,14 +1172,29 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs, qs->p->save(); if (path) { - qs->no_update_clip_bounds = true; - status = _cairo_qt_surface_intersect_clip_path (qs, path, fill_rule, tolerance, antialias); - qs->no_update_clip_bounds = false; + cairo_int_status_t status; - if (status != CAIRO_INT_STATUS_SUCCESS) { - qs->p->restore(); - return false; - } + cairo_clip_t clip, old_clip = qs->clipper.clip; + + _cairo_clip_init_copy (&clip, &qs->clipper.clip); + status = (cairo_int_status_t) _cairo_clip_clip (&clip, + path, + fill_rule, + tolerance, + antialias); + if (unlikely (status)) { + qs->p->restore(); + return false; + } + + status = _cairo_qt_surface_set_clip (qs, &clip); + if (unlikely (status)) { + qs->p->restore(); + return false; + } + + _cairo_clip_reset (&clip); + qs->clipper.clip = old_clip; } qs->p->setWorldMatrix (sourceMatrix.inverted(), true); @@ -1242,16 +1228,19 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs, qs->p->restore(); return true; +#else + return false; +#endif } static cairo_int_status_t _cairo_qt_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { - Q_UNUSED(extents); cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; + cairo_int_status_t status; D(fprintf(stderr, "q[%p] paint op:%s\n", abstract_surface, _opstr(op))); @@ -1261,6 +1250,10 @@ _cairo_qt_surface_paint (void *abstract_surface, if (! _op_is_supported (qs, op)) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_qt_surface_set_clip (qs, clip); + if (unlikely (status)) + return status; + if (qs->supports_porter_duff) qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op)); @@ -1283,9 +1276,8 @@ _cairo_qt_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t * extents) + cairo_clip_t *clip) { - Q_UNUSED(extents); cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; D(fprintf(stderr, "q[%p] fill op:%s\n", abstract_surface, _opstr(op))); @@ -1296,6 +1288,10 @@ _cairo_qt_surface_fill (void *abstract_surface, if (! _op_is_supported (qs, op)) return CAIRO_INT_STATUS_UNSUPPORTED; + cairo_int_status_t status = _cairo_qt_surface_set_clip (qs, clip); + if (unlikely (status)) + return status; + if (qs->supports_porter_duff) qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op)); @@ -1333,9 +1329,8 @@ _cairo_qt_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { - Q_UNUSED(extents); cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; D(fprintf(stderr, "q[%p] stroke op:%s\n", abstract_surface, _opstr(op))); @@ -1346,6 +1341,10 @@ _cairo_qt_surface_stroke (void *abstract_surface, if (! _op_is_supported (qs, op)) return CAIRO_INT_STATUS_UNSUPPORTED; + cairo_int_status_t int_status = _cairo_qt_surface_set_clip (qs, clip); + if (unlikely (int_status)) + return int_status; + QPainterPath qpath; cairo_status_t status; @@ -1387,8 +1386,8 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; @@ -1404,37 +1403,6 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface, glyphs[i].y -= qs->redir_offset.y(); } - if (qs->has_clipping != qs->xlib_has_clipping || - qs->clip_bounds != qs->xlib_clip_bounds) - { - cairo_status_t status; - - status = _cairo_surface_reset_clip (qs->xlib_equiv); - assert (status == CAIRO_STATUS_SUCCESS); - - if (qs->has_clipping) { - cairo_region_t region; - cairo_rectangle_int_t rect = { - qs->clip_bounds.x() - qs->redir_offset.x(), - qs->clip_bounds.y() - qs->redir_offset.y(), - qs->clip_bounds.width(), - qs->clip_bounds.height() - }; - - _cairo_region_init_rectangle (®ion, &rect); - status = _cairo_surface_set_clip_region (qs->xlib_equiv, - ®ion, - ++qs->xlib_clip_serial); - _cairo_region_fini (®ion); - - if (status) - return (cairo_int_status_t) status; - } - - qs->xlib_has_clipping = qs->has_clipping; - qs->xlib_clip_bounds = qs->clip_bounds; - } - return (cairo_int_status_t) _cairo_surface_show_text_glyphs (qs->xlib_equiv, op, source, @@ -1443,7 +1411,7 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface, NULL, 0, (cairo_text_cluster_flags_t) 0, scaled_font, - extents); + clip); } #endif @@ -1452,12 +1420,11 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface, static cairo_int_status_t _cairo_qt_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_pattern_t *mask, + cairo_clip_t *clip) { - Q_UNUSED(extents); cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; D(fprintf(stderr, "q[%p] mask op:%s\n", abstract_surface, _opstr(op))); @@ -1471,7 +1438,7 @@ _cairo_qt_surface_mask (void *abstract_surface, qs->p->setOpacity (solid_mask->color.alpha); - result = _cairo_qt_surface_paint (abstract_surface, op, source, 0); + result = _cairo_qt_surface_paint (abstract_surface, op, source, clip); qs->p->setOpacity (1.0); @@ -1498,7 +1465,8 @@ _cairo_qt_surface_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; @@ -1508,6 +1476,8 @@ _cairo_qt_surface_composite (cairo_operator_t op, if (! _op_is_supported (qs, op)) return CAIRO_INT_STATUS_UNSUPPORTED; + _cairo_qt_surface_set_clip_region (qs, clip_region); + D(fprintf(stderr, "q[%p] composite op:%s src:%p [%d %d] dst [%d %d] dim [%d %d]\n", abstract_surface, _opstr(op), (void*)pattern, src_x, src_y, dst_x, dst_y, width, height)); @@ -1618,8 +1588,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - _cairo_qt_surface_intersect_clip_path, _cairo_qt_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -1636,7 +1604,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = { NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ @@ -1728,6 +1695,10 @@ cairo_qt_surface_create (QPainter *painter) qs->window = painter->window(); + _cairo_surface_clipper_init (&qs->clipper, + _cairo_qt_surface_clipper_intersect_clip_path); + + #if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs); #endif diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c index dab3dc87d..7aa7ffdc7 100644 --- a/src/cairo-quartz-image-surface.c +++ b/src/cairo-quartz-image-surface.c @@ -58,9 +58,8 @@ _cairo_quartz_image_surface_create_similar (void *asurface, int height) { cairo_surface_t *result; - cairo_surface_t *isurf = cairo_image_surface_create (_cairo_format_from_content (content), - width, - height); + cairo_surface_t *isurf = + _cairo_image_surface_create_for_content (content, width, height); if (cairo_surface_status(isurf)) return isurf; @@ -108,18 +107,16 @@ _cairo_quartz_image_surface_acquire_dest_image (void *asurface, *image_extra = NULL; return CAIRO_STATUS_SUCCESS; - } -static cairo_int_status_t +static cairo_bool_t _cairo_quartz_image_surface_get_extents (void *asurface, cairo_rectangle_int_t *extents) { cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; *extents = surface->extents; - - return CAIRO_STATUS_SUCCESS; + return TRUE; } /* we assume some drawing happened to the image buffer; make sure it's @@ -168,8 +165,6 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - NULL, /* intersect_clip_path */ _cairo_quartz_image_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -185,7 +180,6 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = { NULL, /* surface_show_glyphs */ NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ NULL /* fill_stroke */ }; diff --git a/src/cairo-quartz-private.h b/src/cairo-quartz-private.h index 8ba896874..d7e07ac8f 100644 --- a/src/cairo-quartz-private.h +++ b/src/cairo-quartz-private.h @@ -42,6 +42,7 @@ #if CAIRO_HAS_QUARTZ_SURFACE #include "cairo-quartz.h" +#include "cairo-surface-clipper-private.h" typedef struct cairo_quartz_surface { cairo_surface_t base; @@ -52,6 +53,7 @@ typedef struct cairo_quartz_surface { void *imageData; cairo_surface_t *imageSurfaceEquiv; + cairo_surface_clipper_t clipper; cairo_rectangle_int_t extents; /* These are stored while drawing operations are in place, set up diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index 892a156df..1db8ba72f 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -38,6 +38,7 @@ #include "cairoint.h" #include "cairo-quartz-private.h" +#include "cairo-surface-clipper-private.h" #include @@ -837,7 +838,8 @@ _cairo_surface_to_cgimage (cairo_surface_t *target, } if (stype != CAIRO_SURFACE_TYPE_IMAGE) { - status = _cairo_surface_acquire_source_image (source, &isurf, &image_extra); + status = _cairo_surface_acquire_source_image (source, + &isurf, &image_extra); if (status) return status; } else { @@ -848,12 +850,11 @@ _cairo_surface_to_cgimage (cairo_surface_t *target, *image_out = NULL; } else { cairo_image_surface_t *isurf_snap = NULL; - isurf_snap = (cairo_image_surface_t*) _cairo_surface_snapshot ((cairo_surface_t*) isurf); - if (isurf_snap == NULL) - return CAIRO_STATUS_NO_MEMORY; - if (isurf_snap->base.type != CAIRO_SURFACE_TYPE_IMAGE) - return CAIRO_STATUS_SURFACE_TYPE_MISMATCH; + isurf_snap = (cairo_image_surface_t*) + _cairo_surface_snapshot (&isurf->base); + if (isurf_snap->base.status) + return isurf_snap->base.status; image = _cairo_quartz_create_cgimage (isurf_snap->format, isurf_snap->width, @@ -868,10 +869,10 @@ _cairo_surface_to_cgimage (cairo_surface_t *target, *image_out = image; } - if ((cairo_surface_t*) isurf != source) + if (&isurf->base != source) _cairo_surface_release_source_image (source, isurf, image_extra); - return status; + return CAIRO_STATUS_SUCCESS; } /* Generic #cairo_pattern_t -> CGPattern function */ @@ -942,6 +943,7 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t SurfacePatternDrawInfo *info; float rw, rh; cairo_status_t status; + cairo_bool_t is_bounded; cairo_matrix_t m; @@ -952,9 +954,8 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t spattern = (cairo_surface_pattern_t *) apattern; pat_surf = spattern->surface; - status = _cairo_surface_get_extents (pat_surf, &extents); - if (status) - return status; + is_bounded = _cairo_surface_get_extents (pat_surf, &extents); + assert (is_bounded); status = _cairo_surface_to_cgimage ((cairo_surface_t*) dest, pat_surf, &image); if (status != CAIRO_STATUS_SUCCESS) @@ -1042,9 +1043,7 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface, double x0, y0, w, h; cairo_surface_t *fallback; - cairo_t *fallback_cr; CGImageRef img; - cairo_pattern_t *source_copy; cairo_status_t status; @@ -1070,20 +1069,38 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface, fallback = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (int) w, (int) h); cairo_surface_set_device_offset (fallback, -x0, -y0); - /* Paint the source onto our temporary */ - fallback_cr = cairo_create (fallback); - cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE); +#if 0 + { + cairo_t *fallback_cr; + cairo_pattern_t *source_copy; - /* Use a copy of the pattern because it is const and could be allocated - * on the stack */ - status = _cairo_pattern_create_copy (&source_copy, source); - cairo_set_source (fallback_cr, source_copy); - cairo_pattern_destroy (source_copy); + /* Paint the source onto our temporary */ + fallback_cr = cairo_create (fallback); + cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE); - cairo_paint (fallback_cr); - cairo_destroy (fallback_cr); + /* Use a copy of the pattern because it is const and could be allocated + * on the stack */ + status = _cairo_pattern_create_copy (&source_copy, source); + cairo_set_source (fallback_cr, source_copy); + cairo_pattern_destroy (source_copy); - status = _cairo_surface_to_cgimage ((cairo_surface_t*) surface, fallback, &img); + cairo_paint (fallback_cr); + cairo_destroy (fallback_cr); + } +#else + { + cairo_pattern_union_t pattern; + + _cairo_pattern_init_static_copy (&pattern, source); + _cairo_pattern_transform (pattern_copy, + &fallback->device_transform_inverse); + status = _cairo_surface_paint (fallback, + CAIRO_OPERATOR_SOURCE, + &pattern.base, NULL); + } +#endif + + status = _cairo_surface_to_cgimage (&surface->base, fallback, &img); if (status == CAIRO_STATUS_SUCCESS && img == NULL) return DO_NOTHING; if (status) @@ -1251,6 +1268,7 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface, CGAffineTransform xform; CGRect srcRect; cairo_fixed_t fw, fh; + cairo_bool_t is_bounded; status = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf, &img); if (status == CAIRO_STATUS_SUCCESS && img == NULL) @@ -1263,9 +1281,8 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface, cairo_matrix_invert(&m); _cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceTransform); - status = _cairo_surface_get_extents (pat_surf, &extents); - if (status) - return DO_UNSUPPORTED; + is_bounded = _cairo_surface_get_extents (pat_surf, &extents); + assert (is_bounded); if (source->extend == CAIRO_EXTEND_NONE) { surface->sourceImageRect = CGRectMake (0, 0, extents.width, extents.height); @@ -1485,6 +1502,7 @@ _cairo_quartz_surface_finish (void *abstract_surface) /* Restore our saved gstate that we use to reset clipping */ CGContextRestoreGState (surface->cgContext); + _cairo_surface_clipper_reset (&surface->clipper); CGContextRelease (surface->cgContext); @@ -1700,22 +1718,21 @@ FINISH: return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t +static cairo_bool_t _cairo_quartz_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *extents) { cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; *extents = surface->extents; - - return CAIRO_STATUS_SUCCESS; + return TRUE; } static cairo_int_status_t _cairo_quartz_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; @@ -1729,6 +1746,10 @@ _cairo_quartz_surface_paint (void *abstract_surface, if (op == CAIRO_OPERATOR_DEST) return CAIRO_STATUS_SUCCESS; + rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (rv)) + return rv; + CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op)); action = _cairo_quartz_setup_source (surface, source); @@ -1771,7 +1792,7 @@ _cairo_quartz_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; @@ -1790,7 +1811,7 @@ _cairo_quartz_surface_fill (void *abstract_surface, /* Check whether the path would be a no-op */ /* XXX handle unbounded ops */ - if (_cairo_path_fixed_is_empty(path) || + if (_cairo_path_fixed_fill_is_empty(path) || (_cairo_path_fixed_is_box(path, &box) && box.p1.x == box.p2.x && box.p1.y == box.p2.y)) @@ -1798,6 +1819,10 @@ _cairo_quartz_surface_fill (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } + rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (rv)) + return rv; + CGContextSaveGState (surface->cgContext); CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE)); @@ -1879,7 +1904,7 @@ _cairo_quartz_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; @@ -1896,6 +1921,10 @@ _cairo_quartz_surface_stroke (void *abstract_surface, if (op == CAIRO_OPERATOR_DEST) return CAIRO_STATUS_SUCCESS; + rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (rv)) + return rv; + CGContextSaveGState (surface->cgContext); // Turning antialiasing off used to cause misrendering with @@ -2024,7 +2053,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, int num_glyphs, cairo_scaled_font_t *scaled_font, int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { CGAffineTransform textTransform, ctm; #define STATIC_BUF_SIZE 64 @@ -2055,6 +2084,10 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface, if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_QUARTZ) return CAIRO_INT_STATUS_UNSUPPORTED; + rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (rv)) + return rv; + CGContextSaveGState (surface->cgContext); action = _cairo_quartz_setup_source (surface, source); @@ -2239,10 +2272,10 @@ _cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface, cairo_surface_t *pat_surf = mask->surface; cairo_status_t status = CAIRO_STATUS_SUCCESS; CGAffineTransform ctm, mask_matrix; + cairo_bool_t is_bounded; - status = _cairo_surface_get_extents (pat_surf, &mask_extents); - if (status) - return status; + is_bounded = _cairo_surface_get_extents (pat_surf, &mask_extents); + assert (is_bounded); // everything would be masked out, so do nothing if (mask_extents.width == 0 || mask_extents.height == 0) @@ -2347,7 +2380,7 @@ _cairo_quartz_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; @@ -2357,6 +2390,10 @@ _cairo_quartz_surface_mask (void *abstract_surface, if (IS_EMPTY(surface)) return CAIRO_STATUS_SUCCESS; + rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (rv)) + return rv; + if (mask->type == CAIRO_PATTERN_TYPE_SOLID) { /* This is easy; we just need to paint with the alpha. */ cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask; @@ -2387,14 +2424,15 @@ _cairo_quartz_surface_mask (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_cairo_quartz_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) +static cairo_status_t +_cairo_quartz_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) { - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; + cairo_quartz_surface_t *surface = + cairo_container_of (clipper, cairo_quartz_surface_t, clipper); quartz_stroke_t stroke; cairo_status_t status; @@ -2455,8 +2493,6 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - _cairo_quartz_surface_intersect_clip_path, _cairo_quartz_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -2477,7 +2513,6 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = { _cairo_quartz_surface_snapshot, NULL, /* is_similar */ - NULL, /* reset */ NULL /* fill_stroke */ }; @@ -2501,6 +2536,9 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext, _cairo_surface_init(&surface->base, &cairo_quartz_surface_backend, content); + _cairo_surface_clipper_init (&surface->clipper, + _cairo_quartz_surface_intersect_clip_path); + /* Save our extents */ surface->extents.x = surface->extents.y = 0; surface->extents.width = width; diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h new file mode 100644 index 000000000..8a10115d8 --- /dev/null +++ b/src/cairo-region-private.h @@ -0,0 +1,73 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Owen Taylor + * Vladimir Vukicevic + * Søren Sandmann + */ + +#ifndef CAIRO_REGION_PRIVATE_H +#define CAIRO_REGION_PRIVATE_H + +#include "cairo-types-private.h" +#include "cairo-reference-count-private.h" + +#include + +CAIRO_BEGIN_DECLS + +struct _cairo_region { + cairo_reference_count_t ref_count; + cairo_status_t status; + + pixman_region32_t rgn; +}; + +cairo_private void +_cairo_region_init (cairo_region_t *region); + +cairo_private void +_cairo_region_init_rectangle (cairo_region_t *region, + const cairo_rectangle_int_t *rectangle); + +cairo_private cairo_status_t +_cairo_region_init_rectangles (cairo_region_t *region, + const cairo_rectangle_int_t *rects, + int count); + +cairo_private void +_cairo_region_fini (cairo_region_t *region); + +CAIRO_END_DECLS + +#endif /* CAIRO_REGION_PRIVATE_H */ diff --git a/src/cairo-region.c b/src/cairo-region.c index 6dfa9332d..d6fff7f7f 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -38,7 +38,13 @@ #include "cairoint.h" +#include "cairo-region-private.h" + +/* XXX need to update pixman headers to be const as appropriate */ +#define CONST_CAST (pixman_region32_t *) + static const cairo_region_t _cairo_region_nil = { + CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NO_MEMORY, /* status */ }; @@ -82,6 +88,7 @@ _cairo_region_init (cairo_region_t *region) VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t))); region->status = CAIRO_STATUS_SUCCESS; + CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0); pixman_region32_init (®ion->rgn); } @@ -92,6 +99,7 @@ _cairo_region_init_rectangle (cairo_region_t *region, VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t))); region->status = CAIRO_STATUS_SUCCESS; + CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0); pixman_region32_init_rect (®ion->rgn, rectangle->x, rectangle->y, rectangle->width, rectangle->height); @@ -100,6 +108,7 @@ _cairo_region_init_rectangle (cairo_region_t *region, void _cairo_region_fini (cairo_region_t *region) { + assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count)); pixman_region32_fini (®ion->rgn); VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t))); } @@ -127,6 +136,7 @@ cairo_region_create (void) return (cairo_region_t *) &_cairo_region_nil; region->status = CAIRO_STATUS_SUCCESS; + CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1); pixman_region32_init (®ion->rgn); @@ -134,29 +144,23 @@ cairo_region_create (void) } slim_hidden_def (cairo_region_create); -cairo_region_t * -cairo_region_create_rectangles (cairo_rectangle_int_t *rects, - int count) +cairo_status_t +_cairo_region_init_rectangles (cairo_region_t *region, + const cairo_rectangle_int_t *rects, + int count) { pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)]; pixman_box32_t *pboxes = stack_pboxes; - cairo_region_t *region; + cairo_status_t status; int i; - region = _cairo_malloc (sizeof (cairo_region_t)); - - if (!region) - return (cairo_region_t *)&_cairo_region_nil; - - region->status = CAIRO_STATUS_SUCCESS; + status = CAIRO_STATUS_SUCCESS; + CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0); if (count > ARRAY_LENGTH (stack_pboxes)) { pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t)); - - if (unlikely (pboxes == NULL)) { - free (region); - return (cairo_region_t *)&_cairo_region_nil; - } + if (unlikely (pboxes == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); } for (i = 0; i < count; i++) { @@ -166,15 +170,35 @@ cairo_region_create_rectangles (cairo_rectangle_int_t *rects, pboxes[i].y2 = rects[i].y + rects[i].height; } - if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) { - free (region); - - region = (cairo_region_t *)&_cairo_region_nil; - } + if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); if (pboxes != stack_pboxes) free (pboxes); + return region->status = status; +} + +cairo_region_t * +cairo_region_create_rectangles (const cairo_rectangle_int_t *rects, + int count) +{ + cairo_region_t *region; + cairo_status_t status; + + region = _cairo_malloc (sizeof (cairo_region_t)); + if (unlikely (region == NULL)) { + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); + return (cairo_region_t *) &_cairo_region_nil; + } + + status = _cairo_region_init_rectangles (region, rects, count); + if (unlikely (status)) { + cairo_region_destroy (region); + return (cairo_region_t *) &_cairo_region_nil; + } + + CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1); return region; } slim_hidden_def (cairo_region_create_rectangles); @@ -199,10 +223,11 @@ cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle) cairo_region_t *region; region = _cairo_malloc (sizeof (cairo_region_t)); - if (region == NULL) + if (unlikely (region == NULL)) return (cairo_region_t *) &_cairo_region_nil; region->status = CAIRO_STATUS_SUCCESS; + CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1); pixman_region32_init_rect (®ion->rgn, rectangle->x, rectangle->y, @@ -227,18 +252,20 @@ slim_hidden_def (cairo_region_create_rectangle); * Since: 1.10 **/ cairo_region_t * -cairo_region_copy (cairo_region_t *original) +cairo_region_copy (const cairo_region_t *original) { cairo_region_t *copy; - if (original->status) + if (original != NULL && original->status) return (cairo_region_t *) &_cairo_region_nil; copy = cairo_region_create (); - if (copy->status) + if (unlikely (copy->status)) return copy; - if (! pixman_region32_copy (©->rgn, &original->rgn)) { + if (original != NULL && + ! pixman_region32_copy (©->rgn, CONST_CAST &original->rgn)) + { cairo_region_destroy (copy); return (cairo_region_t *) &_cairo_region_nil; } @@ -247,6 +274,31 @@ cairo_region_copy (cairo_region_t *original) } slim_hidden_def (cairo_region_copy); +/** + * cairo_region_reference: + * @region: a #cairo_region_t + * + * Increases the reference count on @region by one. This prevents + * @region from being destroyed until a matching call to + * cairo_region_destroy() is made. + * + * Return value: the referenced #cairo_region_t. + * + * Since: 1.10 + **/ +cairo_region_t * +cairo_region_reference (cairo_region_t *region) +{ + if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count)) + return NULL; + + assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count)); + + _cairo_reference_count_inc (®ion->ref_count); + return region; +} +slim_hidden_def (cairo_region_reference); + /** * cairo_region_destroy: * @region: a #cairo_region_t @@ -260,10 +312,15 @@ slim_hidden_def (cairo_region_copy); void cairo_region_destroy (cairo_region_t *region) { - if (region == (cairo_region_t *) &_cairo_region_nil) + if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count)) return; - pixman_region32_fini (®ion->rgn); + assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count)); + + if (! _cairo_reference_count_dec_and_test (®ion->ref_count)) + return; + + _cairo_region_fini (region); free (region); } slim_hidden_def (cairo_region_destroy); @@ -279,12 +336,12 @@ slim_hidden_def (cairo_region_destroy); * Since: 1.10 **/ int -cairo_region_num_rectangles (cairo_region_t *region) +cairo_region_num_rectangles (const cairo_region_t *region) { if (region->status) return 0; - return pixman_region32_n_rects (®ion->rgn); + return pixman_region32_n_rects (CONST_CAST ®ion->rgn); } slim_hidden_def (cairo_region_num_rectangles); @@ -299,7 +356,7 @@ slim_hidden_def (cairo_region_num_rectangles); * Since: 1.10 **/ void -cairo_region_get_rectangle (cairo_region_t *region, +cairo_region_get_rectangle (const cairo_region_t *region, int nth, cairo_rectangle_int_t *rectangle) { @@ -311,7 +368,7 @@ cairo_region_get_rectangle (cairo_region_t *region, return; } - pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth; + pbox = pixman_region32_rectangles (CONST_CAST ®ion->rgn, NULL) + nth; rectangle->x = pbox->x1; rectangle->y = pbox->y1; @@ -330,7 +387,7 @@ slim_hidden_def (cairo_region_get_rectangle); * Since: 1.10 **/ void -cairo_region_get_extents (cairo_region_t *region, +cairo_region_get_extents (const cairo_region_t *region, cairo_rectangle_int_t *extents) { pixman_box32_t *pextents; @@ -341,7 +398,7 @@ cairo_region_get_extents (cairo_region_t *region, return; } - pextents = pixman_region32_extents (®ion->rgn); + pextents = pixman_region32_extents (CONST_CAST ®ion->rgn); extents->x = pextents->x1; extents->y = pextents->y1; @@ -362,7 +419,7 @@ slim_hidden_def (cairo_region_get_extents); * Since: 1.10 **/ cairo_status_t -cairo_region_status (cairo_region_t *region) +cairo_region_status (const cairo_region_t *region) { return region->status; } @@ -564,12 +621,12 @@ slim_hidden_def (cairo_region_union_rectangle); * Since: 1.10 **/ cairo_bool_t -cairo_region_is_empty (cairo_region_t *region) +cairo_region_is_empty (const cairo_region_t *region) { if (region->status) return TRUE; - return ! pixman_region32_not_empty (®ion->rgn); + return ! pixman_region32_not_empty (CONST_CAST ®ion->rgn); } slim_hidden_def (cairo_region_is_empty); @@ -610,7 +667,7 @@ slim_hidden_def (cairo_region_translate); * Since: 1.10 **/ cairo_region_overlap_t -cairo_region_contains_rectangle (cairo_region_t *region, +cairo_region_contains_rectangle (const cairo_region_t *region, const cairo_rectangle_int_t *rectangle) { pixman_box32_t pbox; @@ -624,7 +681,8 @@ cairo_region_contains_rectangle (cairo_region_t *region, pbox.x2 = rectangle->x + rectangle->width; pbox.y2 = rectangle->y + rectangle->height; - poverlap = pixman_region32_contains_rectangle (®ion->rgn, &pbox); + poverlap = pixman_region32_contains_rectangle (CONST_CAST ®ion->rgn, + &pbox); switch (poverlap) { default: case PIXMAN_REGION_OUT: return CAIRO_REGION_OVERLAP_OUT; @@ -647,14 +705,44 @@ slim_hidden_def (cairo_region_contains_rectangle); * Since: 1.10 **/ cairo_bool_t -cairo_region_contains_point (cairo_region_t *region, +cairo_region_contains_point (const cairo_region_t *region, int x, int y) { pixman_box32_t box; - + if (region->status) return FALSE; - return pixman_region32_contains_point (®ion->rgn, x, y, &box); + return pixman_region32_contains_point (CONST_CAST ®ion->rgn, x, y, &box); } slim_hidden_def (cairo_region_contains_point); + +/** + * cairo_region_equal: + * @region_a: a #cairo_region_t + * @region_b: a #cairo_region_t + * + * Compares whether region_a is equivalent to region_b. + * + * Return value: %TRUE if both regions contained the same coverage, + * %FALSE if it is not. + * + * Since: 1.10 + **/ +cairo_bool_t +cairo_region_equal (const cairo_region_t *a, + const cairo_region_t *b) +{ + /* error objects are never equal */ + if ((a != NULL && a->status) || (b != NULL && b->status)) + return FALSE; + + if (a == b) + return TRUE; + + if (a == NULL || b == NULL) + return FALSE; + + return pixman_region32_equal (CONST_CAST &a->rgn, CONST_CAST &b->rgn); +} +slim_hidden_def (cairo_region_equal); diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 0510264b4..bf5a4f736 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -1969,18 +1969,19 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font, } cairo_status_t -_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, - cairo_operator_t op, +_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, + cairo_operator_t op, const cairo_pattern_t *pattern, - cairo_surface_t *surface, - int source_x, - int source_y, - int dest_x, - int dest_y, - unsigned int width, - unsigned int height, - cairo_glyph_t *glyphs, - int num_glyphs) + cairo_surface_t *surface, + int source_x, + int source_y, + int dest_x, + int dest_y, + unsigned int width, + unsigned int height, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_region_t *clip_region) { cairo_status_t status; cairo_surface_t *mask = NULL; @@ -2008,7 +2009,9 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, source_x, source_y, dest_x, dest_y, width, height, - glyphs, num_glyphs, &remaining_glyphs); + glyphs, num_glyphs, + clip_region, + &remaining_glyphs); glyphs += num_glyphs - remaining_glyphs; num_glyphs = remaining_glyphs; if (remaining_glyphs == 0) @@ -2088,7 +2091,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, 0, 0, 0, 0, 0, 0, - width, height); + width, height, + NULL); _cairo_pattern_fini (&mask_pattern.base); @@ -2116,7 +2120,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, 0, 0, x - dest_x, y - dest_y, glyph_surface->width, - glyph_surface->height); + glyph_surface->height, + NULL); _cairo_pattern_fini (&glyph_pattern.base); @@ -2134,7 +2139,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, source_x, source_y, 0, 0, dest_x, dest_y, - width, height); + width, height, + clip_region); _cairo_pattern_fini (&mask_pattern.base); @@ -2148,58 +2154,6 @@ CLEANUP_MASK: return _cairo_scaled_font_set_error (scaled_font, status); } -typedef struct _cairo_scaled_glyph_path_closure { - cairo_point_t offset; - cairo_path_fixed_t *path; -} cairo_scaled_glyph_path_closure_t; - -static cairo_status_t -_scaled_glyph_path_move_to (void *abstract_closure, - const cairo_point_t *point) -{ - cairo_scaled_glyph_path_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_move_to (closure->path, - point->x + closure->offset.x, - point->y + closure->offset.y); -} - -static cairo_status_t -_scaled_glyph_path_line_to (void *abstract_closure, - const cairo_point_t *point) -{ - cairo_scaled_glyph_path_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_line_to (closure->path, - point->x + closure->offset.x, - point->y + closure->offset.y); -} - -static cairo_status_t -_scaled_glyph_path_curve_to (void *abstract_closure, - const cairo_point_t *p0, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - cairo_scaled_glyph_path_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_curve_to (closure->path, - p0->x + closure->offset.x, - p0->y + closure->offset.y, - p1->x + closure->offset.x, - p1->y + closure->offset.y, - p2->x + closure->offset.x, - p2->y + closure->offset.y); -} - -static cairo_status_t -_scaled_glyph_path_close_path (void *abstract_closure) -{ - cairo_scaled_glyph_path_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_close_path (closure->path); -} - /* Add a single-device-unit rectangle to a path. */ static cairo_status_t _add_unit_rectangle_to_path (cairo_path_fixed_t *path, int x, int y) @@ -2309,14 +2263,13 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, { cairo_status_t status; int i; - cairo_scaled_glyph_path_closure_t closure; + cairo_path_fixed_t glyph_path_static; cairo_path_fixed_t *glyph_path; status = scaled_font->status; if (unlikely (status)) return status; - closure.path = path; _cairo_scaled_font_freeze_cache (scaled_font); for (i = 0; i < num_glyphs; i++) { cairo_scaled_glyph_t *scaled_glyph; @@ -2325,14 +2278,12 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_PATH, &scaled_glyph); - if (status == CAIRO_STATUS_SUCCESS) + if (status == CAIRO_STATUS_SUCCESS) { glyph_path = scaled_glyph->path; - else if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto BAIL; - - /* If the font is incapable of providing a path, then we'll - * have to trace our own from a surface. */ - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + /* If the font is incapable of providing a path, then we'll + * have to trace our own from a surface. + */ status = _cairo_scaled_glyph_lookup (scaled_font, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_SURFACE, @@ -2340,31 +2291,22 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, if (unlikely (status)) goto BAIL; - glyph_path = _cairo_path_fixed_create (); - if (unlikely (glyph_path == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - + _cairo_path_fixed_init (&glyph_path_static); + glyph_path = &glyph_path_static; status = _trace_mask_to_path (scaled_glyph->surface, glyph_path); - if (unlikely (status)) { - _cairo_path_fixed_destroy (glyph_path); + if (unlikely (status)) goto BAIL; - } + } else { + goto BAIL; } - closure.offset.x = _cairo_fixed_from_double (glyphs[i].x); - closure.offset.y = _cairo_fixed_from_double (glyphs[i].y); + status = _cairo_path_fixed_append (path, + glyph_path, CAIRO_DIRECTION_FORWARD, + _cairo_fixed_from_double (glyphs[i].x), + _cairo_fixed_from_double (glyphs[i].y)); - status = _cairo_path_fixed_interpret (glyph_path, - CAIRO_DIRECTION_FORWARD, - _scaled_glyph_path_move_to, - _scaled_glyph_path_line_to, - _scaled_glyph_path_curve_to, - _scaled_glyph_path_close_path, - &closure); if (glyph_path != scaled_glyph->path) - _cairo_path_fixed_destroy (glyph_path); + _cairo_path_fixed_fini (glyph_path); if (unlikely (status)) goto BAIL; diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c index 059ef95b8..fb1a4f8f2 100644 --- a/src/cairo-script-surface.c +++ b/src/cairo-script-surface.c @@ -51,6 +51,10 @@ #include "cairo-list-private.h" #include "cairo-meta-surface-private.h" #include "cairo-output-stream-private.h" +#include "cairo-surface-clipper-private.h" +#include "cairo-surface-wrapper-private.h" + +#include #define _cairo_output_stream_puts(S, STR) \ _cairo_output_stream_write ((S), (STR), strlen (STR)) @@ -85,6 +89,7 @@ struct _cairo_script_vmcontext { cairo_list_t deferred; cairo_script_surface_font_private_t *fonts; + cairo_list_t defines; }; struct _cairo_script_surface_font_private { @@ -114,7 +119,10 @@ struct _cairo_script_implicit_context { struct _cairo_script_surface { cairo_surface_t base; + cairo_surface_wrapper_t wrapper; + cairo_script_vmcontext_t *ctx; + cairo_surface_clipper_t clipper; unsigned long id; cairo_list_t operand; @@ -131,7 +139,11 @@ static const cairo_surface_backend_t _cairo_script_surface_backend; static cairo_script_surface_t * _cairo_script_surface_create_internal (cairo_script_vmcontext_t *ctx, double width, - double height); + double height, + cairo_surface_t *passthrough); + +static cairo_status_t +_vmcontext_destroy (cairo_script_vmcontext_t *ctx); static void _cairo_script_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font); @@ -637,9 +649,10 @@ _emit_dash (cairo_script_surface_t *surface, if (num_dashes) { surface->cr.current_style.dash = _cairo_realloc_ab - (surface->cr.current_style.dash, - num_dashes, - sizeof (double)); + (surface->cr.current_style.dash, num_dashes, sizeof (double)); + if (unlikely (surface->cr.current_style.dash == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + memcpy (surface->cr.current_style.dash, dash, sizeof (double) * num_dashes); } else { @@ -833,50 +846,46 @@ static cairo_status_t _emit_meta_surface_pattern (cairo_script_surface_t *surface, const cairo_pattern_t *pattern) { + cairo_script_implicit_context_t old_cr; cairo_surface_pattern_t *surface_pattern; - cairo_surface_t *source; - cairo_surface_t *null_surface; - cairo_surface_t *analysis_surface; + cairo_meta_surface_t *source; cairo_script_surface_t *similar; cairo_status_t status; cairo_box_t bbox; - int width, height; + cairo_rectangle_int_t rect; surface_pattern = (cairo_surface_pattern_t *) pattern; - source = surface_pattern->surface; + source = (cairo_meta_surface_t *) surface_pattern->surface; /* first measure the extents */ - null_surface = _cairo_null_surface_create (source->content); - analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1); - cairo_surface_destroy (null_surface); - - status = analysis_surface->status; + status = _cairo_meta_surface_get_bbox (source, &bbox, NULL); if (unlikely (status)) return status; - status = cairo_meta_surface_replay (source, analysis_surface); - _cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox); - cairo_surface_destroy (analysis_surface); - if (unlikely (status)) - return status; - - width = _cairo_fixed_integer_ceil (bbox.p2.x - bbox.p1.x); - height = _cairo_fixed_integer_ceil (bbox.p2.y - bbox.p1.y); + /* convert to extents so that it matches the public api */ + _cairo_box_round_to_rectangle (&bbox, &rect); similar = _cairo_script_surface_create_internal (surface->ctx, - width, height); + rect.width, + rect.height, + NULL); if (unlikely (similar->base.status)) return similar->base.status; + cairo_surface_set_device_offset (&similar->base, -rect.x, -rect.y); _get_target (surface); _cairo_output_stream_printf (surface->ctx->stream, - "%u %u //%s similar dup context\n", - width, height, + "%d %d //%s similar dup context\n", + rect.width, rect.height, _content_to_string (source->content)); target_push (similar); - status = cairo_meta_surface_replay (source, &similar->base); + old_cr = surface->cr; + _cairo_script_implicit_context_init (&surface->cr); + status = cairo_meta_surface_replay (&source->base, &similar->base); + surface->cr = old_cr; + if (unlikely (status)) { cairo_surface_destroy (&similar->base); return status; @@ -1048,6 +1057,23 @@ _emit_png_surface (cairo_script_surface_t *surface, return CAIRO_STATUS_SUCCESS; } +struct def { + cairo_script_vmcontext_t *ctx; + cairo_user_data_array_t *user_data; + unsigned int tag; + cairo_list_t link; +}; + +static void +_undef (void *data) +{ + struct def *def = data; + + cairo_list_del (&def->link); + _cairo_output_stream_printf (def->ctx->stream, "/s%u undef ", def->tag); + free (def); +} + static cairo_status_t _emit_image_surface (cairo_script_surface_t *surface, cairo_image_surface_t *image) @@ -1057,12 +1083,23 @@ _emit_image_surface (cairo_script_surface_t *surface, cairo_status_t status, status2; const uint8_t *mime_data; unsigned int mime_data_length; + struct def *tag; + + if (_cairo_user_data_array_get_data (&image->base.user_data, + (cairo_user_data_key_t *) surface->ctx)) + { + _cairo_output_stream_printf (surface->ctx->stream, + "s%u pattern ", + image->base.unique_id); + return CAIRO_STATUS_SUCCESS; + } status = _emit_png_surface (surface, image); if (_cairo_status_is_error (status)) { return status; } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) { cairo_image_surface_t *clone; + uint32_t len; if (image->format == CAIRO_FORMAT_INVALID) { clone = @@ -1078,14 +1115,34 @@ _emit_image_surface (cairo_script_surface_t *surface, "/width %d " "/height %d " "/format //%s " - "/source <~", + "/source ", clone->width, clone->height, _format_to_string (clone->format)); - if (clone->width * clone->height > 8) { - base85_stream = _cairo_base85_stream_create (surface->ctx->stream); - zlib_stream = _cairo_deflate_stream_create (base85_stream); + switch (clone->format) { + case CAIRO_FORMAT_A1: + len = (clone->width + 7)/8; + break; + case CAIRO_FORMAT_A8: + len = clone->width; + break; + case CAIRO_FORMAT_RGB24: + len = clone->width * 3; + break; + case CAIRO_FORMAT_ARGB32: + len = clone->width * 4; + break; + } + len *= clone->height; + if (len > 24) { + _cairo_output_stream_puts (surface->ctx->stream, "<|"); + + base85_stream = _cairo_base85_stream_create (surface->ctx->stream); + + _cairo_output_stream_write (base85_stream, &len, sizeof (len)); + + zlib_stream = _cairo_deflate_stream_create (base85_stream); status = _write_image_surface (zlib_stream, clone); status2 = _cairo_output_stream_destroy (zlib_stream); @@ -1096,23 +1153,42 @@ _emit_image_surface (cairo_script_surface_t *surface, status = status2; if (unlikely (status)) return status; - - _cairo_output_stream_puts (surface->ctx->stream, - " /deflate filter >> image "); } else { + _cairo_output_stream_puts (surface->ctx->stream, "<~"); + base85_stream = _cairo_base85_stream_create (surface->ctx->stream); status = _write_image_surface (base85_stream, clone); status2 = _cairo_output_stream_destroy (base85_stream); if (status == CAIRO_STATUS_SUCCESS) status = status2; - - _cairo_output_stream_puts (surface->ctx->stream, - " >> image "); + if (unlikely (status)) + return status; } + _cairo_output_stream_puts (surface->ctx->stream, " >> image "); cairo_surface_destroy (&clone->base); } + tag = malloc (sizeof (*tag)); + if (unlikely (tag == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + tag->ctx = surface->ctx; + tag->tag = image->base.unique_id; + tag->user_data = &image->base.user_data; + cairo_list_add (&tag->link, &surface->ctx->defines); + status = _cairo_user_data_array_set_data (&image->base.user_data, + (cairo_user_data_key_t *) surface->ctx, + tag, _undef); + if (unlikely (status)) { + free (tag); + return status; + } + + _cairo_output_stream_printf (surface->ctx->stream, + "dup /s%u exch def ", + image->base.unique_id); + cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_JPEG, &mime_data, &mime_data_length); if (mime_data != NULL) { @@ -1126,14 +1202,28 @@ _emit_image_surface (cairo_script_surface_t *surface, if (unlikely (status)) return status; - _cairo_output_stream_puts (surface->ctx->stream, - " set-mime-data\n"); + _cairo_output_stream_puts (surface->ctx->stream, " set-mime-data\n"); } - _cairo_output_stream_puts (surface->ctx->stream, - "pattern"); + cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_JP2, + &mime_data, &mime_data_length); + if (mime_data != NULL) { + _cairo_output_stream_printf (surface->ctx->stream, + "\n (%s) <~", + CAIRO_MIME_TYPE_JP2); - return status; + base85_stream = _cairo_base85_stream_create (surface->ctx->stream); + _cairo_output_stream_write (base85_stream, mime_data, mime_data_length); + status = _cairo_output_stream_destroy (base85_stream); + if (unlikely (status)) + return status; + + _cairo_output_stream_puts (surface->ctx->stream, " set-mime-data\n"); + } + + _cairo_output_stream_puts (surface->ctx->stream, "pattern"); + + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -1141,22 +1231,17 @@ _emit_image_surface_pattern (cairo_script_surface_t *surface, const cairo_pattern_t *pattern) { cairo_surface_pattern_t *surface_pattern; - cairo_surface_t *source; cairo_image_surface_t *image; - void *image_extra; cairo_status_t status; + /* XXX keeping a copy is nasty, but we want to hook into the surface's + * lifetime. Using a snapshot is a convenient method. + */ surface_pattern = (cairo_surface_pattern_t *) pattern; - source = surface_pattern->surface; - - /* XXX snapshot-cow */ - status = _cairo_surface_acquire_source_image (source, &image, &image_extra); - if (unlikely (status)) - return status; - + image = (cairo_image_surface_t *) + _cairo_surface_snapshot (surface_pattern->surface); status = _emit_image_surface (surface, image); - - _cairo_surface_release_source_image (source, image, image_extra); + cairo_surface_destroy (&image->base); return status; } @@ -1249,6 +1334,9 @@ _emit_pattern (cairo_script_surface_t *surface, _extend_to_string (pattern->extend)); } + if (need_newline) + _cairo_output_stream_puts (surface->ctx->stream, "\n "); + return CAIRO_STATUS_SUCCESS; } @@ -1414,13 +1502,21 @@ _emit_path (cairo_script_surface_t *surface, } static cairo_status_t -_emit_matrix (cairo_script_surface_t *surface, - const cairo_matrix_t *ctm, - cairo_bool_t *matrix_updated) +_emit_scaling_matrix (cairo_script_surface_t *surface, + const cairo_matrix_t *ctm, + cairo_bool_t *matrix_updated) { + cairo_matrix_t current, ctm_scaling; + assert (target_is_active (surface)); - if (memcmp (&surface->cr.current_ctm, ctm, sizeof (cairo_matrix_t)) == 0) + current = surface->cr.current_ctm; + current.x0 = current.y0 = 0; + + ctm_scaling = *ctm; + ctm_scaling.x0 = ctm_scaling.y0 = 0; + + if (memcmp (¤t, &ctm_scaling, sizeof (cairo_matrix_t)) == 0) return CAIRO_STATUS_SUCCESS; *matrix_updated = TRUE; @@ -1475,11 +1571,11 @@ _cairo_script_surface_create_similar (void *abstract_surface, int width, int height) { - cairo_script_surface_t *surface, *other; + cairo_script_surface_t *surface, *other = abstract_surface; + cairo_surface_t *passthrough = NULL; cairo_script_vmcontext_t *ctx; cairo_status_t status; - other = abstract_surface; ctx = other->ctx; if (other->id == (unsigned long) -1) { @@ -1490,8 +1586,20 @@ _cairo_script_surface_create_similar (void *abstract_surface, target_push (other); } - surface = _cairo_script_surface_create_internal (ctx, width, height); - if (surface->base.status) + if (_cairo_surface_wrapper_is_active (&other->wrapper)) { + passthrough = + _cairo_surface_wrapper_create_similar (&other->wrapper, + content, width, height); + if (unlikely (passthrough->status)) + return passthrough; + } + + surface = _cairo_script_surface_create_internal (ctx, + width, height, + passthrough); + cairo_surface_destroy (passthrough); + + if (unlikely (surface->base.status)) return &surface->base; status = _bitmap_next_id (&ctx->surface_id, @@ -1527,6 +1635,16 @@ _vmcontext_destroy (cairo_script_vmcontext_t *ctx) _cairo_script_surface_scaled_font_fini (font->parent); } + while (! cairo_list_is_empty (&ctx->defines)) { + struct def *def = cairo_list_first_entry (&ctx->defines, + struct def, link); + + status = _cairo_user_data_array_set_data (def->user_data, + (cairo_user_data_key_t *) ctx, + NULL, NULL); + assert (status == CAIRO_STATUS_SUCCESS); + } + status = _cairo_output_stream_destroy (ctx->stream); free (ctx); @@ -1534,14 +1652,50 @@ _vmcontext_destroy (cairo_script_vmcontext_t *ctx) return status; } +static cairo_status_t +_cairo_script_surface_acquire_source_image (void *abstract_surface, + cairo_image_surface_t **image_out, + void **image_extra) +{ + cairo_script_surface_t *surface = abstract_surface; + + if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { + return _cairo_surface_wrapper_acquire_source_image (&surface->wrapper, + image_out, + image_extra); + } + + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static void +_cairo_script_surface_release_source_image (void *abstract_surface, + cairo_image_surface_t *image, + void *image_extra) +{ + cairo_script_surface_t *surface = abstract_surface; + + assert (_cairo_surface_wrapper_is_active (&surface->wrapper)); + _cairo_surface_wrapper_release_source_image (&surface->wrapper, + image, + image_extra); +} + static cairo_status_t _cairo_script_surface_finish (void *abstract_surface) { cairo_script_surface_t *surface = abstract_surface; cairo_status_t status = CAIRO_STATUS_SUCCESS, status2; + _cairo_surface_wrapper_fini (&surface->wrapper); + + if (surface->cr.current_style.dash != NULL) { + free (surface->cr.current_style.dash); + surface->cr.current_style.dash = NULL; + } _cairo_pattern_fini (&surface->cr.current_source.base); _cairo_path_fixed_fini (&surface->cr.current_path); + _cairo_surface_clipper_reset (&surface->clipper); if (surface->id != (unsigned long) -1) { if (! surface->ctx->active) { @@ -1622,16 +1776,19 @@ _cairo_script_surface_show_page (void *abstract_surface) return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_cairo_script_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) +static cairo_status_t +_cairo_script_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) { - cairo_script_surface_t *surface = abstract_surface; + cairo_script_surface_t *surface = cairo_container_of (clipper, + cairo_script_surface_t, + clipper); cairo_bool_t matrix_updated = FALSE; cairo_status_t status; + cairo_box_t box; status = _emit_context (surface); if (unlikely (status)) @@ -1645,6 +1802,18 @@ _cairo_script_surface_intersect_clip_path (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } + /* skip the trivial clip covering the surface extents */ + if (surface->width >=0 && surface->height >= 0 && + _cairo_path_fixed_is_rectangle (path, &box)) + { + if (box.p1.x <= 0 && box.p1.y <= 0 && + box.p2.x - box.p1.x >= _cairo_fixed_from_double (surface->width) && + box.p2.y - box.p1.y >= _cairo_fixed_from_double (surface->height)) + { + return CAIRO_STATUS_SUCCESS; + } + } + status = _emit_identity (surface, &matrix_updated); if (unlikely (status)) return status; @@ -1653,13 +1822,17 @@ _cairo_script_surface_intersect_clip_path (void *abstract_surface, if (unlikely (status)) return status; - status = _emit_tolerance (surface, tolerance, matrix_updated); - if (unlikely (status)) - return status; + if (! path->is_rectilinear) { + status = _emit_tolerance (surface, tolerance, matrix_updated); + if (unlikely (status)) + return status; + } - status = _emit_antialias (surface, antialias); - if (unlikely (status)) - return status; + if (! path->maybe_fill_region) { + status = _emit_antialias (surface, antialias); + if (unlikely (status)) + return status; + } status = _emit_path (surface, path); if (unlikely (status)) @@ -1721,18 +1894,18 @@ static cairo_int_status_t _cairo_script_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_script_surface_t *surface = abstract_surface; cairo_status_t status; ctx_active (surface->ctx); - status = _emit_context (surface); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); if (unlikely (status)) return status; - status = _emit_operator (surface, op); + status = _emit_context (surface); if (unlikely (status)) return status; @@ -1740,10 +1913,20 @@ _cairo_script_surface_paint (void *abstract_surface, if (unlikely (status)) return status; + status = _emit_operator (surface, op); + if (unlikely (status)) + return status; + _cairo_output_stream_puts (surface->ctx->stream, "paint\n"); ctx_inactive (surface->ctx); + + if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { + return _cairo_surface_wrapper_paint (&surface->wrapper, + op, source, clip); + } + return CAIRO_STATUS_SUCCESS; } @@ -1752,18 +1935,18 @@ _cairo_script_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_script_surface_t *surface = abstract_surface; cairo_status_t status; ctx_active (surface->ctx); - status = _emit_context (surface); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); if (unlikely (status)) return status; - status = _emit_operator (surface, op); + status = _emit_context (surface); if (unlikely (status)) return status; @@ -1771,14 +1954,30 @@ _cairo_script_surface_mask (void *abstract_surface, if (unlikely (status)) return status; - status = _emit_pattern (surface, mask); + status = _emit_operator (surface, op); if (unlikely (status)) return status; + if (_cairo_pattern_equal (source, mask)) { + _cairo_output_stream_puts (surface->ctx->stream, "/source get"); + } else { + status = _emit_pattern (surface, mask); + if (unlikely (status)) + return status; + } + + assert (surface->cr.current_operator == op); + _cairo_output_stream_puts (surface->ctx->stream, " mask\n"); ctx_inactive (surface->ctx); + + if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { + return _cairo_surface_wrapper_mask (&surface->wrapper, + op, source, mask, clip); + } + return CAIRO_STATUS_SUCCESS; } @@ -1792,7 +1991,7 @@ _cairo_script_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_script_surface_t *surface = abstract_surface; cairo_bool_t matrix_updated = FALSE; @@ -1800,6 +1999,10 @@ _cairo_script_surface_stroke (void *abstract_surface, ctx_active (surface->ctx); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + status = _emit_context (surface); if (unlikely (status)) return status; @@ -1816,7 +2019,7 @@ _cairo_script_surface_stroke (void *abstract_surface, if (unlikely (status)) return status; - status = _emit_matrix (surface, ctm, &matrix_updated); + status = _emit_scaling_matrix (surface, ctm, &matrix_updated); if (unlikely (status)) return status; @@ -1828,9 +2031,11 @@ _cairo_script_surface_stroke (void *abstract_surface, if (unlikely (status)) return status; - status = _emit_tolerance (surface, tolerance, matrix_updated); - if (unlikely (status)) - return status; + if (! path->is_rectilinear) { + status = _emit_tolerance (surface, tolerance, matrix_updated); + if (unlikely (status)) + return status; + } status = _emit_antialias (surface, antialias); if (unlikely (status)) @@ -1839,6 +2044,16 @@ _cairo_script_surface_stroke (void *abstract_surface, _cairo_output_stream_puts (surface->ctx->stream, "stroke+\n"); ctx_inactive (surface->ctx); + + if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { + return _cairo_surface_wrapper_stroke (&surface->wrapper, + op, source, path, + style, + ctm, ctm_inverse, + tolerance, antialias, + clip); + } + return CAIRO_STATUS_SUCCESS; } @@ -1850,7 +2065,7 @@ _cairo_script_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_script_surface_t *surface = abstract_surface; cairo_bool_t matrix_updated = FALSE; @@ -1858,11 +2073,11 @@ _cairo_script_surface_fill (void *abstract_surface, ctx_active (surface->ctx); - status = _emit_context (surface); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); if (unlikely (status)) return status; - status = _emit_operator (surface, op); + status = _emit_context (surface); if (unlikely (status)) return status; @@ -1878,21 +2093,39 @@ _cairo_script_surface_fill (void *abstract_surface, if (unlikely (status)) return status; - status = _emit_tolerance (surface, tolerance, matrix_updated); - if (unlikely (status)) - return status; + if (! path->is_rectilinear) { + status = _emit_tolerance (surface, tolerance, matrix_updated); + if (unlikely (status)) + return status; + } - status = _emit_antialias (surface, antialias); - if (unlikely (status)) - return status; + if (! path->maybe_fill_region) { + status = _emit_antialias (surface, antialias); + if (unlikely (status)) + return status; + } status = _emit_path (surface, path); if (unlikely (status)) return status; + status = _emit_operator (surface, op); + if (unlikely (status)) + return status; + _cairo_output_stream_puts (surface->ctx->stream, "fill+\n"); ctx_inactive (surface->ctx); + + if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { + return _cairo_surface_wrapper_fill (&surface->wrapper, + op, source, path, + fill_rule, + tolerance, + antialias, + clip); + } + return CAIRO_STATUS_SUCCESS; } @@ -2024,6 +2257,7 @@ _emit_type42_font (cairo_script_surface_t *surface, cairo_status_t status, status2; unsigned long size; unsigned int load_flags; + uint32_t len; uint8_t *buf; backend = scaled_font->backend; @@ -2049,13 +2283,15 @@ _emit_type42_font (cairo_script_surface_t *surface, _cairo_output_stream_printf (surface->ctx->stream, "<< " "/type 42 " - "/size %lu " "/index 0 " "/flags %d " - "/source <~", - size, load_flags); + "/source <|", + load_flags); base85_stream = _cairo_base85_stream_create (surface->ctx->stream); + len = size; + _cairo_output_stream_write (base85_stream, &len, sizeof (len)); + zlib_stream = _cairo_deflate_stream_create (base85_stream); _cairo_output_stream_write (zlib_stream, buf, size); @@ -2071,7 +2307,6 @@ _emit_type42_font (cairo_script_surface_t *surface, font_private = scaled_font->surface_private; _cairo_output_stream_printf (surface->ctx->stream, - " /deflate filter" " >> font dup /f%lu exch def set-font-face\n", font_private->id); @@ -2146,7 +2381,7 @@ _emit_scaled_font (cairo_script_surface_t *surface, cairo_script_surface_font_private_t *font_private; cairo_scaled_font_get_ctm (scaled_font, &matrix); - status = _emit_matrix (surface, &matrix, &matrix_updated); + status = _emit_scaling_matrix (surface, &matrix, &matrix_updated); if (unlikely (status)) return status; @@ -2268,7 +2503,7 @@ _emit_scaled_glyph_bitmap (cairo_script_surface_t *surface, if (! _cairo_matrix_is_identity (&scaled_font->font_matrix)) { _cairo_output_stream_printf (surface->ctx->stream, - " [%f %f %f %f %f %f] set-matrix\n", + "\n [%f %f %f %f %f %f] set-matrix\n", scaled_font->font_matrix.xx, scaled_font->font_matrix.yx, scaled_font->font_matrix.xy, @@ -2390,6 +2625,65 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface, return status; } +static void +_emit_string_literal (cairo_script_surface_t *surface, + const char *utf8, int len) +{ + char c; + const char *end; + + _cairo_output_stream_puts (surface->ctx->stream, "("); + + if (utf8 == NULL) { + end = utf8; + } else { + if (len < 0) + len = strlen (utf8); + end = utf8 + len; + } + + while (utf8 < end) { + switch ((c = *utf8++)) { + case '\n': + c = 'n'; + goto ESCAPED_CHAR; + case '\r': + c = 'r'; + goto ESCAPED_CHAR; + case '\t': + c = 't'; + goto ESCAPED_CHAR; + case '\b': + c = 'b'; + goto ESCAPED_CHAR; + case '\f': + c = 'f'; + goto ESCAPED_CHAR; + case '\\': + case '(': + case ')': +ESCAPED_CHAR: + _cairo_output_stream_printf (surface->ctx->stream, "\\%c", c); + break; + default: + if (isprint (c) || isspace (c)) { + _cairo_output_stream_printf (surface->ctx->stream, "%c", c); + } else { + int octal = 0; + while (c) { + octal *= 10; + octal += c&7; + c /= 8; + } + _cairo_output_stream_printf (surface->ctx->stream, + "\\%03d", octal); + } + break; + } + } + _cairo_output_stream_puts (surface->ctx->stream, ")"); +} + static cairo_int_status_t _cairo_script_surface_show_text_glyphs (void *abstract_surface, cairo_operator_t op, @@ -2402,7 +2696,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, int num_clusters, cairo_text_cluster_flags_t backward, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_script_surface_t *surface = abstract_surface; cairo_script_surface_font_private_t *font_private; @@ -2415,11 +2709,11 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, ctx_active (surface->ctx); - status = _emit_context (surface); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); if (unlikely (status)) return status; - status = _emit_operator (surface, op); + status = _emit_context (surface); if (unlikely (status)) return status; @@ -2431,6 +2725,10 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, if (unlikely (status)) return status; + status = _emit_operator (surface, op); + if (unlikely (status)) + return status; + status = _emit_scaled_glyphs (surface, scaled_font, glyphs, num_glyphs); if (unlikely (status)) return status; @@ -2439,9 +2737,8 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, /* [cx cy [glyphs]] show_glyphs */ if (utf8 != NULL && clusters != NULL) { - _cairo_output_stream_printf (surface->ctx->stream, - "(%s) ", - utf8); + _emit_string_literal (surface, utf8, utf8_len); + _cairo_output_stream_puts (surface->ctx->stream, " "); } matrix = surface->cr.current_ctm; @@ -2597,24 +2894,41 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, } ctx_inactive (surface->ctx); + + if (_cairo_surface_wrapper_is_active (&surface->wrapper)){ + return _cairo_surface_wrapper_show_text_glyphs (&surface->wrapper, + op, source, + utf8, utf8_len, + glyphs, num_glyphs, + clusters, num_clusters, + backward, + scaled_font, + clip); + } + return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t +static cairo_bool_t _cairo_script_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { cairo_script_surface_t *surface = abstract_surface; + if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { + return _cairo_surface_wrapper_get_extents (&surface->wrapper, + rectangle); + } + if (surface->width < 0 || surface->height < 0) - return CAIRO_INT_STATUS_UNSUPPORTED; + return FALSE; rectangle->x = 0; rectangle->y = 0; rectangle->width = surface->width; rectangle->height = surface->height; - return CAIRO_STATUS_SUCCESS; + return TRUE; } static const cairo_surface_backend_t @@ -2622,8 +2936,8 @@ _cairo_script_surface_backend = { CAIRO_SURFACE_TYPE_SCRIPT, _cairo_script_surface_create_similar, _cairo_script_surface_finish, - NULL, //_cairo_script_surface_acquire_source_image, - NULL, //_cairo_script_surface_release_source_image, + _cairo_script_surface_acquire_source_image, + _cairo_script_surface_release_source_image, NULL, /* acquire_dest_image */ NULL, /* release_dest_image */ NULL, /* clone_similar */ @@ -2634,8 +2948,6 @@ _cairo_script_surface_backend = { NULL, /* check_span_renderer */ _cairo_script_surface_copy_page, _cairo_script_surface_show_page, - NULL, /* set_clip_region */ - _cairo_script_surface_intersect_clip_path, _cairo_script_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -2651,10 +2963,10 @@ _cairo_script_surface_backend = { _cairo_script_surface_fill, NULL, - NULL, //_cairo_script_surface_snapshot, + NULL, /* _cairo_script_surface_snapshot, */ NULL, /* is_similar */ - NULL, /* reset */ + /* XXX need fill-stroke for passthrough */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ @@ -2686,6 +2998,8 @@ _cairo_script_vmcontext_create (cairo_output_stream_t *stream) ctx->stream = stream; ctx->mode = CAIRO_SCRIPT_MODE_ASCII; + cairo_list_init (&ctx->defines); + return ctx; } @@ -2711,7 +3025,8 @@ _cairo_script_implicit_context_init (cairo_script_implicit_context_t *cr) static cairo_script_surface_t * _cairo_script_surface_create_internal (cairo_script_vmcontext_t *ctx, double width, - double height) + double height, + cairo_surface_t *passthrough) { cairo_script_surface_t *surface; @@ -2726,6 +3041,11 @@ _cairo_script_surface_create_internal (cairo_script_vmcontext_t *ctx, &_cairo_script_surface_backend, CAIRO_CONTENT_COLOR_ALPHA); + _cairo_surface_wrapper_init (&surface->wrapper, passthrough); + + _cairo_surface_clipper_init (&surface->clipper, + _cairo_script_surface_clipper_intersect_clip_path); + surface->ctx = ctx; ctx->ref++; @@ -2755,7 +3075,7 @@ cairo_script_surface_create (const char *filename, surface = _cairo_script_surface_create_internal - (_cairo_script_vmcontext_create (stream), width, height); + (_cairo_script_vmcontext_create (stream), width, height, NULL); if (surface->base.status) return &surface->base; @@ -2776,7 +3096,64 @@ cairo_script_surface_create_for_stream (cairo_write_func_t write_func, return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); return &_cairo_script_surface_create_internal - (_cairo_script_vmcontext_create (stream), width, height)->base; + (_cairo_script_vmcontext_create (stream), width, height, NULL)->base; +} + +cairo_surface_t * +cairo_script_surface_create_for_target (cairo_surface_t *target, + cairo_write_func_t write_func, + void *closure) +{ + cairo_output_stream_t *stream; + cairo_script_surface_t *surface; + cairo_rectangle_int_t extents; + + if (unlikely (target->status)) + return _cairo_surface_create_in_error (target->status); + + stream = _cairo_output_stream_create (write_func, NULL, closure); + if (_cairo_output_stream_get_status (stream)) + return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); + + if (! _cairo_surface_get_extents (target, &extents)) + extents.width = extents.height = -1; + + surface = _cairo_script_surface_create_internal + (_cairo_script_vmcontext_create (stream), + extents.width, extents.height, + target); + if (unlikely (surface->base.status)) + return &surface->base; + + _cairo_output_stream_puts (surface->ctx->stream, "%!CairoScript\n"); + return &surface->base; +} + +void +cairo_script_surface_write_comment (cairo_surface_t *abstract_surface, + const char *comment, + int len) +{ + cairo_script_surface_t *surface; + cairo_status_t status_ignored; + + if (! _cairo_surface_is_script (abstract_surface)) { + status_ignored = _cairo_surface_set_error (abstract_surface, + CAIRO_STATUS_SURFACE_TYPE_MISMATCH); + return; + } + + if (abstract_surface->status) + return; + + surface = (cairo_script_surface_t *) abstract_surface; + + if (len < 0) + len = strlen (comment); + + _cairo_output_stream_puts (surface->ctx->stream, "% "); + _cairo_output_stream_write (surface->ctx->stream, comment, len); + _cairo_output_stream_puts (surface->ctx->stream, "\n"); } void diff --git a/src/cairo-script.h b/src/cairo-script.h index 9c428e3b8..397080bc2 100644 --- a/src/cairo-script.h +++ b/src/cairo-script.h @@ -53,6 +53,16 @@ cairo_script_surface_create_for_stream (cairo_write_func_t write_func, double width, double height); +cairo_public cairo_surface_t * +cairo_script_surface_create_for_target (cairo_surface_t *surface, + cairo_write_func_t write_func, + void *closure); + +cairo_public void +cairo_script_surface_write_comment (cairo_surface_t *abstract_surface, + const char *comment, + int len); + typedef enum { CAIRO_SCRIPT_MODE_BINARY, CAIRO_SCRIPT_MODE_ASCII diff --git a/src/cairo-spans-private.h b/src/cairo-spans-private.h index c285f9495..c706b22a7 100644 --- a/src/cairo-spans-private.h +++ b/src/cairo-spans-private.h @@ -132,13 +132,14 @@ _cairo_span_renderer_set_error (void *abstract_renderer, cairo_status_t error); cairo_private cairo_status_t -_cairo_path_fixed_fill_using_spans ( - cairo_operator_t op, - const cairo_pattern_t *pattern, - cairo_path_fixed_t *path, - cairo_surface_t *dst, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects); +_cairo_path_fixed_fill_using_spans (cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_path_fixed_t *path, + cairo_surface_t *dst, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region); + #endif /* CAIRO_SPANS_PRIVATE_H */ diff --git a/src/cairo-spans.c b/src/cairo-spans.c index cf8f76776..48396b54f 100644 --- a/src/cairo-spans.c +++ b/src/cairo-spans.c @@ -149,19 +149,19 @@ _create_scan_converter (cairo_fill_rule_t fill_rule, } cairo_status_t -_cairo_path_fixed_fill_using_spans ( - cairo_operator_t op, - const cairo_pattern_t *pattern, - cairo_path_fixed_t *path, - cairo_surface_t *dst, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects) +_cairo_path_fixed_fill_using_spans (cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_path_fixed_t *path, + cairo_surface_t *dst, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region) { cairo_status_t status; cairo_span_renderer_t *renderer = _cairo_surface_create_span_renderer ( - op, pattern, dst, antialias, rects); + op, pattern, dst, antialias, rects, clip_region); cairo_scan_converter_t *converter = _create_scan_converter ( fill_rule, antialias, rects); diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c index 9ab91e535..38518838c 100644 --- a/src/cairo-stroke-style.c +++ b/src/cairo-stroke-style.c @@ -110,13 +110,13 @@ _cairo_stroke_style_max_distance_from_path (const cairo_stroke_style_t *style, style_expansion = M_SQRT1_2; if (style->line_join == CAIRO_LINE_JOIN_MITER && - style_expansion < style->miter_limit) + style_expansion < M_SQRT2 * style->miter_limit) { - style_expansion = style->miter_limit; + style_expansion = M_SQRT2 * style->miter_limit; } style_expansion *= style->line_width; - *dx = style_expansion * (fabs (ctm->xx) + fabs (ctm->xy)); - *dy = style_expansion * (fabs (ctm->yy) + fabs (ctm->yx)); + *dx = style_expansion * hypot (ctm->xx, ctm->xy); + *dy = style_expansion * hypot (ctm->yy, ctm->yx); } diff --git a/src/cairo-surface-clipper-private.h b/src/cairo-surface-clipper-private.h new file mode 100644 index 000000000..f3d9de189 --- /dev/null +++ b/src/cairo-surface-clipper-private.h @@ -0,0 +1,72 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2009 Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Chris Wilson + */ + +#ifndef CAIRO_SURFACE_CLIPPER_PRIVATE_H +#define CAIRO_SURFACE_CLIPPER_PRIVATE_H + +#include "cairo-types-private.h" +#include "cairo-clip-private.h" + +CAIRO_BEGIN_DECLS + +typedef struct _cairo_surface_clipper cairo_surface_clipper_t; + +typedef cairo_status_t +(*cairo_surface_clipper_intersect_clip_path_func_t) (cairo_surface_clipper_t *, + cairo_path_fixed_t *, + cairo_fill_rule_t, + double, + cairo_antialias_t); +struct _cairo_surface_clipper { + cairo_clip_t clip; + cairo_bool_t is_clipped; + cairo_surface_clipper_intersect_clip_path_func_t intersect_clip_path; +}; + +cairo_private cairo_status_t +_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper, + cairo_clip_t *clip); + +cairo_private void +_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper, + cairo_surface_clipper_intersect_clip_path_func_t intersect); + +cairo_private void +_cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper); + +CAIRO_END_DECLS + +#endif /* CAIRO_SURFACE_CLIPPER_PRIVATE_H */ diff --git a/src/cairo-surface-clipper.c b/src/cairo-surface-clipper.c new file mode 100644 index 000000000..d536f0cbe --- /dev/null +++ b/src/cairo-surface-clipper.c @@ -0,0 +1,138 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2009 Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Chris Wilson + */ + +#include "cairoint.h" + +#include "cairo-surface-clipper-private.h" + +/* A collection of routines to facilitate vector surface clipping */ + +static cairo_status_t +_cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *clipper, + cairo_clip_path_t *clip_path) +{ + cairo_status_t status; + + if (clip_path->prev != NULL) { + status = + _cairo_surface_clipper_intersect_clip_path_recursive (clipper, + clip_path->prev); + if (unlikely (status)) + return status; + } + + return clipper->intersect_clip_path (clipper, + &clip_path->path, + clip_path->fill_rule, + clip_path->tolerance, + clip_path->antialias); +} + +cairo_status_t +_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_bool_t clear; + + /* XXX as we cache a reference to the path, and compare every time, + * we may in future need to install a notification if the clip->path + * is every modified (e.g. cairo_clip_translate). + */ + + if (clip == NULL && clipper->clip.path == NULL) + return CAIRO_STATUS_SUCCESS; + + if (clip != NULL && clip->path == clipper->clip.path) + return CAIRO_STATUS_SUCCESS; + + if (clip != NULL && clipper->clip.path != NULL && + _cairo_path_fixed_equal (&clip->path->path, &clipper->clip.path->path)) + { + return CAIRO_STATUS_SUCCESS; + } + + /* all clipped out state should never propagate this far */ + assert (clip == NULL || clip->path != NULL); + + /* Check whether this clip is a continuation of the previous. + * If not, we have to remove the current clip and rebuild. + */ + clear = clip == NULL || clip->path->prev != clipper->clip.path; + + _cairo_clip_reset (&clipper->clip); + _cairo_clip_init_copy (&clipper->clip, clip); + + if (clear) { + clipper->is_clipped = FALSE; + status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0); + if (unlikely (status)) + return status; + + if (clip != NULL && clip->path != NULL) { + status = + _cairo_surface_clipper_intersect_clip_path_recursive (clipper, + clip->path); + clipper->is_clipped = TRUE; + } + } else { + cairo_clip_path_t *path = clip->path; + + clipper->is_clipped = TRUE; + status = clipper->intersect_clip_path (clipper, + &path->path, + path->fill_rule, + path->tolerance, + path->antialias); + } + + return status; +} + +void +_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper, + cairo_surface_clipper_intersect_clip_path_func_t func) +{ + _cairo_clip_init (&clipper->clip); + clipper->is_clipped = FALSE; + clipper->intersect_clip_path = func; +} + +void +_cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper) +{ + _cairo_clip_reset (&clipper->clip); + clipper->is_clipped = FALSE; +} diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h index cd1817809..236b74590 100644 --- a/src/cairo-surface-fallback-private.h +++ b/src/cairo-surface-fallback-private.h @@ -44,13 +44,15 @@ cairo_private cairo_status_t _cairo_surface_fallback_paint (cairo_surface_t *surface, cairo_operator_t op, - const cairo_pattern_t *source); + const cairo_pattern_t *source, + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_fallback_mask (cairo_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *source, - const cairo_pattern_t *mask); + const cairo_pattern_t *mask, + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_fallback_stroke (cairo_surface_t *surface, @@ -61,7 +63,8 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, cairo_matrix_t *ctm, cairo_matrix_t *ctm_inverse, double tolerance, - cairo_antialias_t antialias); + cairo_antialias_t antialias, + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_fallback_fill (cairo_surface_t *surface, @@ -70,7 +73,8 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, - cairo_antialias_t antialias); + cairo_antialias_t antialias, + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface, @@ -78,7 +82,8 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface, const cairo_pattern_t *source, cairo_glyph_t *glyphs, int num_glyphs, - cairo_scaled_font_t *scaled_font); + cairo_scaled_font_t *scaled_font, + cairo_clip_t *clip); cairo_private cairo_surface_t * _cairo_surface_fallback_snapshot (cairo_surface_t *surface); @@ -95,7 +100,8 @@ _cairo_surface_fallback_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height); + unsigned int height, + cairo_region_t *clip_region); cairo_private cairo_status_t _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface, @@ -116,7 +122,8 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps); + int num_traps, + cairo_region_t *clip_region); cairo_private cairo_status_t _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 830c1b3de..9867eea85 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -40,6 +40,7 @@ #include "cairo-surface-fallback-private.h" #include "cairo-clip-private.h" +#include "cairo-region-private.h" typedef struct { cairo_surface_t *dst; @@ -82,13 +83,13 @@ _fallback_init (fallback_state_t *state, if (unlikely (status)) return status; + /* XXX: This NULL value tucked away in state->image is a rather * ugly interface. Cleaner would be to push the * CAIRO_INT_STATUS_NOTHING_TO_DO value down into * _cairo_surface_acquire_dest_image and its backend * counterparts. */ - if (state->image == NULL) - return CAIRO_INT_STATUS_NOTHING_TO_DO; + assert (state->image != NULL); return CAIRO_STATUS_SUCCESS; } @@ -101,46 +102,85 @@ _fallback_fini (fallback_state_t *state) state->image_extra); } -typedef cairo_status_t (*cairo_draw_func_t) (void *closure, - cairo_operator_t op, - const cairo_pattern_t *src, - cairo_surface_t *dst, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents); +typedef cairo_status_t +(*cairo_draw_func_t) (void *closure, + cairo_operator_t op, + const cairo_pattern_t *src, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_int_t *extents, + cairo_region_t *clip_region); static cairo_status_t _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern, cairo_clip_t *clip, - cairo_draw_func_t draw_func, + cairo_draw_func_t draw_func, void *draw_closure, cairo_surface_t *dst, const cairo_rectangle_int_t *extents) { cairo_surface_t *mask; + cairo_region_t *clip_region = NULL; + cairo_solid_pattern_t solid; cairo_status_t status; + cairo_bool_t clip_surface = FALSE; - mask = cairo_surface_create_similar (dst, - CAIRO_CONTENT_ALPHA, - extents->width, - extents->height); - if (mask->status) + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + assert (! _cairo_status_is_error (status)); + + clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED; + + if (clip_region && cairo_region_num_rectangles (clip_region) == 1) + clip_region = NULL; + } + + /* We need to use solid here, because to use CAIRO_OPERATOR_SOURCE with + * a mask (as called via _cairo_surface_mask) triggers assertion failures. + */ + mask = _cairo_surface_create_similar_solid (dst, + CAIRO_CONTENT_ALPHA, + extents->width, + extents->height, + CAIRO_COLOR_TRANSPARENT, + TRUE); + if (unlikely (mask->status)) return mask->status; - status = (*draw_func) (draw_closure, CAIRO_OPERATOR_ADD, - NULL, mask, - extents->x, extents->y, - extents); + _cairo_pattern_init_solid (&solid, CAIRO_COLOR_WHITE, CAIRO_CONTENT_ALPHA); + status = draw_func (draw_closure, CAIRO_OPERATOR_ADD, + &solid.base, mask, + extents->x, extents->y, + extents, + clip_region); if (unlikely (status)) goto CLEANUP_SURFACE; - if (clip && clip->surface) - status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_IN, - mask, - extents->x, extents->y, - extents); - if (unlikely (status)) - goto CLEANUP_SURFACE; + if (clip_surface) { + cairo_surface_pattern_t pattern; + cairo_surface_t *surface; + + surface = _cairo_clip_get_surface (clip, mask); + _cairo_pattern_init_for_surface (&pattern, surface); + cairo_surface_destroy (surface); + + status = _cairo_surface_composite (CAIRO_OPERATOR_IN, + &pattern.base, + NULL, + mask, + extents->x - clip->path->extents.x, + extents->y - clip->path->extents.y, + 0, 0, + 0, 0, + extents->width, extents->height, + NULL); + + _cairo_pattern_fini (&pattern.base); + + if (unlikely (status)) + goto CLEANUP_SURFACE; + } _cairo_pattern_init_for_surface (mask_pattern, mask); @@ -169,17 +209,17 @@ _clip_and_composite_with_mask (cairo_clip_t *clip, clip, draw_func, draw_closure, dst, extents); - if (unlikely (status)) - return status; + if (likely (status == CAIRO_STATUS_SUCCESS)) { + status = _cairo_surface_composite (op, + src, &mask_pattern.base, dst, + extents->x, extents->y, + 0, 0, + extents->x, extents->y, + extents->width, extents->height, + NULL); - status = _cairo_surface_composite (op, - src, &mask_pattern.base, dst, - extents->x, extents->y, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - - _cairo_pattern_fini (&mask_pattern.base); + _cairo_pattern_fini (&mask_pattern.base); + } return status; } @@ -197,77 +237,95 @@ _clip_and_composite_combine (cairo_clip_t *clip, const cairo_rectangle_int_t *extents) { cairo_surface_t *intermediate; - cairo_surface_pattern_t dst_pattern; - cairo_surface_pattern_t intermediate_pattern; + cairo_surface_pattern_t pattern; + cairo_surface_pattern_t clip_pattern; + cairo_surface_t *clip_surface; cairo_status_t status; /* We'd be better off here creating a surface identical in format * to dst, but we have no way of getting that information. * A CAIRO_CONTENT_CLONE or something might be useful. - * cairo_surface_create_similar() also unnecessarily clears the surface. */ - intermediate = cairo_surface_create_similar (dst, - CAIRO_CONTENT_COLOR_ALPHA, - extents->width, - extents->height); - if (intermediate->status) + intermediate = + _cairo_surface_create_similar_scratch (dst, + CAIRO_CONTENT_COLOR_ALPHA, + extents->width, + extents->height); + if (intermediate == NULL) { + intermediate = + _cairo_image_surface_create_with_content (CAIRO_CONTENT_COLOR_ALPHA, + extents->width, + extents->width); + } + if (unlikely (intermediate->status)) return intermediate->status; - /* Initialize the intermediate surface from the destination surface - */ - _cairo_pattern_init_for_surface (&dst_pattern, dst); - + /* Initialize the intermediate surface from the destination surface */ + _cairo_pattern_init_for_surface (&pattern, dst); status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, - &dst_pattern.base, NULL, intermediate, + &pattern.base, NULL, intermediate, extents->x, extents->y, 0, 0, 0, 0, - extents->width, extents->height); - - _cairo_pattern_fini (&dst_pattern.base); - + extents->width, extents->height, + NULL); + _cairo_pattern_fini (&pattern.base); if (unlikely (status)) goto CLEANUP_SURFACE; status = (*draw_func) (draw_closure, op, src, intermediate, extents->x, extents->y, - extents); + extents, + NULL); if (unlikely (status)) goto CLEANUP_SURFACE; - /* Combine that with the clip - */ - status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_DEST_IN, - intermediate, - extents->x, extents->y, - extents); + assert (clip->path != NULL); + clip_surface = _cairo_clip_get_surface (clip, dst); + if (unlikely (clip_surface->status)) + goto CLEANUP_SURFACE; + + _cairo_pattern_init_for_surface (&clip_pattern, clip_surface); + cairo_surface_destroy (clip_surface); + + /* Combine that with the clip */ + status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_IN, + &clip_pattern.base, NULL, intermediate, + extents->x - clip->path->extents.x, + extents->y - clip->path->extents.y, + 0, 0, + 0, 0, + extents->width, extents->height, + NULL); if (unlikely (status)) goto CLEANUP_SURFACE; - /* Punch the clip out of the destination - */ - status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_DEST_OUT, - dst, - 0, 0, - extents); + /* Punch the clip out of the destination */ + status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_OUT, + &clip_pattern.base, NULL, dst, + extents->x - clip->path->extents.x, + extents->y - clip->path->extents.y, + 0, 0, + extents->x, extents->y, + extents->width, extents->height, + NULL); if (unlikely (status)) goto CLEANUP_SURFACE; - /* Now add the two results together - */ - _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); - + /* Now add the two results together */ + _cairo_pattern_init_for_surface (&pattern, intermediate); status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, - &intermediate_pattern.base, NULL, dst, + &pattern.base, NULL, dst, 0, 0, 0, 0, extents->x, extents->y, - extents->width, extents->height); - - _cairo_pattern_fini (&intermediate_pattern.base); + extents->width, extents->height, + NULL); + _cairo_pattern_fini (&pattern.base); CLEANUP_SURFACE: + _cairo_pattern_fini (&clip_pattern.base); cairo_surface_destroy (intermediate); return status; @@ -285,10 +343,10 @@ _clip_and_composite_source (cairo_clip_t *clip, const cairo_rectangle_int_t *extents) { cairo_surface_pattern_t mask_pattern; + cairo_region_t *clip_region = NULL; cairo_status_t status; - /* Create a surface that is mask IN clip - */ + /* Create a surface that is mask IN clip */ status = _create_composite_mask_pattern (&mask_pattern, clip, draw_func, draw_closure, @@ -296,26 +354,35 @@ _clip_and_composite_source (cairo_clip_t *clip, if (unlikely (status)) return status; - /* Compute dest' = dest OUT (mask IN clip) - */ + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + assert (! _cairo_status_is_error (status)); + + /* a solitary clip rectangle is already accommodated by extents */ + if (clip_region && cairo_region_num_rectangles (clip_region) == 1) + clip_region = NULL; + } + + /* Compute dest' = dest OUT (mask IN clip) */ status = _cairo_surface_composite (CAIRO_OPERATOR_DEST_OUT, &mask_pattern.base, NULL, dst, 0, 0, 0, 0, extents->x, extents->y, - extents->width, extents->height); + extents->width, extents->height, + clip_region); if (unlikely (status)) goto CLEANUP_MASK_PATTERN; - /* Now compute (src IN (mask IN clip)) ADD dest' - */ + /* Now compute (src IN (mask IN clip)) ADD dest' */ status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, src, &mask_pattern.base, dst, extents->x, extents->y, 0, 0, extents->x, extents->y, - extents->width, extents->height); + extents->width, extents->height, + clip_region); CLEANUP_MASK_PATTERN: _cairo_pattern_fini (&mask_pattern.base); @@ -372,30 +439,45 @@ _clip_and_composite (cairo_clip_t *clip, op = CAIRO_OPERATOR_DEST_OUT; } - if ((clip && clip->surface) || op == CAIRO_OPERATOR_SOURCE) - { - if (op == CAIRO_OPERATOR_SOURCE) - status = _clip_and_composite_source (clip, - src, - draw_func, draw_closure, - dst, extents); - else if (_cairo_operator_bounded_by_mask (op)) - status = _clip_and_composite_with_mask (clip, op, - src, - draw_func, draw_closure, - dst, extents); - else - status = _clip_and_composite_combine (clip, op, - src, - draw_func, draw_closure, - dst, extents); - } - else - { - status = (*draw_func) (draw_closure, op, - src, dst, - 0, 0, - extents); + if (op == CAIRO_OPERATOR_SOURCE) { + status = _clip_and_composite_source (clip, + src, + draw_func, draw_closure, + dst, extents); + } else { + cairo_bool_t clip_surface = FALSE; + cairo_region_t *clip_region = NULL; + + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + assert (! _cairo_status_is_error (status)); + + clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED; + } + + if (clip_surface) { + if (_cairo_operator_bounded_by_mask (op)) { + status = _clip_and_composite_with_mask (clip, op, + src, + draw_func, draw_closure, + dst, extents); + } else { + status = _clip_and_composite_combine (clip, op, + src, + draw_func, draw_closure, + dst, extents); + } + } else { + /* a solitary clip rectangle is already accommodated by extents */ + if (clip_region && cairo_region_num_rectangles (clip_region) == 1) + clip_region = NULL; + + status = draw_func (draw_closure, op, + src, dst, + 0, 0, + extents, + clip_region); + } } return status; @@ -409,59 +491,51 @@ _composite_trap_region (cairo_clip_t *clip, cairo_operator_t op, cairo_surface_t *dst, cairo_region_t *trap_region, - cairo_rectangle_int_t *extents) + const cairo_rectangle_int_t *extents) { cairo_status_t status; cairo_solid_pattern_t solid_pattern; - cairo_surface_pattern_t mask; - int num_rects = cairo_region_num_rectangles (trap_region); - unsigned int clip_serial; - cairo_surface_t *clip_surface = clip ? clip->surface : NULL; + cairo_surface_pattern_t mask_pattern; + cairo_pattern_t *mask = NULL; + int mask_x = 0, mask_y =0; - if (num_rects == 0) - return CAIRO_STATUS_SUCCESS; + if (clip != NULL) { + cairo_surface_t *clip_surface = NULL; + const cairo_rectangle_int_t *clip_extents; - if (clip_surface && op == CAIRO_OPERATOR_CLEAR) { - _cairo_pattern_init_solid (&solid_pattern, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); - src = &solid_pattern.base; - op = CAIRO_OPERATOR_DEST_OUT; + clip_surface = _cairo_clip_get_surface (clip, dst); + if (unlikely (clip_surface->status)) + return clip_surface->status; + + if (op == CAIRO_OPERATOR_CLEAR) { + _cairo_pattern_init_solid (&solid_pattern, CAIRO_COLOR_WHITE, + CAIRO_CONTENT_COLOR); + src = &solid_pattern.base; + op = CAIRO_OPERATOR_DEST_OUT; + } + + _cairo_pattern_init_for_surface (&mask_pattern, clip_surface); + cairo_surface_destroy (clip_surface); + + clip_extents = _cairo_clip_get_extents (clip); + mask_x = extents->x - clip_extents->x; + mask_y = extents->y - clip_extents->y; + mask = &mask_pattern.base; } - if (num_rects > 1) { - if (_cairo_surface_get_clip_mode (dst) != CAIRO_CLIP_MODE_REGION) - return CAIRO_INT_STATUS_UNSUPPORTED; + /* reduce a solitary clipping region to the extents */ + if (cairo_region_num_rectangles (trap_region) == 1) + trap_region = NULL; - clip_serial = _cairo_surface_allocate_clip_serial (dst); - status = _cairo_surface_set_clip_region (dst, - trap_region, - clip_serial); - if (unlikely (status)) - return status; - } - - if (clip_surface) - _cairo_pattern_init_for_surface (&mask, clip_surface); - - status = _cairo_surface_composite (op, - src, - clip_surface ? &mask.base : NULL, - dst, + status = _cairo_surface_composite (op, src, mask, dst, extents->x, extents->y, - extents->x - (clip_surface ? clip->surface_rect.x : 0), - extents->y - (clip_surface ? clip->surface_rect.y : 0), + mask_x, mask_y, extents->x, extents->y, - extents->width, extents->height); + extents->width, extents->height, + trap_region); - /* Restore the original clip if we modified it temporarily. */ - if (num_rects > 1) { - cairo_status_t status2 = _cairo_surface_set_clip (dst, clip); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } - - if (clip_surface) - _cairo_pattern_fini (&mask.base); + if (mask != NULL) + _cairo_pattern_fini (mask); return status; } @@ -478,27 +552,117 @@ _composite_traps_draw_func (void *closure, cairo_surface_t *dst, int dst_x, int dst_y, - const cairo_rectangle_int_t *extents) + const cairo_rectangle_int_t *extents, + cairo_region_t *clip_region) { cairo_composite_traps_info_t *info = closure; - cairo_solid_pattern_t pattern; if (dst_x != 0 || dst_y != 0) _cairo_traps_translate (info->traps, - dst_x, - dst_y); - if (src == NULL) { - _cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); - src = &pattern.base; - } - return _cairo_surface_composite_trapezoids (op, src, dst, info->antialias, extents->x, extents->y, extents->x - dst_x, extents->y - dst_y, extents->width, extents->height, info->traps->traps, - info->traps->num_traps); + info->traps->num_traps, + clip_region); +} + +enum { + HAS_CLEAR_REGION = 0x1, +}; + +static cairo_status_t +_clip_and_composite_region (const cairo_pattern_t *src, + cairo_operator_t op, + cairo_surface_t *dst, + cairo_region_t *trap_region, + cairo_antialias_t antialias, + cairo_clip_t *clip, + cairo_rectangle_int_t *extents) +{ + cairo_region_t clear_region; + cairo_bool_t clip_surface = FALSE; + unsigned int has_region = 0; + cairo_status_t status; + + if (clip != NULL) { + cairo_region_t *clip_region; + + status = _cairo_clip_get_region (clip, &clip_region); + assert (! _cairo_status_is_error (status)); + + clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED; + } + + if (_cairo_operator_bounded_by_mask (op)) { + cairo_rectangle_int_t trap_extents; + + cairo_region_get_extents (trap_region, &trap_extents); + if (! _cairo_rectangle_intersect (extents, &trap_extents)) + return CAIRO_STATUS_SUCCESS; + } else { + if (! clip_surface) { + /* If we optimize drawing with an unbounded operator to + * _cairo_surface_fill_rectangles() or to drawing with a + * clip region, then we have an additional region to clear. + */ + _cairo_region_init_rectangle (&clear_region, extents); + status = cairo_region_subtract (&clear_region, trap_region); + if (unlikely (status)) + return status; + + if (! cairo_region_is_empty (&clear_region)) + has_region |= HAS_CLEAR_REGION; + } + } + + if ((src->type == CAIRO_PATTERN_TYPE_SOLID || op == CAIRO_OPERATOR_CLEAR) && + ! clip_surface) + { + const cairo_color_t *color; + + if (op == CAIRO_OPERATOR_CLEAR) + color = CAIRO_COLOR_TRANSPARENT; + else + color = &((cairo_solid_pattern_t *)src)->color; + + /* Solid rectangles special case */ + status = _cairo_surface_fill_region (dst, op, color, trap_region); + } else { + /* For a simple rectangle, we can just use composite(), for more + * rectangles, we have to set a clip region. The cost of rasterizing + * trapezoids is pretty high for most backends currently, so it's + * worthwhile even if a region is needed. + * + * If we have a clip surface, we set it as the mask; this only works + * for bounded operators other than SOURCE; for unbounded operators, + * clip and mask cannot be interchanged. For SOURCE, the operator + * as implemented by the backends is different in its handling + * of the mask then what we want. + * + * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has + * more than rectangle and the destination doesn't support clip + * regions. In that case, we fall through. + */ + status = _composite_trap_region (clip_surface ? clip : NULL, + src, op, dst, + trap_region, extents); + } + + if (has_region & HAS_CLEAR_REGION) { + if (status == CAIRO_STATUS_SUCCESS) { + status = _cairo_surface_fill_region (dst, + CAIRO_OPERATOR_CLEAR, + CAIRO_COLOR_TRANSPARENT, + &clear_region); + } + _cairo_region_fini (&clear_region); + } + + return status; } /* Warning: This call modifies the coordinates of traps */ @@ -507,154 +671,92 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, cairo_operator_t op, cairo_surface_t *dst, cairo_traps_t *traps, + cairo_antialias_t antialias, cairo_clip_t *clip, - cairo_antialias_t antialias) + cairo_rectangle_int_t *extents) { - cairo_status_t status; - cairo_region_t *trap_region = NULL; - cairo_region_t *clear_region = NULL; - cairo_rectangle_int_t extents; cairo_composite_traps_info_t traps_info; + cairo_region_t *clip_region = NULL; + cairo_bool_t clip_surface = FALSE; + cairo_status_t status; if (_cairo_operator_bounded_by_mask (op) && traps->num_traps == 0) return CAIRO_STATUS_SUCCESS; - status = _cairo_surface_get_extents (dst, &extents); - if (unlikely (status)) - return status; + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + if (unlikely (_cairo_status_is_error (status))) + return status; - status = _cairo_traps_extract_region (traps, &trap_region); - if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - if (_cairo_operator_bounded_by_mask (op)) { - cairo_rectangle_int_t trap_extents; - - if (trap_region) { - status = _cairo_clip_intersect_to_region (clip, trap_region); - if (unlikely (status)) - goto out; - - cairo_region_get_extents (trap_region, &trap_extents); - } else { - cairo_box_t trap_box; - _cairo_traps_extents (traps, &trap_box); - _cairo_box_round_to_rectangle (&trap_box, &trap_extents); - } - - if (! _cairo_rectangle_intersect (&extents, &trap_extents)) { - status = CAIRO_STATUS_SUCCESS; - goto out; - } - - status = _cairo_clip_intersect_to_rectangle (clip, &extents); - if (unlikely (status)) - goto out; - } else { - cairo_surface_t *clip_surface = clip ? clip->surface : NULL; - - if (trap_region && !clip_surface) { - /* If we optimize drawing with an unbounded operator to - * _cairo_surface_fill_rectangles() or to drawing with a - * clip region, then we have an additional region to clear. - */ - clear_region = cairo_region_create_rectangle (&extents); - - status = cairo_region_status (clear_region); - if (unlikely (status)) - goto out; - - status = _cairo_clip_intersect_to_region (clip, clear_region); - if (unlikely (status)) - goto out; - - cairo_region_get_extents (clear_region, &extents); - - status = cairo_region_subtract (clear_region, trap_region); - if (unlikely (status)) - goto out; - - if (cairo_region_is_empty (clear_region)) { - cairo_region_destroy (clear_region); - clear_region = NULL; - } - } else { - status = _cairo_clip_intersect_to_rectangle (clip, &extents); - } + /* The all-clipped state should not have been propagated this far. */ + assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO); + clip_surface = status == CAIRO_INT_STATUS_UNSUPPORTED; } - if (unlikely (status)) - goto out; + /* Use a fast path if the trapezoids consist of a simple region, + * but we can only do this if we do not have a clip surface, or can + * substitute the mask with the clip. + */ + if (! clip_surface || + (_cairo_operator_bounded_by_mask (op) && op != CAIRO_OPERATOR_SOURCE)) + { + cairo_region_t *trap_region = NULL; - if (trap_region) { - cairo_surface_t *clip_surface = clip ? clip->surface : NULL; + status = _cairo_traps_extract_region (traps, &trap_region); + if (unlikely (_cairo_status_is_error (status))) + return status; - if ((src->type == CAIRO_PATTERN_TYPE_SOLID || - op == CAIRO_OPERATOR_CLEAR) && !clip_surface) { - const cairo_color_t *color; - - if (op == CAIRO_OPERATOR_CLEAR) { - color = CAIRO_COLOR_TRANSPARENT; - } else { - color = &((cairo_solid_pattern_t *)src)->color; - } - - /* Solid rectangles special case */ - status = _cairo_surface_fill_region (dst, op, color, trap_region); - - if (!status && clear_region) { - status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - clear_region); + if (trap_region != NULL) { + status = cairo_region_intersect_rectangle (trap_region, extents); + if (unlikely (status)) { + cairo_region_destroy (trap_region); + return status; } - goto out; - } + if (clip_region != NULL) { + status = cairo_region_intersect (trap_region, clip_region); + if (unlikely (status)) { + cairo_region_destroy (trap_region); + return status; + } + } - if ((_cairo_operator_bounded_by_mask (op) && - op != CAIRO_OPERATOR_SOURCE) || !clip_surface) { - /* For a simple rectangle, we can just use composite(), for more - * rectangles, we have to set a clip region. The cost of rasterizing - * trapezoids is pretty high for most backends currently, so it's - * worthwhile even if a region is needed. - * - * If we have a clip surface, we set it as the mask; this only works - * for bounded operators other than SOURCE; for unbounded operators, - * clip and mask cannot be interchanged. For SOURCE, the operator - * as implemented by the backends is different in its handling - * of the mask then what we want. - * - * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has - * more than rectangle and the destination doesn't support clip - * regions. In that case, we fall through. - */ - status = _composite_trap_region (clip, src, op, dst, - trap_region, &extents); + if (cairo_region_is_empty (trap_region) && + _cairo_operator_bounded_by_mask (op)) + { + cairo_region_destroy (trap_region); + return CAIRO_STATUS_SUCCESS; + } - if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - if (!status && clear_region) - status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - clear_region); - goto out; - } - } + status = _clip_and_composite_region (src, op, dst, + trap_region, + antialias, + clip, extents); + cairo_region_destroy (trap_region); + + if (likely (status != CAIRO_INT_STATUS_UNSUPPORTED)) + return status; + } + } + + /* Otherwise we need to render the trapezoids to a mask and composite + * in the usual fashion. + */ + if (_cairo_operator_bounded_by_mask (op)) { + cairo_rectangle_int_t trap_extents; + cairo_box_t trap_box; + + _cairo_traps_extents (traps, &trap_box); + _cairo_box_round_to_rectangle (&trap_box, &trap_extents); + if (! _cairo_rectangle_intersect (extents, &trap_extents)) + return CAIRO_STATUS_SUCCESS; } traps_info.traps = traps; traps_info.antialias = antialias; - - status = _clip_and_composite (clip, op, src, - _composite_traps_draw_func, - &traps_info, dst, &extents); - -out: - if (trap_region) - cairo_region_destroy (trap_region); - if (clear_region) - cairo_region_destroy (clear_region); - - return status; + return _clip_and_composite (clip, op, src, + _composite_traps_draw_func, + &traps_info, dst, extents); } typedef struct { @@ -671,11 +773,11 @@ _composite_spans_fill_func (void *closure, cairo_surface_t *dst, int dst_x, int dst_y, - const cairo_rectangle_int_t *extents) + const cairo_rectangle_int_t *extents, + cairo_region_t *clip_region) { cairo_composite_rectangles_t rects; cairo_composite_spans_fill_info_t *info = closure; - cairo_solid_pattern_t pattern; _cairo_composite_rectangles_init ( &rects, extents->x, extents->y, @@ -687,60 +789,60 @@ _composite_spans_fill_func (void *closure, rects.dst.x -= dst_x; rects.dst.y -= dst_y; - /* We're called without a source pattern from - * _create_composite_mask_pattern(). */ - if (src == NULL) { - _cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); - src = &pattern.base; + return _cairo_path_fixed_fill_using_spans (op, src, info->path, dst, + info->fill_rule, + info->tolerance, + info->antialias, + &rects, + clip_region); +} + +static cairo_bool_t +_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip) +{ + if (clip != NULL) { + const cairo_rectangle_int_t *clip_extents; + + clip_extents = _cairo_clip_get_extents (clip); + if (clip_extents != NULL) + return _cairo_rectangle_intersect (extents, clip_extents); } - return _cairo_path_fixed_fill_using_spans ( - op, src, info->path, dst, - info->fill_rule, info->tolerance, info->antialias, - &rects); + return ! _cairo_rectangle_empty (extents); } cairo_status_t _cairo_surface_fallback_paint (cairo_surface_t *surface, cairo_operator_t op, - const cairo_pattern_t *source) + const cairo_pattern_t *source, + cairo_clip_t *clip) { cairo_status_t status; cairo_rectangle_int_t extents; cairo_box_t box; cairo_traps_t traps; + cairo_bool_t is_bounded; - status = _cairo_surface_get_extents (surface, &extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (surface, &extents); + assert (is_bounded || clip); if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - + _cairo_pattern_get_extents (source, &source_extents); if (! _cairo_rectangle_intersect (&extents, &source_extents)) return CAIRO_STATUS_SUCCESS; } - status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (unlikely (status)) - return status; + if (! _rectangle_intersect_clip (&extents, clip)) + return CAIRO_STATUS_SUCCESS; _cairo_box_from_rectangle (&box, &extents); _cairo_traps_init_box (&traps, &box); - - status = _clip_and_composite_trapezoids (source, - op, - surface, - &traps, - surface->clip, - CAIRO_ANTIALIAS_NONE); - + status = _clip_and_composite_trapezoids (source, op, surface, + &traps, CAIRO_ANTIALIAS_NONE, + clip, &extents); _cairo_traps_fini (&traps); return status; @@ -753,69 +855,67 @@ _cairo_surface_mask_draw_func (void *closure, cairo_surface_t *dst, int dst_x, int dst_y, - const cairo_rectangle_int_t *extents) + const cairo_rectangle_int_t *extents, + cairo_region_t *clip_region) { cairo_pattern_t *mask = closure; - if (src) + if (src) { return _cairo_surface_composite (op, src, mask, dst, extents->x, extents->y, extents->x, extents->y, extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - else + extents->width, extents->height, + clip_region); + } else { return _cairo_surface_composite (op, mask, NULL, dst, extents->x, extents->y, 0, 0, /* unused */ extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); + extents->width, extents->height, + clip_region); + } } + cairo_status_t _cairo_surface_fallback_mask (cairo_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *source, - const cairo_pattern_t *mask) + const cairo_pattern_t *mask, + cairo_clip_t *clip) { - cairo_status_t status; - cairo_rectangle_int_t extents, source_extents, mask_extents; + cairo_rectangle_int_t extents; + cairo_bool_t is_bounded; - status = _cairo_surface_get_extents (surface, &extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (surface, &extents); + assert (is_bounded || clip); if (_cairo_operator_bounded_by_source (op)) { - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; + cairo_rectangle_int_t source_extents; + _cairo_pattern_get_extents (source, &source_extents); if (! _cairo_rectangle_intersect (&extents, &source_extents)) return CAIRO_STATUS_SUCCESS; } if (_cairo_operator_bounded_by_mask (op)) { - status = _cairo_pattern_get_extents (mask, &mask_extents); - if (unlikely (status)) - return status; + cairo_rectangle_int_t mask_extents; + _cairo_pattern_get_extents (mask, &mask_extents); if (! _cairo_rectangle_intersect (&extents, &mask_extents)) return CAIRO_STATUS_SUCCESS; } - status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (unlikely (status)) - return status; + if (! _rectangle_intersect_clip (&extents, clip)) + return CAIRO_STATUS_SUCCESS; - status = _clip_and_composite (surface->clip, op, - source, - _cairo_surface_mask_draw_func, - (void *) mask, - surface, - &extents); - - return status; + return _clip_and_composite (clip, op, source, + _cairo_surface_mask_draw_func, + (void *) mask, + surface, &extents); } cairo_status_t @@ -827,32 +927,27 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, cairo_matrix_t *ctm, cairo_matrix_t *ctm_inverse, double tolerance, - cairo_antialias_t antialias) + cairo_antialias_t antialias, + cairo_clip_t *clip) { cairo_status_t status; cairo_traps_t traps; cairo_box_t box; cairo_rectangle_int_t extents; + cairo_bool_t is_bounded; - status = _cairo_surface_get_extents (surface, &extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (surface, &extents); + assert (is_bounded || clip); if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; + _cairo_pattern_get_extents (source, &source_extents); if (! _cairo_rectangle_intersect (&extents, &source_extents)) return CAIRO_STATUS_SUCCESS; } - status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (unlikely (status)) - return status; - - if (extents.width == 0 || extents.height == 0) + if (! _rectangle_intersect_clip (&extents, clip)) return CAIRO_STATUS_SUCCESS; _cairo_box_from_rectangle (&box, &extents); @@ -868,14 +963,10 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, if (unlikely (status)) goto FAIL; - status = _clip_and_composite_trapezoids (source, - op, - surface, - &traps, - surface->clip, - antialias); - -FAIL: + status = _clip_and_composite_trapezoids (source, op, + surface, &traps, antialias, + clip, &extents); + FAIL: _cairo_traps_fini (&traps); return status; @@ -888,35 +979,41 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, - cairo_antialias_t antialias) + cairo_antialias_t antialias, + cairo_clip_t *clip) { cairo_status_t status; cairo_traps_t traps; cairo_box_t box; cairo_rectangle_int_t extents; + cairo_bool_t is_bounded; - status = _cairo_surface_get_extents (surface, &extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (surface, &extents); + assert (is_bounded || clip); if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; - status = _cairo_pattern_get_extents (source, &source_extents); - if (unlikely (status)) - return status; - + _cairo_pattern_get_extents (source, &source_extents); if (! _cairo_rectangle_intersect (&extents, &source_extents)) return CAIRO_STATUS_SUCCESS; } - status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (unlikely (status)) - return status; - - if (extents.width == 0 || extents.height == 0) + if (! _rectangle_intersect_clip (&extents, clip)) return CAIRO_STATUS_SUCCESS; + /* XXX future direction: + status = _cairo_path_fixed_fill_to_region (path, fill_rule, ®ion); + if (status != CAIRO_STATUS_INT_UNSUPPORTED) { + if (unlikely (status)) + return status; + + status = _clip_and_composite_region (); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; + } + */ + /* Ask if the surface would like to render this combination of * op/source/dst/antialias with spans or not, but don't actually * make a renderer yet. We'll try to hit the region optimisations @@ -927,9 +1024,7 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, /* TODO: The region filling code should be lifted from * _clip_and_composite_trapezoids() and given first priority * explicitly before deciding between spans and trapezoids. */ - if (antialias != CAIRO_ANTIALIAS_NONE && - !_cairo_path_fixed_is_box (path, &box) && - !_cairo_path_fixed_is_region (path) && + if (antialias != CAIRO_ANTIALIAS_NONE && ! path->is_rectilinear && _cairo_surface_check_span_renderer ( op, source, surface, antialias, NULL)) { @@ -948,12 +1043,11 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, return CAIRO_STATUS_SUCCESS; } - return _clip_and_composite ( - surface->clip, op, source, - _composite_spans_fill_func, - &info, - surface, - &extents); + return _clip_and_composite (clip, op, source, + _composite_spans_fill_func, + &info, + surface, + &extents); } /* Fall back to trapezoid fills. */ @@ -965,18 +1059,13 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, fill_rule, tolerance, &traps); - if (unlikely (status)) { - _cairo_traps_fini (&traps); - return status; - } - - status = _clip_and_composite_trapezoids (source, - op, - surface, - &traps, - surface->clip, - antialias); + if (unlikely (status)) + goto FAIL; + status = _clip_and_composite_trapezoids (source, op, surface, + &traps, antialias, + clip, &extents); + FAIL: _cairo_traps_fini (&traps); return status; @@ -995,10 +1084,10 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure cairo_surface_t *dst, int dst_x, int dst_y, - const cairo_rectangle_int_t *extents) + const cairo_rectangle_int_t *extents, + cairo_region_t *clip_region) { cairo_show_glyphs_info_t *glyph_info = closure; - cairo_solid_pattern_t pattern; cairo_status_t status; /* Modifying the glyph array is fine because we know that this function @@ -1008,19 +1097,12 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure if (dst_x != 0 || dst_y != 0) { int i; - for (i = 0; i < glyph_info->num_glyphs; ++i) - { + for (i = 0; i < glyph_info->num_glyphs; ++i) { ((cairo_glyph_t *) glyph_info->glyphs)[i].x -= dst_x; ((cairo_glyph_t *) glyph_info->glyphs)[i].y -= dst_y; } } - if (src == NULL) { - _cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE, - CAIRO_CONTENT_COLOR); - src = &pattern.base; - } - status = _cairo_surface_old_show_glyphs (glyph_info->font, op, src, dst, extents->x, extents->y, @@ -1029,7 +1111,8 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure extents->width, extents->height, glyph_info->glyphs, - glyph_info->num_glyphs); + glyph_info->num_glyphs, + clip_region); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; @@ -1041,7 +1124,8 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure extents->y - dst_y, extents->width, extents->height, glyph_info->glyphs, - glyph_info->num_glyphs); + glyph_info->num_glyphs, + clip_region); } cairo_status_t @@ -1050,15 +1134,16 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface, const cairo_pattern_t *source, cairo_glyph_t *glyphs, int num_glyphs, - cairo_scaled_font_t *scaled_font) + cairo_scaled_font_t *scaled_font, + cairo_clip_t *clip) { cairo_status_t status; cairo_rectangle_int_t extents; cairo_show_glyphs_info_t glyph_info; + cairo_bool_t is_bounded; - status = _cairo_surface_get_extents (surface, &extents); - if (unlikely (status)) - return status; + is_bounded = _cairo_surface_get_extents (surface, &extents); + assert (is_bounded || clip); if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t glyph_extents; @@ -1074,23 +1159,18 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface, return CAIRO_STATUS_SUCCESS; } - status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (unlikely (status)) - return status; + if (! _rectangle_intersect_clip (&extents, clip)) + return CAIRO_STATUS_SUCCESS; glyph_info.font = scaled_font; glyph_info.glyphs = glyphs; glyph_info.num_glyphs = num_glyphs; - status = _clip_and_composite (surface->clip, - op, - source, - _cairo_surface_old_show_glyphs_draw_func, - &glyph_info, - surface, - &extents); - - return status; + return _clip_and_composite (clip, op, source, + _cairo_surface_old_show_glyphs_draw_func, + &glyph_info, + surface, + &extents); } cairo_surface_t * @@ -1124,15 +1204,10 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) } _cairo_pattern_init_for_surface (&pattern, &image->base); - status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, - &pattern.base, - NULL, - snapshot, - 0, 0, - 0, 0, - 0, 0, - image->width, - image->height); + status = _cairo_surface_paint (snapshot, + CAIRO_OPERATOR_SOURCE, + &pattern.base, + NULL); _cairo_pattern_fini (&pattern.base); _cairo_surface_release_source_image (surface, image, image_extra); if (unlikely (status)) { @@ -1155,15 +1230,17 @@ _cairo_surface_fallback_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { fallback_state_t state; + cairo_region_t *fallback_region = NULL; cairo_status_t status; status = _fallback_init (&state, dst, dst_x, dst_y, width, height); if (unlikely (status)) { if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) - return CAIRO_STATUS_SUCCESS; + status = CAIRO_STATUS_SUCCESS; return status; } @@ -1172,12 +1249,29 @@ _cairo_surface_fallback_composite (cairo_operator_t op, * _cairo_surface_composite so that we get the correct device * offset handling. */ + + if (clip_region != NULL && (state.image_rect.x || state.image_rect.y)) { + fallback_region = cairo_region_copy (clip_region); + status = fallback_region->status; + if (unlikely (status)) + goto FAIL; + + cairo_region_translate (fallback_region, + -state.image_rect.x, + -state.image_rect.y); + clip_region = fallback_region; + } + status = _cairo_surface_composite (op, src, mask, &state.image->base, src_x, src_y, mask_x, mask_y, dst_x - state.image_rect.x, dst_y - state.image_rect.y, - width, height); + width, height, + clip_region); + FAIL: + if (fallback_region != NULL) + cairo_region_destroy (fallback_region); _fallback_fini (&state); return status; @@ -1224,7 +1318,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface, status = _fallback_init (&state, surface, x1, y1, x2 - x1, y2 - y1); if (unlikely (status)) { if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) - return CAIRO_STATUS_SUCCESS; + status = CAIRO_STATUS_SUCCESS; return status; } @@ -1271,16 +1365,18 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps) + int num_traps, + cairo_region_t *clip_region) { fallback_state_t state; + cairo_region_t *fallback_region = NULL; cairo_trapezoid_t *offset_traps = NULL; cairo_status_t status; status = _fallback_init (&state, dst, dst_x, dst_y, width, height); if (unlikely (status)) { if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) - return CAIRO_STATUS_SUCCESS; + status = CAIRO_STATUS_SUCCESS; return status; } @@ -1288,15 +1384,28 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, if (state.image_rect.x != 0 || state.image_rect.y != 0) { offset_traps = _cairo_malloc_ab (num_traps, sizeof (cairo_trapezoid_t)); - if (!offset_traps) { + if (offset_traps == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto DONE; + goto FAIL; } _cairo_trapezoid_array_translate_and_scale (offset_traps, traps, num_traps, - state.image_rect.x, - state.image_rect.y, 1.0, 1.0); traps = offset_traps; + + /* similarly we need to adjust the region */ + if (clip_region != NULL) { + fallback_region = cairo_region_copy (clip_region); + status = fallback_region->status; + if (unlikely (status)) + goto FAIL; + + cairo_region_translate (fallback_region, + -state.image_rect.x, + -state.image_rect.y); + clip_region = fallback_region; + } } status = _cairo_surface_composite_trapezoids (op, pattern, @@ -1306,11 +1415,14 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, dst_x - state.image_rect.x, dst_y - state.image_rect.y, width, height, - traps, num_traps); - if (offset_traps) + traps, num_traps, + clip_region); + if (offset_traps != NULL) free (offset_traps); - DONE: + FAIL: + if (fallback_region != NULL) + cairo_region_destroy (fallback_region); _fallback_fini (&state); return status; @@ -1335,7 +1447,9 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, new_surface = _cairo_surface_create_similar_scratch (surface, src->content & content, width, height); - if (new_surface->status) + if (new_surface == NULL) + return CAIRO_INT_STATUS_UNSUPPORTED; + if (unlikely (new_surface->status)) return new_surface->status; /* We have to copy these here, so that the coordinate spaces are correct */ @@ -1348,7 +1462,8 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, status = _cairo_surface_paint (new_surface, CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); + &pattern.base, + NULL); _cairo_pattern_fini (&pattern.base); if (unlikely (status)) { diff --git a/src/cairo-surface-private.h b/src/cairo-surface-private.h index c25b6dc8a..5c80d43f5 100644 --- a/src/cairo-surface-private.h +++ b/src/cairo-surface-private.h @@ -42,6 +42,7 @@ #include "cairo-types-private.h" #include "cairo-reference-count-private.h" +#include "cairo-clip-private.h" typedef void (*cairo_surface_func_t) (cairo_surface_t *); @@ -77,24 +78,6 @@ struct _cairo_surface { double x_fallback_resolution; double y_fallback_resolution; - cairo_clip_t *clip; - - /* - * Each time a clip region is modified, it gets the next value in this - * sequence. This means that clip regions for this surface are uniquely - * identified and updates to the clip can be readily identified - */ - unsigned int next_clip_serial; - /* - * The serial number of the current clip. This is set when - * the surface clipping is set. The gstate can then cheaply - * check whether the surface clipping is already correct before - * performing a rendering operation. - * - * The special value '0' is reserved for the unclipped case. - */ - unsigned int current_clip_serial; - /* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */ cairo_surface_t *snapshot_of; cairo_surface_func_t snapshot_detach; diff --git a/src/cairo-surface-wrapper-private.h b/src/cairo-surface-wrapper-private.h new file mode 100644 index 000000000..5ebcb8606 --- /dev/null +++ b/src/cairo-surface-wrapper-private.h @@ -0,0 +1,156 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2002 University of Southern California + * Copyright © 2005 Red Hat, Inc. + * Copyright © 2009 Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Chris Wilson + */ + +#ifndef CAIRO_SURFACE_WRAPPER_PRIVATE_H +#define CAIRO_SURFACE_WRAPPER_PRIVATE_H + +#include "cairo-types-private.h" + +CAIRO_BEGIN_DECLS + +struct _cairo_surface_wrapper { + cairo_surface_t *target; + + /* any other information? */ +}; + +cairo_private void +_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper, + cairo_surface_t *target); + +cairo_private void +_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper); + +cairo_private cairo_status_t +_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper, + cairo_image_surface_t **image_out, + void **image_extra); + +cairo_private void +_cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper, + cairo_image_surface_t *image, + void *image_extra); + + +cairo_private cairo_status_t +_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_clip_t *clip); + +cairo_private cairo_status_t +_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_pattern_t *mask, + cairo_clip_t *clip); + +cairo_private cairo_status_t +_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_stroke_style_t *stroke_style, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip); + +cairo_private cairo_status_t +_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper, + cairo_operator_t fill_op, + const cairo_pattern_t *fill_source, + cairo_fill_rule_t fill_rule, + double fill_tolerance, + cairo_antialias_t fill_antialias, + cairo_path_fixed_t *path, + cairo_operator_t stroke_op, + const cairo_pattern_t *stroke_source, + cairo_stroke_style_t *stroke_style, + cairo_matrix_t *stroke_ctm, + cairo_matrix_t *stroke_ctm_inverse, + double stroke_tolerance, + cairo_antialias_t stroke_antialias, + cairo_clip_t *clip); + +cairo_private cairo_status_t +_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip); + +cairo_private cairo_status_t +_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + const char *utf8, + int utf8_len, + cairo_glyph_t *glyphs, + int num_glyphs, + const cairo_text_cluster_t *clusters, + int num_clusters, + cairo_text_cluster_flags_t cluster_flags, + cairo_scaled_font_t *scaled_font, + cairo_clip_t *clip); + +cairo_private cairo_surface_t * +_cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper, + cairo_content_t content, + int width, + int height); +cairo_private cairo_bool_t +_cairo_surface_wrapper_get_extents (cairo_surface_wrapper_t *wrapper, + cairo_rectangle_int_t *extents); + +cairo_private cairo_bool_t +_cairo_surface_wrapper_has_show_text_glyphs (cairo_surface_wrapper_t *wrapper); + +static inline cairo_bool_t +_cairo_surface_wrapper_is_active (cairo_surface_wrapper_t *wrapper) +{ + return wrapper->target != (cairo_surface_t *) 0; +} + +CAIRO_END_DECLS + +#endif /* CAIRO_SURFACE_WRAPPER_PRIVATE_H */ diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c new file mode 100644 index 000000000..b21a32dab --- /dev/null +++ b/src/cairo-surface-wrapper.c @@ -0,0 +1,449 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc + * Copyright © 2007 Adrian Johnson + * Copyright © 2009 Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Chris Wilson + */ + +#include "cairoint.h" + +#include "cairo-surface-wrapper-private.h" + +/* A collection of routines to facilitate surface wrapping */ + +static cairo_bool_t +_cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper, + cairo_matrix_t *matrix) +{ + if (_cairo_matrix_is_identity (&wrapper->target->device_transform)) + return FALSE; + + *matrix = wrapper->target->device_transform; + return TRUE; +} + +cairo_status_t +_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper, + cairo_image_surface_t **image_out, + void **image_extra) +{ + if (unlikely (wrapper->target->status)) + return wrapper->target->status; + + return _cairo_surface_acquire_source_image (wrapper->target, + image_out, image_extra); +} + +void +_cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper, + cairo_image_surface_t *image, + void *image_extra) +{ + _cairo_surface_release_source_image (wrapper->target, image, image_extra); +} + +cairo_status_t +_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_matrix_t device_transform; + cairo_clip_t clip_copy, *dev_clip = clip; + + if (unlikely (wrapper->target->status)) + return wrapper->target->status; + + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + if (clip != NULL && + _cairo_surface_wrapper_needs_device_transform (wrapper, + &device_transform)) + { + status = _cairo_clip_init_copy_transformed (&clip_copy, clip, + &device_transform); + if (unlikely (status)) + goto FINISH; + + dev_clip = &clip_copy; + } + + status = _cairo_surface_paint (wrapper->target, op, source, dev_clip); + + FINISH: + if (dev_clip != clip) + _cairo_clip_reset (dev_clip); + return status; +} + +cairo_status_t +_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_pattern_t *mask, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_matrix_t device_transform; + cairo_clip_t clip_copy, *dev_clip = clip; + + if (unlikely (wrapper->target->status)) + return wrapper->target->status; + + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + if (clip != NULL && + _cairo_surface_wrapper_needs_device_transform (wrapper, + &device_transform)) + { + status = _cairo_clip_init_copy_transformed (&clip_copy, clip, + &device_transform); + if (unlikely (status)) + goto FINISH; + + dev_clip = &clip_copy; + } + + status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip); + + FINISH: + if (dev_clip != clip) + _cairo_clip_reset (dev_clip); + return status; +} + +cairo_status_t +_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_stroke_style_t *stroke_style, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_matrix_t device_transform; + cairo_path_fixed_t path_copy, *dev_path = path; + cairo_clip_t clip_copy, *dev_clip = clip; + cairo_matrix_t dev_ctm = *ctm; + cairo_matrix_t dev_ctm_inverse = *ctm_inverse; + + if (unlikely (wrapper->target->status)) + return wrapper->target->status; + + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + if (_cairo_surface_wrapper_needs_device_transform (wrapper, + &device_transform)) + { + status = _cairo_path_fixed_init_copy (&path_copy, dev_path); + if (unlikely (status)) + goto FINISH; + + _cairo_path_fixed_transform (&path_copy, &device_transform); + dev_path = &path_copy; + + if (clip != NULL) { + status = _cairo_clip_init_copy_transformed (&clip_copy, clip, + &device_transform); + if (unlikely (status)) + goto FINISH; + + dev_clip = &clip_copy; + } + + cairo_matrix_multiply (&dev_ctm, &dev_ctm, &device_transform); + status = cairo_matrix_invert (&device_transform); + assert (status == CAIRO_STATUS_SUCCESS); + cairo_matrix_multiply (&dev_ctm_inverse, + &device_transform, + &dev_ctm_inverse); + } + + status = _cairo_surface_stroke (wrapper->target, op, source, + dev_path, stroke_style, + &dev_ctm, &dev_ctm_inverse, + tolerance, antialias, + dev_clip); + + FINISH: + if (dev_path != path) + _cairo_path_fixed_fini (dev_path); + if (dev_clip != clip) + _cairo_clip_reset (dev_clip); + return status; +} + +cairo_status_t +_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper, + cairo_operator_t fill_op, + const cairo_pattern_t *fill_source, + cairo_fill_rule_t fill_rule, + double fill_tolerance, + cairo_antialias_t fill_antialias, + cairo_path_fixed_t *path, + cairo_operator_t stroke_op, + const cairo_pattern_t *stroke_source, + cairo_stroke_style_t *stroke_style, + cairo_matrix_t *stroke_ctm, + cairo_matrix_t *stroke_ctm_inverse, + double stroke_tolerance, + cairo_antialias_t stroke_antialias, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_matrix_t device_transform; + cairo_path_fixed_t path_copy, *dev_path = path; + cairo_clip_t clip_copy, *dev_clip = clip; + cairo_matrix_t dev_ctm = *stroke_ctm; + cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse; + + if (unlikely (wrapper->target->status)) + return wrapper->target->status; + + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + if (_cairo_surface_wrapper_needs_device_transform (wrapper, + &device_transform)) + { + status = _cairo_path_fixed_init_copy (&path_copy, dev_path); + if (unlikely (status)) + goto FINISH; + + _cairo_path_fixed_transform (&path_copy, &device_transform); + dev_path = &path_copy; + + if (clip != NULL) { + status = _cairo_clip_init_copy_transformed (&clip_copy, clip, + &device_transform); + if (unlikely (status)) + goto FINISH; + + dev_clip = &clip_copy; + } + + cairo_matrix_multiply (&dev_ctm, &dev_ctm, &device_transform); + status = cairo_matrix_invert (&device_transform); + assert (status == CAIRO_STATUS_SUCCESS); + cairo_matrix_multiply (&dev_ctm_inverse, + &device_transform, + &dev_ctm_inverse); + } + + status = _cairo_surface_fill_stroke (wrapper->target, + fill_op, fill_source, fill_rule, + fill_tolerance, fill_antialias, + dev_path, + stroke_op, stroke_source, + stroke_style, + &dev_ctm, &dev_ctm_inverse, + stroke_tolerance, stroke_antialias, + dev_clip); + + FINISH: + if (dev_path != path) + _cairo_path_fixed_fini (dev_path); + if (dev_clip != clip) + _cairo_clip_reset (dev_clip); + return status; +} + +cairo_status_t +_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_matrix_t device_transform; + cairo_path_fixed_t path_copy, *dev_path = path; + cairo_clip_t clip_copy, *dev_clip = clip; + + if (unlikely (wrapper->target->status)) + return wrapper->target->status; + + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + if (_cairo_surface_wrapper_needs_device_transform (wrapper, + &device_transform)) + { + status = _cairo_path_fixed_init_copy (&path_copy, dev_path); + if (unlikely (status)) + goto FINISH; + + _cairo_path_fixed_transform (&path_copy, &device_transform); + dev_path = &path_copy; + + if (clip != NULL) { + status = _cairo_clip_init_copy_transformed (&clip_copy, clip, + &device_transform); + if (unlikely (status)) + goto FINISH; + + dev_clip = &clip_copy; + } + } + + status = _cairo_surface_fill (wrapper->target, op, source, + dev_path, fill_rule, + tolerance, antialias, + dev_clip); + + FINISH: + if (dev_path != path) + _cairo_path_fixed_fini (dev_path); + if (dev_clip != clip) + _cairo_clip_reset (dev_clip); + return status; +} + +cairo_status_t +_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper, + cairo_operator_t op, + const cairo_pattern_t *source, + const char *utf8, + int utf8_len, + cairo_glyph_t *glyphs, + int num_glyphs, + const cairo_text_cluster_t *clusters, + int num_clusters, + cairo_text_cluster_flags_t cluster_flags, + cairo_scaled_font_t *scaled_font, + cairo_clip_t *clip) +{ + cairo_status_t status; + cairo_matrix_t device_transform; + cairo_clip_t clip_copy, *dev_clip = clip; + cairo_glyph_t *dev_glyphs = glyphs; + + if (unlikely (wrapper->target->status)) + return wrapper->target->status; + + if (glyphs == NULL || num_glyphs == 0) + return CAIRO_STATUS_SUCCESS; + + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + if (_cairo_surface_wrapper_needs_device_transform (wrapper, + &device_transform)) + { + int i; + + if (clip != NULL) { + dev_clip = &clip_copy; + status = _cairo_clip_init_copy_transformed (&clip_copy, clip, + &device_transform); + if (unlikely (status)) + goto FINISH; + } + + dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); + if (dev_glyphs == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto FINISH; + } + + for (i = 0; i < num_glyphs; i++) { + dev_glyphs[i] = glyphs[i]; + cairo_matrix_transform_point (&device_transform, + &dev_glyphs[i].x, + &dev_glyphs[i].y); + } + } + + status = _cairo_surface_show_text_glyphs (wrapper->target, op, source, + utf8, utf8_len, + dev_glyphs, num_glyphs, + clusters, num_clusters, + cluster_flags, + scaled_font, + dev_clip); + FINISH: + if (dev_clip != clip) + _cairo_clip_reset (dev_clip); + if (dev_glyphs != glyphs) + free (dev_glyphs); + return status; +} + +cairo_surface_t * +_cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper, + cairo_content_t content, + int width, + int height) +{ + return _cairo_surface_create_similar_solid (wrapper->target, + content, width, height, + CAIRO_COLOR_TRANSPARENT, + TRUE); +} + +cairo_bool_t +_cairo_surface_wrapper_get_extents (cairo_surface_wrapper_t *wrapper, + cairo_rectangle_int_t *extents) +{ + return _cairo_surface_get_extents (wrapper->target, extents); +} + +cairo_bool_t +_cairo_surface_wrapper_has_show_text_glyphs (cairo_surface_wrapper_t *wrapper) +{ + return cairo_surface_has_show_text_glyphs (wrapper->target); +} + +void +_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper, + cairo_surface_t *target) +{ + wrapper->target = cairo_surface_reference (target); +} + +void +_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper) +{ + cairo_surface_destroy (wrapper->target); +} diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 16e84921a..f656ed5f0 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -41,6 +41,7 @@ #include "cairo-surface-fallback-private.h" #include "cairo-clip-private.h" #include "cairo-meta-surface-private.h" +#include "cairo-region-private.h" #define DEFINE_NIL_SURFACE(status, name) \ const cairo_surface_t name = { \ @@ -59,9 +60,6 @@ const cairo_surface_t name = { \ 0.0, /* y_resolution */ \ 0.0, /* x_fallback_resolution */ \ 0.0, /* y_fallback_resolution */ \ - NULL, /* clip */ \ - 0, /* next_clip_serial */ \ - 0, /* current_clip_serial */ \ NULL, /* snapshot_of */ \ NULL, /* snapshot_detach */ \ { 0, /* size */ \ @@ -77,8 +75,11 @@ const cairo_surface_t name = { \ } /* font_options */ \ } +/* XXX error object! */ + static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil); static DEFINE_NIL_SURFACE(CAIRO_STATUS_SURFACE_TYPE_MISMATCH, _cairo_surface_nil_surface_type_mismatch); +static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STATUS, _cairo_surface_nil_invalid_status); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_VISUAL, _cairo_surface_nil_invalid_visual); @@ -89,7 +90,7 @@ static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_err static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size); -static cairo_status_t +static void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t **pattern, cairo_surface_t *destination, cairo_pattern_t *pattern_copy); @@ -361,43 +362,16 @@ _cairo_surface_init (cairo_surface_t *surface, surface->x_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT; surface->y_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT; - surface->clip = NULL; - surface->next_clip_serial = 0; - surface->current_clip_serial = 0; - _cairo_array_init (&surface->snapshots, sizeof (cairo_surface_t *)); surface->snapshot_of = NULL; surface->has_font_options = FALSE; } -cairo_surface_t * -_cairo_surface_create_similar_scratch (cairo_surface_t *other, - cairo_content_t content, - int width, - int height) +static void +_cairo_surface_copy_similar_properties (cairo_surface_t *surface, + cairo_surface_t *other) { - cairo_surface_t *surface = NULL; - - if (other->status) - return _cairo_surface_create_in_error (other->status); - - if (other->backend->create_similar) { - surface = other->backend->create_similar (other, content, width, height); - if (surface != NULL && surface->status) - return surface; - } - - if (surface == NULL) { - surface = - cairo_image_surface_create (_cairo_format_from_content (content), - width, height); - } - - /* If any error occurred, then return the nil surface we received. */ - if (unlikely (surface->status)) - return surface; - if (other->has_font_options || other->backend != surface->backend) { cairo_font_options_t options; @@ -408,6 +382,28 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other, cairo_surface_set_fallback_resolution (surface, other->x_fallback_resolution, other->y_fallback_resolution); +} + +cairo_surface_t * +_cairo_surface_create_similar_scratch (cairo_surface_t *other, + cairo_content_t content, + int width, + int height) +{ + cairo_surface_t *surface; + + if (unlikely (other->status)) + return _cairo_surface_create_in_error (other->status); + + if (other->backend->create_similar == NULL) + return NULL; + + surface = other->backend->create_similar (other, + content, width, height); + if (surface == NULL || surface->status) + return surface; + + _cairo_surface_copy_similar_properties (surface, other); return surface; } @@ -443,46 +439,46 @@ cairo_surface_create_similar (cairo_surface_t *other, int width, int height) { - if (other->status) + if (unlikely (other->status)) return _cairo_surface_create_in_error (other->status); - if (! CAIRO_CONTENT_VALID (content)) + if (unlikely (! CAIRO_CONTENT_VALID (content))) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); - return _cairo_surface_create_similar_solid (other, content, - width, height, - CAIRO_COLOR_TRANSPARENT); + return _cairo_surface_create_similar_solid (other, + content, width, height, + CAIRO_COLOR_TRANSPARENT, + TRUE); } -slim_hidden_def (cairo_surface_create_similar); cairo_surface_t * _cairo_surface_create_similar_solid (cairo_surface_t *other, cairo_content_t content, int width, int height, - const cairo_color_t *color) + const cairo_color_t *color, + cairo_bool_t allow_fallback) { cairo_status_t status; cairo_surface_t *surface; - cairo_solid_pattern_t solid_pattern; + cairo_solid_pattern_t pattern; surface = _cairo_surface_create_similar_scratch (other, content, width, height); - if (surface->status) + if (surface == NULL && allow_fallback) + surface = _cairo_image_surface_create_with_content (content, + width, height); + if (surface == NULL || surface->status) return surface; - _cairo_pattern_init_solid (&solid_pattern, color, content); - + _cairo_pattern_init_solid (&pattern, color, content); status = _cairo_surface_paint (surface, color == CAIRO_COLOR_TRANSPARENT ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE, - &solid_pattern.base, NULL); - - _cairo_pattern_fini (&solid_pattern.base); - + &pattern.base, NULL); if (unlikely (status)) { cairo_surface_destroy (surface); - return _cairo_surface_create_in_error (status); + surface = _cairo_surface_create_in_error (status); } return surface; @@ -504,7 +500,8 @@ _cairo_surface_create_solid_pattern_surface (cairo_surface_t *other, return _cairo_surface_create_similar_solid (other, solid_pattern->content, 1, 1, - &solid_pattern->color); + &solid_pattern->color, + FALSE); } cairo_int_status_t @@ -532,17 +529,6 @@ _cairo_surface_repaint_solid_pattern_surface (cairo_surface_t *other, NULL); } -cairo_clip_mode_t -_cairo_surface_get_clip_mode (cairo_surface_t *surface) -{ - if (surface->backend->intersect_clip_path != NULL) - return CAIRO_CLIP_MODE_PATH; - else if (surface->backend->set_clip_region != NULL) - return CAIRO_CLIP_MODE_REGION; - else - return CAIRO_CLIP_MODE_MASK; -} - /** * cairo_surface_reference: * @surface: a #cairo_surface_t @@ -604,36 +590,6 @@ cairo_surface_destroy (cairo_surface_t *surface) } slim_hidden_def(cairo_surface_destroy); -/** - * _cairo_surface_reset: - * @surface: a #cairo_surface_t - * - * Resets the surface back to defaults such that it may be reused in lieu - * of creating a new surface. - **/ -cairo_status_t -_cairo_surface_reset (cairo_surface_t *surface) -{ - if (surface == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - return CAIRO_STATUS_SUCCESS; - - assert (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count) == 1); - - _cairo_user_data_array_fini (&surface->user_data); - _cairo_user_data_array_fini (&surface->mime_data); - - if (surface->backend->reset != NULL) { - cairo_status_t status = surface->backend->reset (surface); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - } - - _cairo_surface_init (surface, surface->backend, surface->content); - - return CAIRO_STATUS_SUCCESS; -} - /** * cairo_surface_get_reference_count: * @surface: a #cairo_surface_t @@ -1078,14 +1034,7 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, * call mark_dirty()). */ assert (! _cairo_surface_has_snapshots (surface)); - /* Always reset the clip here, to avoid having external calls to - * clip manipulation functions of the underlying device clip result - * in a desync between the cairo clip and the backend clip, due to - * the clip caching. - */ - surface->current_clip_serial = -1; - - if (surface->backend->mark_dirty_rectangle) { + if (surface->backend->mark_dirty_rectangle != NULL) { /* XXX: FRAGILE: We're ignoring the scaling component of * device_transform here. I don't know what the right thing to * do would actually be if there were some scaling here, but @@ -1478,13 +1427,17 @@ _cairo_meta_surface_clone_similar (cairo_surface_t *surface, return CAIRO_STATUS_SUCCESS; } - if (width*height*8 < meta->extents.width*meta->extents.height) { - similar = cairo_surface_create_similar (surface, - src->content & content, - width, height); - status = similar->status; - if (unlikely (status)) - return status; + if (meta->unbounded || + width*height*8 < meta->extents.width*meta->extents.height) + { + /* XXX use _solid to perform an initial CLEAR? */ + similar = _cairo_surface_create_similar_scratch (surface, + src->content & content, + width, height); + if (similar == NULL) + return CAIRO_INT_STATUS_UNSUPPORTED; + if (unlikely (similar->status)) + return similar->status; cairo_surface_set_device_offset (similar, -src_x, -src_y); @@ -1493,15 +1446,15 @@ _cairo_meta_surface_clone_similar (cairo_surface_t *surface, cairo_surface_destroy (similar); return status; } - } else { - similar = cairo_surface_create_similar (surface, - src->content & content, - meta->extents.width, - meta->extents.height); - status = similar->status; - if (unlikely (status)) - return status; + similar = _cairo_surface_create_similar_scratch (surface, + src->content & content, + meta->extents.width, + meta->extents.height); + if (similar == NULL) + return CAIRO_INT_STATUS_UNSUPPORTED; + if (unlikely (similar->status)) + return similar->status; status = cairo_meta_surface_replay (src, similar); if (unlikely (status)) { @@ -1567,7 +1520,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, if (unlikely (surface->finished)) return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - if (surface->backend->clone_similar) { + if (surface->backend->clone_similar != NULL) { status = surface->backend->clone_similar (surface, src, content, src_x, src_y, @@ -1575,7 +1528,6 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, clone_offset_x, clone_offset_y, clone_out); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { if (_cairo_surface_is_image (src)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1620,7 +1572,6 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, clone_out); } - /* We should never get UNSUPPORTED here, so if we have an error, bail. */ if (unlikely (status)) return status; @@ -1762,11 +1713,12 @@ _cairo_surface_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_int_status_t status; - if (dst->status) + if (unlikely (dst->status)) return dst->status; assert (_cairo_surface_is_writable (dst)); @@ -1784,7 +1736,8 @@ _cairo_surface_composite (cairo_operator_t op, src_x, src_y, mask_x, mask_y, dst_x, dst_y, - width, height); + width, height, + clip_region); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return _cairo_surface_set_error (dst, status); } @@ -1795,7 +1748,8 @@ _cairo_surface_composite (cairo_operator_t op, src_x, src_y, mask_x, mask_y, dst_x, dst_y, - width, height)); + width, height, + clip_region)); } /** @@ -1883,8 +1837,8 @@ _cairo_surface_fill_region (cairo_surface_t *surface, for (i = 0; i < num_rects; i++) cairo_region_get_rectangle (region, i, &rects[i]); - status = _cairo_surface_fill_rectangles (surface, op, - color, rects, num_rects); + status = _cairo_surface_fill_rectangles (surface, + op, color, rects, num_rects); if (rects != stack_rects) free (rects); @@ -1926,14 +1880,16 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface, return CAIRO_STATUS_SUCCESS; if (surface->backend->fill_rectangles) { - status = surface->backend->fill_rectangles (surface, op, color, + status = surface->backend->fill_rectangles (surface, + op, color, rects, num_rects); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return _cairo_surface_set_error (surface, status); } return _cairo_surface_set_error (surface, - _cairo_surface_fallback_fill_rectangles (surface, op, color, + _cairo_surface_fallback_fill_rectangles (surface, + op, color, rects, num_rects)); } @@ -1941,34 +1897,32 @@ cairo_status_t _cairo_surface_paint (cairo_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_pattern_union_t dev_source; - if (surface->status) + if (unlikely (surface->status)) return surface->status; + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + _cairo_surface_begin_modification (surface); - status = _cairo_surface_copy_pattern_for_destination (&source, - surface, - &dev_source.base); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); + _cairo_surface_copy_pattern_for_destination (&source, + surface, + &dev_source.base); - if (surface->backend->paint) { - status = surface->backend->paint (surface, op, source, extents); + if (surface->backend->paint != NULL) { + status = surface->backend->paint (surface, op, source, clip); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto FINISH; } - status = _cairo_surface_fallback_paint (surface, op, source); + status = _cairo_surface_fallback_paint (surface, op, source, clip); FINISH: - if (source == &dev_source.base) - _cairo_pattern_fini (&dev_source.base); - return _cairo_surface_set_error (surface, status); } @@ -1977,45 +1931,34 @@ _cairo_surface_mask (cairo_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_pattern_union_t dev_source; cairo_pattern_union_t dev_mask; - if (surface->status) + if (unlikely (surface->status)) return surface->status; + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + _cairo_surface_begin_modification (surface); - status = _cairo_surface_copy_pattern_for_destination (&source, - surface, - &dev_source.base); - if (unlikely (status)) - goto FINISH; + _cairo_surface_copy_pattern_for_destination (&source, surface, + &dev_source.base); + _cairo_surface_copy_pattern_for_destination (&mask, surface, + &dev_mask.base); - status = _cairo_surface_copy_pattern_for_destination (&mask, - surface, - &dev_mask.base); - if (unlikely (status)) - goto CLEANUP_SOURCE; - - if (surface->backend->mask) { - status = surface->backend->mask (surface, op, source, mask, extents); + if (surface->backend->mask != NULL) { + status = surface->backend->mask (surface, op, source, mask, clip); if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto CLEANUP_MASK; + goto FINISH; } - status = _cairo_surface_fallback_mask (surface, op, source, mask); + status = _cairo_surface_fallback_mask (surface, op, source, mask, clip); - CLEANUP_MASK: - if (mask == &dev_mask.base) - _cairo_pattern_fini (&dev_mask.base); - CLEANUP_SOURCE: - if (source == &dev_source.base) - _cairo_pattern_fini (&dev_source.base); FINISH: - return _cairo_surface_set_error (surface, status); } @@ -2034,13 +1977,16 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface, cairo_matrix_t *stroke_ctm_inverse, double stroke_tolerance, cairo_antialias_t stroke_antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; - if (surface->status) + if (unlikely (surface->status)) return surface->status; + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + _cairo_surface_begin_modification (surface); if (surface->backend->fill_stroke) { @@ -2049,21 +1995,10 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface, cairo_matrix_t dev_ctm = *stroke_ctm; cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse; - status = _cairo_surface_copy_pattern_for_destination (&stroke_source, - surface, - &dev_stroke_source.base); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - status = _cairo_surface_copy_pattern_for_destination (&fill_source, - surface, - &dev_fill_source.base); - if (unlikely (status)) { - if (stroke_source == &dev_stroke_source.base) - _cairo_pattern_fini (&dev_stroke_source.base); - - return _cairo_surface_set_error (surface, status); - } + _cairo_surface_copy_pattern_for_destination (&stroke_source, surface, + &dev_stroke_source.base); + _cairo_surface_copy_pattern_for_destination (&fill_source, surface, + &dev_fill_source.base); status = surface->backend->fill_stroke (surface, fill_op, fill_source, fill_rule, @@ -2073,26 +2008,22 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface, stroke_style, &dev_ctm, &dev_ctm_inverse, stroke_tolerance, stroke_antialias, - extents); - - if (stroke_source == &dev_stroke_source.base) - _cairo_pattern_fini (&dev_stroke_source.base); - - if (fill_source == &dev_fill_source.base) - _cairo_pattern_fini (&dev_fill_source.base); + clip); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return _cairo_surface_set_error (surface, status); } status = _cairo_surface_fill (surface, fill_op, fill_source, path, - fill_rule, fill_tolerance, fill_antialias, NULL); + fill_rule, fill_tolerance, fill_antialias, + clip); if (unlikely (status)) return _cairo_surface_set_error (surface, status); status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path, stroke_style, stroke_ctm, stroke_ctm_inverse, - stroke_tolerance, stroke_antialias, NULL); + stroke_tolerance, stroke_antialias, + clip); if (unlikely (status)) return _cairo_surface_set_error (surface, status); @@ -2109,31 +2040,28 @@ _cairo_surface_stroke (cairo_surface_t *surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_pattern_union_t dev_source; - cairo_path_fixed_t *dev_path = path; - cairo_path_fixed_t real_dev_path; - cairo_matrix_t dev_ctm = *ctm; - cairo_matrix_t dev_ctm_inverse = *ctm_inverse; - if (surface->status) + if (unlikely (surface->status)) return surface->status; + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + _cairo_surface_begin_modification (surface); - status = _cairo_surface_copy_pattern_for_destination (&source, - surface, - &dev_source.base); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); + _cairo_surface_copy_pattern_for_destination (&source, surface, + &dev_source.base); - if (surface->backend->stroke) { + if (surface->backend->stroke != NULL) { status = surface->backend->stroke (surface, op, source, path, stroke_style, - &dev_ctm, &dev_ctm_inverse, - tolerance, antialias, extents); + ctm, ctm_inverse, + tolerance, antialias, + clip); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto FINISH; @@ -2141,16 +2069,11 @@ _cairo_surface_stroke (cairo_surface_t *surface, status = _cairo_surface_fallback_stroke (surface, op, source, path, stroke_style, - &dev_ctm, &dev_ctm_inverse, - tolerance, antialias); + ctm, ctm_inverse, + tolerance, antialias, + clip); FINISH: - if (dev_path == &real_dev_path) - _cairo_path_fixed_fini (&real_dev_path); - - if (source == &dev_source.base) - _cairo_pattern_fini (&dev_source.base); - return _cairo_surface_set_error (surface, status); } @@ -2162,26 +2085,26 @@ _cairo_surface_fill (cairo_surface_t *surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_pattern_union_t dev_source; - if (surface->status) + if (unlikely (surface->status)) return surface->status; + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + _cairo_surface_begin_modification (surface); - status = _cairo_surface_copy_pattern_for_destination (&source, - surface, - &dev_source.base); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - if (surface->backend->fill) { + _cairo_surface_copy_pattern_for_destination (&source, surface, + &dev_source.base); + if (surface->backend->fill != NULL) { status = surface->backend->fill (surface, op, source, path, fill_rule, - tolerance, antialias, extents); + tolerance, antialias, + clip); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto FINISH; @@ -2189,12 +2112,10 @@ _cairo_surface_fill (cairo_surface_t *surface, status = _cairo_surface_fallback_fill (surface, op, source, path, fill_rule, - tolerance, antialias); + tolerance, antialias, + clip); FINISH: - if (source == &dev_source.base) - _cairo_pattern_fini (&dev_source.base); - return _cairo_surface_set_error (surface, status); } @@ -2210,7 +2131,8 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps) + int num_traps, + cairo_region_t *clip_region) { cairo_int_status_t status; @@ -2231,7 +2153,8 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, src_x, src_y, dst_x, dst_y, width, height, - traps, num_traps); + traps, num_traps, + clip_region); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return _cairo_surface_set_error (dst, status); } @@ -2242,56 +2165,58 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, src_x, src_y, dst_x, dst_y, width, height, - traps, num_traps)); + traps, num_traps, + clip_region)); } cairo_span_renderer_t * -_cairo_surface_create_span_renderer (cairo_operator_t op, - const cairo_pattern_t *pattern, +_cairo_surface_create_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, cairo_surface_t *dst, - cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects) + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region) { assert (dst->snapshot_of == NULL); - if (dst->status) + if (unlikely (dst->status)) return _cairo_span_renderer_create_in_error (dst->status); - if (dst->finished) + if (unlikely (dst->finished)) return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); if (dst->backend->create_span_renderer) { return dst->backend->create_span_renderer (op, pattern, dst, antialias, - rects); + rects, + clip_region); } ASSERT_NOT_REACHED; return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED); } cairo_bool_t -_cairo_surface_check_span_renderer (cairo_operator_t op, +_cairo_surface_check_span_renderer (cairo_operator_t op, const cairo_pattern_t *pattern, cairo_surface_t *dst, - cairo_antialias_t antialias, + cairo_antialias_t antialias, const cairo_composite_rectangles_t *rects) { cairo_int_status_t status; assert (dst->snapshot_of == NULL); - if (dst->status) + if (unlikely (dst->status)) return FALSE; - if (dst->finished) { + if (unlikely (dst->finished)) { status = _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED); return FALSE; } if (dst->backend->check_span_renderer) { - return dst->backend->check_span_renderer (op, - pattern, dst, + return dst->backend->check_span_renderer (op, pattern, dst, antialias, rects); } @@ -2374,329 +2299,6 @@ cairo_surface_show_page (cairo_surface_t *surface) } slim_hidden_def (cairo_surface_show_page); -/** - * _cairo_surface_get_current_clip_serial: - * @surface: the #cairo_surface_t to return the serial number for - * - * This space left intentionally blank. - * - * Returns: the serial number associated with the current - * clip in the surface. All gstate functions must - * verify that the correct clip is set in the surface before - * invoking any surface drawing function. - */ -unsigned int -_cairo_surface_get_current_clip_serial (cairo_surface_t *surface) -{ - return surface->current_clip_serial; -} - -/** - * _cairo_surface_allocate_clip_serial: - * @surface: the #cairo_surface_t to allocate a serial number from - * - * Each surface has a separate set of clipping serial numbers, and - * this function allocates one from the specified surface. As zero is - * reserved for the special no-clipping case, this function will not - * return that except for an in-error surface, (ie. surface->status != - * %CAIRO_STATUS_SUCCESS). - */ -unsigned int -_cairo_surface_allocate_clip_serial (cairo_surface_t *surface) -{ - unsigned int serial; - - if (surface->status) - return 0; - - if ((serial = ++(surface->next_clip_serial)) == 0) - serial = ++(surface->next_clip_serial); - return serial; -} - -/** - * _cairo_surface_reset_clip: - * @surface: the #cairo_surface_t to reset the clip on - * - * This function sets the clipping for the surface to - * None, which is to say that drawing is entirely - * unclipped. It also sets the clip serial number - * to zero. - */ -cairo_status_t -_cairo_surface_reset_clip (cairo_surface_t *surface) -{ - cairo_status_t status; - - if (surface->status) - return surface->status; - - if (surface->finished) - return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED); - - surface->current_clip_serial = 0; - - if (surface->backend->intersect_clip_path) { - status = surface->backend->intersect_clip_path (surface, - NULL, - CAIRO_FILL_RULE_WINDING, - 0, - CAIRO_ANTIALIAS_DEFAULT); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - } - - if (surface->backend->set_clip_region != NULL) { - status = surface->backend->set_clip_region (surface, NULL); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - } - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_surface_set_clip_region: - * @surface: the #cairo_surface_t to reset the clip on - * @region: the #cairo_region_t to use for clipping - * @serial: the clip serial number associated with the region - * - * This function sets the clipping for the surface to - * the specified region and sets the surface clipping - * serial number to the associated serial number. - */ -cairo_status_t -_cairo_surface_set_clip_region (cairo_surface_t *surface, - cairo_region_t *region, - unsigned int serial) -{ - cairo_status_t status; - - if (surface->status) - return surface->status; - - if (surface->finished) - return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED); - - assert (surface->backend->set_clip_region != NULL); - - status = surface->backend->set_clip_region (surface, region); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - surface->current_clip_serial = serial; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_surface_intersect_clip_path (cairo_surface_t *surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_path_fixed_t *dev_path = path; - cairo_status_t status; - - if (surface->status) - return surface->status; - - if (surface->finished) - return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED); - - assert (surface->backend->intersect_clip_path != NULL); - - status = surface->backend->intersect_clip_path (surface, - dev_path, - fill_rule, - tolerance, - antialias); - - return _cairo_surface_set_error (surface, status); -} - -static cairo_status_t -_cairo_surface_set_clip_path_recursive (cairo_surface_t *surface, - cairo_clip_path_t *clip_path) -{ - cairo_status_t status; - - if (surface->status) - return surface->status; - - if (clip_path == NULL) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_set_clip_path_recursive (surface, clip_path->prev); - if (unlikely (status)) - return status; - - return _cairo_surface_intersect_clip_path (surface, - &clip_path->path, - clip_path->fill_rule, - clip_path->tolerance, - clip_path->antialias); -} - -/** - * _cairo_surface_set_clip_path: - * @surface: the #cairo_surface_t to set the clip on - * @clip_path: the clip path to set - * @serial: the clip serial number associated with the clip path - * - * Sets the given clipping path for the surface and assigns the - * clipping serial to the surface. - **/ -static cairo_status_t -_cairo_surface_set_clip_path (cairo_surface_t *surface, - cairo_clip_path_t *clip_path, - unsigned int serial) -{ - cairo_status_t status; - - if (surface->status) - return surface->status; - - if (surface->finished) - return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED); - - assert (surface->backend->intersect_clip_path != NULL); - - status = surface->backend->intersect_clip_path (surface, - NULL, - CAIRO_FILL_RULE_WINDING, - 0, - CAIRO_ANTIALIAS_DEFAULT); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - status = _cairo_surface_set_clip_path_recursive (surface, clip_path); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - surface->current_clip_serial = serial; - - return CAIRO_STATUS_SUCCESS; -} - - -/** - * _cairo_surface_set_empty_clip_path: - * @surface: the #cairo_surface_t to set the clip on - * @serial: the clip serial number associated with the clip path - * - * Create an empty clip path, one that represents the entire surface clipped - * out, and assigns the given clipping serial to the surface. - **/ -static cairo_status_t -_cairo_surface_set_empty_clip_path (cairo_surface_t *surface, - unsigned int serial) -{ - cairo_path_fixed_t path; - cairo_status_t status; - - if (surface->status) - return surface->status; - - _cairo_path_fixed_init (&path); - - status = surface->backend->intersect_clip_path (surface, - &path, - CAIRO_FILL_RULE_WINDING, - 0, - CAIRO_ANTIALIAS_DEFAULT); - - if (status == CAIRO_STATUS_SUCCESS) - surface->current_clip_serial = serial; - - _cairo_path_fixed_fini (&path); - - return _cairo_surface_set_error (surface, status); -} - -/** - * _cairo_surface_set_empty_clip_region: - * @surface: the #cairo_surface_t to set the clip on - * @serial: the clip serial number associated with the clip path - * - * Create an empty clip region, one that represents the entire surface clipped - * out, and assigns the given clipping serial to the surface. - **/ -static cairo_status_t -_cairo_surface_set_empty_clip_region (cairo_surface_t *surface, - unsigned int serial) -{ - cairo_region_t *region; - cairo_status_t status; - - if (surface->status) - return surface->status; - - region = cairo_region_create (); - status = region->status; - - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_surface_set_clip_region (surface, region, serial); - - cairo_region_destroy (region); - - return _cairo_surface_set_error (surface, status); -} - -cairo_clip_t * -_cairo_surface_get_clip (cairo_surface_t *surface) -{ - return surface->clip; -} - -cairo_status_t -_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip) -{ - unsigned int serial = 0; - - if (surface->status) - return surface->status; - - if (surface->finished) - return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED); - - if (clip) { - serial = clip->serial; - if (serial == 0) - clip = NULL; - } - - surface->clip = clip; - - if (serial == _cairo_surface_get_current_clip_serial (surface)) - return CAIRO_STATUS_SUCCESS; - - if (clip) { - if (clip->all_clipped) { - if (surface->backend->intersect_clip_path != NULL) - return _cairo_surface_set_empty_clip_path (surface, - clip->serial); - - if (surface->backend->set_clip_region != NULL) - return _cairo_surface_set_empty_clip_region (surface, - clip->serial); - } else { - if (clip->path) - return _cairo_surface_set_clip_path (surface, - clip->path, - clip->serial); - - if (clip->region) - return _cairo_surface_set_clip_region (surface, - clip->region, - clip->serial); - } - } - - return _cairo_surface_reset_clip (surface); -} - /** * _cairo_surface_get_extents: * @surface: the #cairo_surface_t to fetch extents for @@ -2721,31 +2323,22 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip) * This behavior would have to be changed is we ever exported a public * variant of this function. */ -cairo_int_status_t +cairo_bool_t _cairo_surface_get_extents (cairo_surface_t *surface, cairo_rectangle_int_t *extents) { - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; + cairo_bool_t bounded = FALSE; - if (surface->status) - return surface->status; + if (unlikely (surface->status || surface->finished)) + return TRUE; - if (surface->finished) - return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED); + if (surface->backend->get_extents != NULL) + bounded = surface->backend->get_extents (surface, extents); - if (surface->backend->get_extents) { - status = _cairo_surface_set_error (surface, - surface->backend->get_extents (surface, extents)); - } + if (! bounded) + _cairo_unbounded_rectangle_init (extents); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - extents->x = CAIRO_RECT_INT_MIN; - extents->y = CAIRO_RECT_INT_MIN; - extents->width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; - extents->height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; - } - - return status; + return bounded; } /** @@ -2817,25 +2410,25 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_scaled_font_t *dev_scaled_font = scaled_font; cairo_pattern_union_t dev_source; - if (surface->status) + if (unlikely (surface->status)) return surface->status; if (num_glyphs == 0 && utf8_len == 0) return CAIRO_STATUS_SUCCESS; + if (clip && clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + _cairo_surface_begin_modification (surface); - status = _cairo_surface_copy_pattern_for_destination (&source, - surface, - &dev_source.base); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); + _cairo_surface_copy_pattern_for_destination (&source, surface, + &dev_source.base); if (_cairo_surface_has_device_transform (surface) && ! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL)) @@ -2853,12 +2446,8 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, &font_options); } status = cairo_scaled_font_status (dev_scaled_font); - if (unlikely (status)) { - if (source == &dev_source.base) - _cairo_pattern_fini (&dev_source.base); - + if (unlikely (status)) return _cairo_surface_set_error (surface, status); - } status = CAIRO_INT_STATUS_UNSUPPORTED; @@ -2867,21 +2456,25 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, if (clusters) { /* A real show_text_glyphs call. Try show_text_glyphs backend * method first */ - if (surface->backend->show_text_glyphs) { + if (surface->backend->show_text_glyphs != NULL) { status = surface->backend->show_text_glyphs (surface, op, source, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags, - dev_scaled_font, extents); + dev_scaled_font, + clip); } - if (status == CAIRO_INT_STATUS_UNSUPPORTED && surface->backend->show_glyphs) { + if (status == CAIRO_INT_STATUS_UNSUPPORTED && + surface->backend->show_glyphs) + { int remaining_glyphs = num_glyphs; status = surface->backend->show_glyphs (surface, op, source, glyphs, num_glyphs, dev_scaled_font, - &remaining_glyphs, extents); + clip, + &remaining_glyphs); glyphs += num_glyphs - remaining_glyphs; num_glyphs = remaining_glyphs; if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0) @@ -2889,18 +2482,19 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, } } else { /* A mere show_glyphs call. Try show_glyphs backend method first */ - if (surface->backend->show_glyphs) { + if (surface->backend->show_glyphs != NULL) { int remaining_glyphs = num_glyphs; status = surface->backend->show_glyphs (surface, op, source, glyphs, num_glyphs, dev_scaled_font, - &remaining_glyphs, extents); + clip, + &remaining_glyphs); glyphs += num_glyphs - remaining_glyphs; num_glyphs = remaining_glyphs; if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0) status = CAIRO_STATUS_SUCCESS; - } else if (surface->backend->show_text_glyphs) { + } else if (surface->backend->show_text_glyphs != NULL) { /* Intentionally only try show_text_glyphs method for show_glyphs * calls if backend does not have show_glyphs. If backend has * both methods implemented, we don't fallback from show_glyphs to @@ -2914,22 +2508,22 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags, - dev_scaled_font, extents); + dev_scaled_font, + clip); } } - if (status == CAIRO_INT_STATUS_UNSUPPORTED) + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { status = _cairo_surface_fallback_show_glyphs (surface, op, source, glyphs, num_glyphs, - dev_scaled_font); + dev_scaled_font, + clip); + } if (dev_scaled_font != scaled_font) cairo_scaled_font_destroy (dev_scaled_font); - if (source == &dev_source.base) - _cairo_pattern_fini (&dev_source.base); - return _cairo_surface_set_error (surface, status); } @@ -2950,7 +2544,8 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, unsigned int width, unsigned int height, cairo_glyph_t *glyphs, - int num_glyphs) + int num_glyphs, + cairo_region_t *clip_region) { cairo_status_t status; @@ -2965,7 +2560,8 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, source_x, source_y, dest_x, dest_y, width, height, - glyphs, num_glyphs); + glyphs, num_glyphs, + clip_region); } else status = CAIRO_INT_STATUS_UNSUPPORTED; @@ -2979,7 +2575,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_rectangle_int_t dst_rectangle; cairo_region_t clear_region; @@ -2995,12 +2592,18 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, _cairo_region_init_rectangle (&clear_region, &dst_rectangle); - if (src_rectangle) { + if (clip_region != NULL) { + status = cairo_region_intersect (&clear_region, clip_region); + if (unlikely (status)) + goto CLEANUP_REGIONS; + } + + if (src_rectangle != NULL) { if (! _cairo_rectangle_intersect (&dst_rectangle, src_rectangle)) goto EMPTY; } - if (mask_rectangle) { + if (mask_rectangle != NULL) { if (! _cairo_rectangle_intersect (&dst_rectangle, mask_rectangle)) goto EMPTY; } @@ -3011,7 +2614,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, goto CLEANUP_REGIONS; EMPTY: - status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE, + status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, CAIRO_COLOR_TRANSPARENT, &clear_region); @@ -3060,13 +2663,14 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_rectangle_int_t src_tmp, mask_tmp; cairo_rectangle_int_t *src_rectangle = NULL; cairo_rectangle_int_t *mask_rectangle = NULL; - if (dst->status) + if (unlikely (dst->status)) return dst->status; assert (_cairo_surface_is_writable (dst)); @@ -3098,7 +2702,8 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst, } return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); } /** @@ -3138,7 +2743,8 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_rectangle_int_t src_tmp, mask_tmp; cairo_rectangle_int_t *src_rectangle = NULL; @@ -3171,7 +2777,8 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst, mask_rectangle = &mask_tmp; return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); } /** @@ -3183,26 +2790,19 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst, * Copies the given pattern, taking into account device scale and offsets * of the destination surface. */ -static cairo_status_t +static void _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t **pattern, cairo_surface_t *destination, cairo_pattern_t *pattern_copy) { - cairo_status_t status; - if (! _cairo_surface_has_device_transform (destination)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_pattern_init_copy (pattern_copy, *pattern); - if (unlikely (status)) - return status; + return; + _cairo_pattern_init_static_copy (pattern_copy, *pattern); _cairo_pattern_transform (pattern_copy, &destination->device_transform_inverse); - *pattern = pattern_copy; - return CAIRO_STATUS_SUCCESS; } /** @@ -3235,6 +2835,8 @@ _cairo_surface_create_in_error (cairo_status_t status) return (cairo_surface_t *) &_cairo_surface_nil; case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: return (cairo_surface_t *) &_cairo_surface_nil_surface_type_mismatch; + case CAIRO_STATUS_INVALID_STATUS: + return (cairo_surface_t *) &_cairo_surface_nil_invalid_status; case CAIRO_STATUS_INVALID_CONTENT: return (cairo_surface_t *) &_cairo_surface_nil_invalid_content; case CAIRO_STATUS_INVALID_FORMAT: @@ -3261,7 +2863,6 @@ _cairo_surface_create_in_error (cairo_status_t status) case CAIRO_STATUS_INVALID_POP_GROUP: case CAIRO_STATUS_NO_CURRENT_POINT: case CAIRO_STATUS_INVALID_MATRIX: - case CAIRO_STATUS_INVALID_STATUS: case CAIRO_STATUS_NULL_POINTER: case CAIRO_STATUS_INVALID_STRING: case CAIRO_STATUS_INVALID_PATH_DATA: diff --git a/src/cairo-svg-surface-private.h b/src/cairo-svg-surface-private.h index e7cd4db8c..64efe7f2a 100644 --- a/src/cairo-svg-surface-private.h +++ b/src/cairo-svg-surface-private.h @@ -44,6 +44,7 @@ #include "cairo-svg.h" #include "cairo-surface-private.h" +#include "cairo-surface-clipper-private.h" typedef struct cairo_svg_document cairo_svg_document_t; @@ -52,8 +53,6 @@ typedef struct cairo_svg_surface { cairo_content_t content; - unsigned int id; - double width; double height; @@ -62,6 +61,7 @@ typedef struct cairo_svg_surface { cairo_output_stream_t *xml_node; cairo_array_t page_set; + cairo_surface_clipper_t clipper; unsigned int clip_level; unsigned int base_clip; cairo_bool_t is_base_clip_emitted; diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index 3a6b62dfa..08e4cfcbe 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -49,6 +49,7 @@ #include "cairo-path-fixed-private.h" #include "cairo-paginated-private.h" #include "cairo-scaled-font-subsets-private.h" +#include "cairo-surface-clipper-private.h" #include "cairo-svg-surface-private.h" typedef struct cairo_svg_page cairo_svg_page_t; @@ -63,6 +64,11 @@ static const cairo_svg_version_t _cairo_svg_versions[] = #define CAIRO_SVG_VERSION_LAST ARRAY_LENGTH (_cairo_svg_versions) +static void +_cairo_svg_surface_emit_path (cairo_output_stream_t *output, + cairo_path_fixed_t *path, + cairo_matrix_t *ctm_inverse); + static cairo_bool_t _cairo_svg_version_has_page_set_support (cairo_svg_version_t version) { @@ -99,7 +105,6 @@ struct cairo_svg_document { cairo_output_stream_t *xml_node_defs; cairo_output_stream_t *xml_node_glyphs; - unsigned int surface_id; unsigned int linear_pattern_id; unsigned int radial_pattern_id; unsigned int pattern_id; @@ -109,18 +114,11 @@ struct cairo_svg_document { cairo_bool_t alpha_filter; - cairo_array_t meta_snapshots; - cairo_svg_version_t svg_version; cairo_scaled_font_subsets_t *font_subsets; }; -typedef struct { - unsigned int id; - cairo_meta_surface_t *meta; -} cairo_meta_snapshot_t; - static cairo_status_t _cairo_svg_document_create (cairo_output_stream_t *stream, double width, @@ -278,8 +276,8 @@ _extract_svg_surface (cairo_surface_t *surface, * Since: 1.2 **/ void -cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface, - cairo_svg_version_t version) +cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface, + cairo_svg_version_t version) { cairo_svg_surface_t *surface = NULL; /* hide compiler warning */ cairo_status_t status; @@ -306,7 +304,7 @@ cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface, **/ void cairo_svg_get_versions (cairo_svg_version_t const **versions, - int *num_versions) + int *num_versions) { if (versions != NULL) *versions = _cairo_svg_versions; @@ -336,6 +334,73 @@ cairo_svg_version_to_string (cairo_svg_version_t version) return _cairo_svg_version_strings[version]; } +static cairo_bool_t +_cliprect_covers_surface (cairo_svg_surface_t *surface, + cairo_path_fixed_t *path) +{ + cairo_box_t box; + + if (_cairo_path_fixed_is_rectangle (path, &box)) { + if (box.p1.x <= 0 && + box.p1.y <= 0 && + _cairo_fixed_to_double (box.p2.x) >= surface->width && + _cairo_fixed_to_double (box.p2.y) >= surface->height) + { + return TRUE; + } + } + + return FALSE; +} + +static cairo_status_t +_cairo_svg_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) +{ + cairo_svg_surface_t *surface = cairo_container_of (clipper, + cairo_svg_surface_t, + clipper); + cairo_svg_document_t *document = surface->document; + unsigned int i; + + if (path == NULL) { + for (i = 0; i < surface->clip_level; i++) + _cairo_output_stream_printf (surface->xml_node, "\n"); + + surface->clip_level = 0; + return CAIRO_STATUS_SUCCESS; + } + + /* skip trivial whole-page clips */ + if (_cliprect_covers_surface (surface, path)) + return CAIRO_STATUS_SUCCESS; + + _cairo_output_stream_printf (document->xml_node_defs, + "\n" + " clip_id); + _cairo_svg_surface_emit_path (document->xml_node_defs, path, NULL); + + _cairo_output_stream_printf (document->xml_node_defs, + "/>\n" + "\n"); + + _cairo_output_stream_printf (surface->xml_node, + "\n", + document->clip_id, + fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? + "evenodd" : "nonzero"); + + document->clip_id++; + surface->clip_level++; + + return CAIRO_STATUS_SUCCESS; +} + static cairo_surface_t * _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, cairo_content_t content, @@ -359,8 +424,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, surface->document = _cairo_svg_document_reference (document); surface->clip_level = 0; + _cairo_surface_clipper_init (&surface->clipper, + _cairo_svg_surface_clipper_intersect_clip_path); - surface->id = document->surface_id++; surface->base_clip = document->clip_id++; surface->is_base_clip_emitted = FALSE; @@ -388,8 +454,6 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, paginated = _cairo_paginated_surface_create (&surface->base, surface->content, - surface->width, - surface->height, &cairo_svg_surface_paginated_backend); status = paginated->status; if (status == CAIRO_STATUS_SUCCESS) { @@ -457,7 +521,7 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface) return NULL; } - page.surface_id = surface->id; + page.surface_id = surface->base.unique_id; page.clip_level = surface->clip_level; page.xml_node = surface->xml_node; @@ -468,11 +532,13 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface) surface->xml_node = stream; surface->clip_level = 0; - for (i = 0; i < page.clip_level; i++) _cairo_output_stream_printf (page.xml_node, "\n"); - return _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1); + _cairo_surface_clipper_reset (&surface->clipper); + + return _cairo_array_index (&surface->page_set, + surface->page_set.num_elements - 1); } static cairo_int_status_t @@ -486,7 +552,6 @@ _cairo_svg_surface_copy_page (void *abstract_surface) return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_memory_stream_copy (page->xml_node, surface->xml_node); - surface->clip_level = page->clip_level; return CAIRO_STATUS_SUCCESS; } @@ -596,7 +661,7 @@ _cairo_svg_path_close_path (void *closure) return CAIRO_STATUS_SUCCESS; } -static cairo_status_t +static void _cairo_svg_surface_emit_path (cairo_output_stream_t *output, cairo_path_fixed_t *path, cairo_matrix_t *ctm_inverse) @@ -615,12 +680,9 @@ _cairo_svg_surface_emit_path (cairo_output_stream_t *output, _cairo_svg_path_curve_to, _cairo_svg_path_close_path, &info); - if (unlikely (status)) - return status; + assert (status == CAIRO_STATUS_SUCCESS); _cairo_output_stream_printf (output, "\""); - - return status; } static cairo_int_status_t @@ -642,9 +704,8 @@ _cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document, _cairo_output_stream_printf (document->xml_node_glyphs, "xml_node_glyphs, scaled_glyph->path, NULL); - if (unlikely (status)) - return status; + _cairo_svg_surface_emit_path (document->xml_node_glyphs, + scaled_glyph->path, NULL); _cairo_output_stream_printf (document->xml_node_glyphs, "/>\n"); @@ -847,22 +908,7 @@ _cairo_svg_surface_operation_supported (cairo_svg_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *pattern) { - if (_cairo_svg_surface_analyze_operation (surface, op, pattern) - != CAIRO_INT_STATUS_UNSUPPORTED) - { - return TRUE; - } else { - return FALSE; - } -} - -static cairo_surface_t * -_cairo_svg_surface_create_similar (void *abstract_src, - cairo_content_t content, - int width, - int height) -{ - return cairo_meta_surface_create (content, width, height); + return _cairo_svg_surface_analyze_operation (surface, op, pattern) != CAIRO_INT_STATUS_UNSUPPORTED; } static cairo_status_t @@ -893,6 +939,8 @@ _cairo_svg_surface_finish (void *abstract_surface) } _cairo_array_fini (&surface->page_set); + _cairo_surface_clipper_reset (&surface->clipper); + status2 = _cairo_svg_document_destroy (document); if (status == CAIRO_STATUS_SUCCESS) status = status2; @@ -900,6 +948,7 @@ _cairo_svg_surface_finish (void *abstract_surface) return status; } + static void _cairo_svg_surface_emit_alpha_filter (cairo_svg_document_t *document) { @@ -1120,112 +1169,139 @@ _cairo_svg_surface_emit_operator_for_style (cairo_output_stream_t *output, } static cairo_status_t -_cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output, - cairo_svg_surface_t *svg_surface, - cairo_operator_t op, - cairo_surface_pattern_t *pattern, - int pattern_id, - const cairo_matrix_t *parent_matrix, - const char *extra_attributes) +_cairo_svg_surface_emit_surface (cairo_svg_document_t *document, + cairo_surface_t *surface) { cairo_rectangle_int_t extents; + cairo_bool_t is_bounded; cairo_status_t status; - cairo_matrix_t p2u; - status = _cairo_surface_get_extents (pattern->surface, &extents); + if (_cairo_user_data_array_get_data (&surface->user_data, + (cairo_user_data_key_t *) document)) + { + return CAIRO_STATUS_SUCCESS; + } + + is_bounded = _cairo_surface_get_extents (surface, &extents); + assert (is_bounded); + + _cairo_output_stream_printf (document->xml_node_defs, + "unique_id, + extents.width, extents.height); + + _cairo_output_stream_printf (document->xml_node_defs, " xlink:href=\""); + + status = _cairo_surface_base64_encode (surface, + document->xml_node_defs); if (unlikely (status)) return status; + _cairo_output_stream_printf (document->xml_node_defs, "\"/>\n"); + + /* and tag it */ + return _cairo_user_data_array_set_data (&surface->user_data, + (cairo_user_data_key_t *) document, + document, NULL); +} + +static cairo_status_t +_cairo_svg_surface_emit_composite_surface_pattern (cairo_output_stream_t *output, + cairo_svg_surface_t *svg_surface, + cairo_operator_t op, + cairo_surface_pattern_t *pattern, + int pattern_id, + const cairo_matrix_t *parent_matrix, + const char *extra_attributes) +{ + cairo_status_t status; + cairo_matrix_t p2u; + p2u = pattern->base.matrix; status = cairo_matrix_invert (&p2u); /* cairo_pattern_set_matrix ensures the matrix is invertible */ assert (status == CAIRO_STATUS_SUCCESS); + status = _cairo_svg_surface_emit_surface (svg_surface->document, + pattern->surface); + if (unlikely (status)) + return status; + if (pattern_id != invalid_pattern_id) { + cairo_rectangle_int_t extents; + cairo_bool_t is_bounded; + + is_bounded = _cairo_surface_get_extents (pattern->surface, &extents); + assert (is_bounded); + _cairo_output_stream_printf (output, "\n"); + _cairo_svg_surface_emit_transform (output, + " patternTransform", + &p2u, parent_matrix); + _cairo_output_stream_printf (output, ">\n "); } _cairo_output_stream_printf (output, - " surface->unique_id); if (extra_attributes) _cairo_output_stream_printf (output, " %s", extra_attributes); - _cairo_output_stream_printf (output, " xlink:href=\""); + if (pattern_id == invalid_pattern_id) { + _cairo_svg_surface_emit_operator (output, svg_surface, op); + _cairo_svg_surface_emit_transform (output, + " transform", + &p2u, parent_matrix); + } + _cairo_output_stream_printf (output, "/>\n"); - status = _cairo_surface_base64_encode (pattern->surface, output); - - _cairo_output_stream_printf (output, "\"/>\n"); if (pattern_id != invalid_pattern_id) _cairo_output_stream_printf (output, "\n"); - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_status_t _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, - cairo_meta_surface_t *surface, - int *id) + cairo_meta_surface_t *source) { cairo_status_t status; cairo_surface_t *paginated_surface; cairo_svg_surface_t *svg_surface; - cairo_meta_snapshot_t new_snapshot; cairo_array_t *page_set; cairo_output_stream_t *contents; - cairo_meta_surface_t *meta; - cairo_meta_snapshot_t *snapshot; - unsigned int num_elements; - unsigned int i; - /* search in already emitted meta snapshots */ - num_elements = document->meta_snapshots.num_elements; - for (i = 0; i < num_elements; i++) { - snapshot = _cairo_array_index (&document->meta_snapshots, i); - meta = snapshot->meta; - if (meta->commands.num_elements == surface->commands.num_elements && - _cairo_array_index (&meta->commands, 0) == _cairo_array_index (&surface->commands, 0)) { - *id = snapshot->id; - return CAIRO_STATUS_SUCCESS; - } + if (_cairo_user_data_array_get_data (&source->base.user_data, + (cairo_user_data_key_t *) document)) + { + return CAIRO_STATUS_SUCCESS; } - meta = (cairo_meta_surface_t *) _cairo_surface_snapshot (&surface->base); - if (unlikely (meta->base.status)) - return meta->base.status; - paginated_surface = _cairo_svg_surface_create_for_document (document, - meta->content, - meta->width_pixels, - meta->height_pixels); - if (paginated_surface->status) { - cairo_surface_destroy (&meta->base); + source->content, + source->extents_pixels.width, + source->extents_pixels.height); + if (unlikely (paginated_surface->status)) return paginated_surface->status; - } - svg_surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (paginated_surface); + svg_surface = (cairo_svg_surface_t *) + _cairo_paginated_surface_get_target (paginated_surface); cairo_surface_set_fallback_resolution (paginated_surface, document->owner->x_fallback_resolution, document->owner->y_fallback_resolution); + cairo_surface_set_device_offset (&svg_surface->base, + -source->extents_pixels.x, + -source->extents_pixels.y); - status = cairo_meta_surface_replay (&meta->base, paginated_surface); + status = cairo_meta_surface_replay (&source->base, paginated_surface); if (unlikely (status)) { - cairo_surface_destroy (&meta->base); cairo_surface_destroy (paginated_surface); return status; } @@ -1233,21 +1309,11 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, cairo_surface_show_page (paginated_surface); status = cairo_surface_status (paginated_surface); if (unlikely (status)) { - cairo_surface_destroy (&meta->base); cairo_surface_destroy (paginated_surface); return status; } - new_snapshot.meta = meta; - new_snapshot.id = svg_surface->id; - status = _cairo_array_append (&document->meta_snapshots, &new_snapshot); - if (unlikely (status)) { - cairo_surface_destroy (&meta->base); - cairo_surface_destroy (paginated_surface); - return status; - } - - if (!svg_surface->is_base_clip_emitted) { + if (! svg_surface->is_base_clip_emitted) { svg_surface->is_base_clip_emitted = TRUE; _cairo_output_stream_printf (document->xml_node_defs, "\n" @@ -1258,19 +1324,19 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, svg_surface->height); } - if (meta->content == CAIRO_CONTENT_ALPHA) { + if (source->content == CAIRO_CONTENT_ALPHA) { _cairo_svg_surface_emit_alpha_filter (document); _cairo_output_stream_printf (document->xml_node_defs, "\n", - svg_surface->id, + source->base.unique_id, svg_surface->base_clip); } else { _cairo_output_stream_printf (document->xml_node_defs, "\n", - svg_surface->id, + source->base.unique_id, svg_surface->base_clip); } @@ -1293,19 +1359,16 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, _cairo_output_stream_printf (document->xml_node_defs, "\n"); - *id = new_snapshot.id; - status = cairo_surface_status (paginated_surface); cairo_surface_destroy (paginated_surface); - /* FIXME: cairo_paginated_surface doesn't take a ref to the - * passed in target surface so we can't call destroy here. - * cairo_paginated_surface should be fixed, but for now just - * work around it. */ + if (unlikely (status)) + return status; - /* cairo_surface_destroy (svg_surface); */ - - return status; + /* and tag it */ + return _cairo_user_data_array_set_data (&source->base.user_data, + (cairo_user_data_key_t *) document, + document, NULL); } static cairo_status_t @@ -1321,7 +1384,6 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output, cairo_meta_surface_t *meta_surface; cairo_matrix_t p2u; cairo_status_t status; - int id = 0; p2u = pattern->base.matrix; status = cairo_matrix_invert (&p2u); @@ -1329,8 +1391,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output, assert (status == CAIRO_STATUS_SUCCESS); meta_surface = (cairo_meta_surface_t *) pattern->surface; - - status = _cairo_svg_surface_emit_meta_surface (document, meta_surface, &id); + status = _cairo_svg_surface_emit_meta_surface (document, meta_surface); if (unlikely (status)) return status; @@ -1340,15 +1401,15 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output, "patternUnits=\"userSpaceOnUse\" " "width=\"%d\" height=\"%d\"", pattern_id, - (int) ceil (meta_surface->width_pixels), - (int) ceil (meta_surface->height_pixels)); + meta_surface->extents.width, + meta_surface->extents.height); _cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix); _cairo_output_stream_printf (output, ">\n"); } _cairo_output_stream_printf (output, "base.unique_id); if (pattern_id == invalid_pattern_id) { _cairo_svg_surface_emit_operator (output, surface, op); @@ -1377,12 +1438,18 @@ _cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t *output, { if (_cairo_surface_is_meta (pattern->surface)) { - return _cairo_svg_surface_emit_composite_meta_pattern (output, surface, op, pattern, - pattern_id, parent_matrix, extra_attributes); + return _cairo_svg_surface_emit_composite_meta_pattern (output, surface, + op, pattern, + pattern_id, + parent_matrix, + extra_attributes); } - return _cairo_svg_surface_emit_composite_image_pattern (output, surface, op, pattern, - pattern_id, parent_matrix, extra_attributes); + return _cairo_svg_surface_emit_composite_surface_pattern (output, surface, + op, pattern, + pattern_id, + parent_matrix, + extra_attributes); } static cairo_status_t @@ -1716,7 +1783,9 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface, document->radial_pattern_id, x1, y1, x1, y1, r1); - _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix); + _cairo_svg_surface_emit_transform (document->xml_node_defs, + "gradientTransform", + &p2u, parent_matrix); _cairo_output_stream_printf (document->xml_node_defs, ">\n"); if (extend == CAIRO_EXTEND_NONE || n_stops < 1) @@ -1981,11 +2050,15 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface, cairo_matrix_t *stroke_ctm_inverse, double stroke_tolerance, cairo_antialias_t stroke_antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_svg_surface_t *surface = abstract_surface; cairo_status_t status; + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + _cairo_output_stream_printf (surface->xml_node, "xml_node, surface, fill_op, fill_source, fill_rule, stroke_ctm_inverse); @@ -1999,9 +2072,7 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface, _cairo_output_stream_printf (surface->xml_node, "\" "); - status = _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse); - if (unlikely (status)) - return status; + _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse); _cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL); _cairo_output_stream_printf (surface->xml_node, "/>\n"); @@ -2017,7 +2088,7 @@ _cairo_svg_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_svg_surface_t *surface = abstract_surface; cairo_status_t status; @@ -2027,6 +2098,10 @@ _cairo_svg_surface_fill (void *abstract_surface, assert (_cairo_svg_surface_operation_supported (surface, op, source)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + _cairo_output_stream_printf (surface->xml_node, "xml_node, surface, op, source, fill_rule, NULL); if (unlikely (status)) @@ -2034,16 +2109,14 @@ _cairo_svg_surface_fill (void *abstract_surface, _cairo_output_stream_printf (surface->xml_node, "\" "); - status = _cairo_svg_surface_emit_path (surface->xml_node, path, NULL); - if (unlikely (status)) - return status; + _cairo_svg_surface_emit_path (surface->xml_node, path, NULL); _cairo_output_stream_printf (surface->xml_node, "/>\n"); return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t +static cairo_bool_t _cairo_svg_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -2053,13 +2126,13 @@ _cairo_svg_surface_get_extents (void *abstract_surface, rectangle->y = 0; /* XXX: The conversion to integers here is pretty bogus, (not to - * mention the aribitray limitation of width to a short(!). We + * mention the arbitrary limitation of width to a short(!). We * may need to come up with a better interface for get_size. */ rectangle->width = (int) ceil (surface->width); rectangle->height = (int) ceil (surface->height); - return CAIRO_STATUS_SUCCESS; + return TRUE; } static cairo_status_t @@ -2106,52 +2179,63 @@ static cairo_int_status_t _cairo_svg_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_svg_surface_t *surface = abstract_surface; - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return _cairo_svg_surface_analyze_operation (surface, op, source); - - assert (_cairo_svg_surface_operation_supported (surface, op, source)); - /* Emulation of clear and source operators, when no clipping region * is defined. We just delete existing content of surface root node, * and exit early if operator is clear. - * XXX: optimization of SOURCE operator doesn't work, since analyze - * above always return FALSE. In order to make it work, we need a way - * to know if there's an active clipping path. - * Optimization of CLEAR works because of a test in paginated surface, - * and an optimization in meta surface. */ - if (surface->clip_level == 0 && op == CAIRO_OPERATOR_CLEAR) { - status = _cairo_output_stream_destroy (surface->xml_node); - if (unlikely (status)) { - surface->xml_node = NULL; - return status; - } - - surface->xml_node = _cairo_memory_stream_create (); - if (_cairo_output_stream_get_status (surface->xml_node)) { - status = _cairo_output_stream_destroy (surface->xml_node); - surface->xml_node = NULL; - return status; - } - - if (op == CAIRO_OPERATOR_CLEAR) { - if (surface->content == CAIRO_CONTENT_COLOR) { - _cairo_output_stream_printf (surface->xml_node, - "\n", - surface->width, surface->height); - } + */ + if ((op == CAIRO_OPERATOR_CLEAR || op == CAIRO_OPERATOR_SOURCE) && + clip == NULL) + { + switch (surface->paginated_mode) { + case CAIRO_PAGINATED_MODE_FALLBACK: + ASSERT_NOT_REACHED; + case CAIRO_PAGINATED_MODE_ANALYZE: return CAIRO_STATUS_SUCCESS; + + case CAIRO_PAGINATED_MODE_RENDER: + status = _cairo_output_stream_destroy (surface->xml_node); + if (unlikely (status)) { + surface->xml_node = NULL; + return status; + } + + surface->xml_node = _cairo_memory_stream_create (); + if (_cairo_output_stream_get_status (surface->xml_node)) { + status = _cairo_output_stream_destroy (surface->xml_node); + surface->xml_node = NULL; + return status; + } + + if (op == CAIRO_OPERATOR_CLEAR) { + if (surface->content == CAIRO_CONTENT_COLOR) { + _cairo_output_stream_printf (surface->xml_node, + "\n", + surface->width, surface->height); + } + return CAIRO_STATUS_SUCCESS; + } + break; } + } else { + if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) + return _cairo_svg_surface_analyze_operation (surface, op, source); + + assert (_cairo_svg_surface_operation_supported (surface, op, source)); } + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + return _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, 0, NULL); } @@ -2161,7 +2245,7 @@ _cairo_svg_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_status_t status; cairo_svg_surface_t *surface = abstract_surface; @@ -2189,6 +2273,10 @@ _cairo_svg_surface_mask (void *abstract_surface, assert (_cairo_svg_surface_operation_supported (surface, op, source)); assert (_cairo_svg_surface_operation_supported (surface, CAIRO_OPERATOR_OVER, mask)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) { const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t*) mask; cairo_content_t content = cairo_surface_get_content (surface_pattern->surface); @@ -2249,7 +2337,7 @@ _cairo_svg_surface_stroke (void *abstract_dst, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_svg_surface_t *surface = abstract_dst; cairo_status_t status; @@ -2259,6 +2347,10 @@ _cairo_svg_surface_stroke (void *abstract_dst, assert (_cairo_svg_surface_operation_supported (surface, op, source)); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + _cairo_output_stream_printf (surface->xml_node, "xml_node, surface, op, source, stroke_style, ctm_inverse); @@ -2267,9 +2359,7 @@ _cairo_svg_surface_stroke (void *abstract_dst, _cairo_output_stream_printf (surface->xml_node, "\" "); - status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse); - if (unlikely (status)) - return status; + _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse); _cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL); _cairo_output_stream_printf (surface->xml_node, "/>\n"); @@ -2284,8 +2374,8 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_svg_surface_t *surface = abstract_surface; cairo_svg_document_t *document = surface->document; @@ -2302,6 +2392,10 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, if (num_glyphs <= 0) return CAIRO_STATUS_SUCCESS; + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + /* FIXME it's probably possible to apply a pattern of a gradient to * a group of symbols, but I don't know how yet. Gradients or patterns * are translated by x and y properties of use element. */ @@ -2349,7 +2443,9 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, FALLBACK: _cairo_path_fixed_init (&path); - status = _cairo_scaled_font_glyph_path (scaled_font,(cairo_glyph_t *) glyphs, num_glyphs, &path); + status = _cairo_scaled_font_glyph_path (scaled_font, + (cairo_glyph_t *) glyphs, + num_glyphs, &path); if (unlikely (status)) { _cairo_path_fixed_fini (&path); @@ -2357,58 +2453,15 @@ FALLBACK: } status = _cairo_svg_surface_fill (abstract_surface, op, pattern, - &path, CAIRO_FILL_RULE_WINDING, 0.0, CAIRO_ANTIALIAS_SUBPIXEL, NULL); + &path, CAIRO_FILL_RULE_WINDING, + 0.0, CAIRO_ANTIALIAS_SUBPIXEL, + clip); _cairo_path_fixed_fini (&path); return status; } -static cairo_int_status_t -_cairo_svg_surface_intersect_clip_path (void *dst, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_svg_surface_t *surface = dst; - cairo_svg_document_t *document = surface->document; - cairo_status_t status; - unsigned int i; - - if (path == NULL) { - for (i = 0; i < surface->clip_level; i++) - _cairo_output_stream_printf (surface->xml_node, "\n"); - - surface->clip_level = 0; - return CAIRO_STATUS_SUCCESS; - } - - _cairo_output_stream_printf (document->xml_node_defs, - "\n" - " clip_id); - status = _cairo_svg_surface_emit_path (document->xml_node_defs, path, NULL); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (document->xml_node_defs, - "/>\n" - "\n"); - - _cairo_output_stream_printf (surface->xml_node, - "\n", - document->clip_id, - fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? - "evenodd" : "nonzero"); - - document->clip_id++; - surface->clip_level++; - - return CAIRO_STATUS_SUCCESS; -} - static void _cairo_svg_surface_get_font_options (void *abstract_surface, cairo_font_options_t *options) @@ -2422,7 +2475,7 @@ _cairo_svg_surface_get_font_options (void *abstract_surface, static const cairo_surface_backend_t cairo_svg_surface_backend = { CAIRO_SURFACE_TYPE_SVG, - _cairo_svg_surface_create_similar, + NULL, /* create_similar: handled by wrapper */ _cairo_svg_surface_finish, NULL, /* acquire_source_image */ NULL, /* release_source_image */ @@ -2436,8 +2489,6 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = { NULL, /* check_span_renderer */ _cairo_svg_surface_copy_page, _cairo_svg_surface_show_page, - NULL, /* set_clip_region */ - _cairo_svg_surface_intersect_clip_path, _cairo_svg_surface_get_extents, NULL, /* _cairo_svg_surface_old_show_glyphs, */ _cairo_svg_surface_get_font_options, @@ -2452,7 +2503,6 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = { _cairo_svg_surface_show_glyphs, NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ _cairo_svg_surface_fill_stroke }; @@ -2487,7 +2537,6 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, document->width = width; document->height = height; - document->surface_id = 0; document->linear_pattern_id = 0; document->radial_pattern_id = 0; document->pattern_id = 0; @@ -2507,9 +2556,6 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, document->alpha_filter = FALSE; - _cairo_array_init (&document->meta_snapshots, - sizeof (cairo_meta_snapshot_t)); - document->svg_version = version; *document_out = document; @@ -2560,7 +2606,6 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) { cairo_status_t status, status2; cairo_output_stream_t *output = document->output_stream; - cairo_meta_snapshot_t *snapshot; cairo_svg_page_t *page; unsigned int i; @@ -2662,16 +2707,6 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) if (status == CAIRO_STATUS_SUCCESS) status = status2; - for (i = 0; i < document->meta_snapshots.num_elements; i++) { - snapshot = _cairo_array_index (&document->meta_snapshots, i); - cairo_surface_finish (&snapshot->meta->base); - status2 = cairo_surface_status (&snapshot->meta->base); - cairo_surface_destroy (&snapshot->meta->base); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } - _cairo_array_fini (&document->meta_snapshots); - document->finished = TRUE; return status; diff --git a/src/cairo-traps.c b/src/cairo-traps.c index d8464cc88..343d77fde 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -39,6 +39,8 @@ #include "cairoint.h" +#include "cairo-region-private.h" + /* private functions */ static int @@ -51,6 +53,8 @@ _cairo_traps_init (cairo_traps_t *traps) traps->status = CAIRO_STATUS_SUCCESS; + traps->maybe_region = 1; + traps->num_traps = 0; traps->traps_size = ARRAY_LENGTH (traps->traps_embedded); @@ -83,6 +87,8 @@ _cairo_traps_clear (cairo_traps_t *traps) { traps->status = CAIRO_STATUS_SUCCESS; + traps->maybe_region = 1; + traps->num_traps = 0; traps->extents.p1.x = traps->extents.p1.y = INT32_MAX; traps->extents.p2.x = traps->extents.p2.y = INT32_MIN; @@ -616,14 +622,18 @@ _cairo_traps_extents (const cairo_traps_t *traps, * or %CAIRO_STATUS_NO_MEMORY **/ cairo_int_status_t -_cairo_traps_extract_region (const cairo_traps_t *traps, - cairo_region_t **region) +_cairo_traps_extract_region (cairo_traps_t *traps, + cairo_region_t **region) { cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; cairo_rectangle_int_t *rects = stack_rects; cairo_int_status_t status; int i, rect_count; + /* we only treat this a hint... */ + if (! traps->maybe_region) + return CAIRO_INT_STATUS_UNSUPPORTED; + for (i = 0; i < traps->num_traps; i++) { if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x || traps->traps[i].right.p1.x != traps->traps[i].right.p2.x || @@ -632,6 +642,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, ! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) || ! _cairo_fixed_is_integer (traps->traps[i].right.p1.x)) { + traps->maybe_region = FALSE; return CAIRO_INT_STATUS_UNSUPPORTED; } } @@ -655,7 +666,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, */ if (x1 == x2 || y1 == y2) continue; - + rects[rect_count].x = x1; rects[rect_count].y = y1; rects[rect_count].width = x2 - x1; @@ -663,18 +674,13 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, rect_count++; } - + *region = cairo_region_create_rectangles (rects, rect_count); - status = cairo_region_status (*region); + status = (*region)->status; if (rects != stack_rects) free (rects); - if (unlikely (status)) { - cairo_region_destroy (*region); - *region = NULL; - } - return status; } diff --git a/src/cairo-type3-glyph-surface-private.h b/src/cairo-type3-glyph-surface-private.h index 33314ae9e..0b0010bcc 100644 --- a/src/cairo-type3-glyph-surface-private.h +++ b/src/cairo-type3-glyph-surface-private.h @@ -42,6 +42,7 @@ #if CAIRO_HAS_FONT_SUBSET #include "cairo-surface-private.h" +#include "cairo-surface-clipper-private.h" #include "cairo-pdf-operators-private.h" typedef cairo_status_t (*cairo_type3_glyph_surface_emit_image_t) (cairo_image_surface_t *image, @@ -55,16 +56,18 @@ typedef struct cairo_type3_glyph_surface { cairo_pdf_operators_t pdf_operators; cairo_matrix_t cairo_to_pdf; cairo_type3_glyph_surface_emit_image_t emit_image; + + cairo_surface_clipper_t clipper; } cairo_type3_glyph_surface_t; cairo_private cairo_surface_t * -_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, +_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, cairo_output_stream_t *stream, cairo_type3_glyph_surface_emit_image_t emit_image, - cairo_scaled_font_subsets_t *font_subsets); + cairo_scaled_font_subsets_t *font_subsets); cairo_private void -_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface, +_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface, cairo_pdf_operators_use_font_subset_t use_font_subset, void *closure); diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index 6e7259609..f55b12ac8 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -42,9 +42,31 @@ #include "cairo-output-stream-private.h" #include "cairo-meta-surface-private.h" #include "cairo-analysis-surface-private.h" +#include "cairo-surface-clipper-private.h" static const cairo_surface_backend_t cairo_type3_glyph_surface_backend; +static cairo_status_t +_cairo_type3_glyph_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) +{ + cairo_type3_glyph_surface_t *surface = cairo_container_of (clipper, + cairo_type3_glyph_surface_t, + clipper); + + if (path == NULL) { + _cairo_output_stream_printf (surface->stream, "Q q\n"); + return CAIRO_STATUS_SUCCESS; + } + + return _cairo_pdf_operators_clip (&surface->pdf_operators, + path, + fill_rule); +} + cairo_surface_t * _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, cairo_output_stream_t *stream, @@ -81,6 +103,9 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, &surface->cairo_to_pdf, font_subsets); + _cairo_surface_clipper_init (&surface->clipper, + _cairo_type3_glyph_surface_clipper_intersect_clip_path); + return &surface->base; } @@ -155,30 +180,11 @@ _cairo_type3_glyph_surface_finish (void *abstract_surface) return _cairo_pdf_operators_fini (&surface->pdf_operators); } -static cairo_int_status_t -_cairo_type3_glyph_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - - if (path == NULL) { - _cairo_output_stream_printf (surface->stream, "Q q\n"); - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_pdf_operators_clip (&surface->pdf_operators, - path, - fill_rule); -} - static cairo_int_status_t _cairo_type3_glyph_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_type3_glyph_surface_t *surface = abstract_surface; const cairo_surface_pattern_t *pattern; @@ -189,8 +195,13 @@ _cairo_type3_glyph_surface_paint (void *abstract_surface, if (source->type != CAIRO_PATTERN_TYPE_SURFACE) return CAIRO_INT_STATUS_IMAGE_FALLBACK; + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + pattern = (const cairo_surface_pattern_t *) source; - status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra); + status = _cairo_surface_acquire_source_image (pattern->surface, + &image, &image_extra); if (unlikely (status)) goto fail; @@ -209,9 +220,11 @@ _cairo_type3_glyph_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { - return _cairo_type3_glyph_surface_paint (abstract_surface, op, mask, extents); + return _cairo_type3_glyph_surface_paint (abstract_surface, + op, mask, + clip); } static cairo_int_status_t @@ -224,9 +237,14 @@ _cairo_type3_glyph_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_type3_glyph_surface_t *surface = abstract_surface; + cairo_int_status_t status; + + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; return _cairo_pdf_operators_stroke (&surface->pdf_operators, path, @@ -243,16 +261,18 @@ _cairo_type3_glyph_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_type3_glyph_surface_t *surface = abstract_surface; cairo_int_status_t status; - status = _cairo_pdf_operators_fill (&surface->pdf_operators, - path, - fill_rule); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; - return status; + return _cairo_pdf_operators_fill (&surface->pdf_operators, + path, + fill_rule); } static cairo_int_status_t @@ -262,8 +282,8 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_type3_glyph_surface_t *surface = abstract_surface; cairo_int_status_t status; @@ -271,8 +291,14 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface, cairo_matrix_t new_ctm, ctm_inverse; int i; - for (i = 0; i < num_glyphs; i++) - cairo_matrix_transform_point (&surface->cairo_to_pdf, &glyphs[i].x, &glyphs[i].y); + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) + return status; + + for (i = 0; i < num_glyphs; i++) { + cairo_matrix_transform_point (&surface->cairo_to_pdf, + &glyphs[i].x, &glyphs[i].y); + } /* We require the matrix to be invertable. */ ctm_inverse = scaled_font->ctm; @@ -316,8 +342,6 @@ static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = { NULL, /* check_span_renderer */ NULL, /* cairo_type3_glyph_surface_copy_page */ NULL, /* _cairo_type3_glyph_surface_show_page */ - NULL, /* set_clip_region */ - _cairo_type3_glyph_surface_intersect_clip_path, NULL, /* _cairo_type3_glyph_surface_get_extents */ NULL, /* old_show_glyphs */ NULL, /* _cairo_type3_glyph_surface_get_font_options */ diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index 2ed3264b6..a68fe500b 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -41,6 +41,7 @@ #include "cairo.h" #include "cairo-fixed-type-private.h" +#include "cairo-list-private.h" #include "cairo-reference-count-private.h" typedef struct _cairo_array cairo_array_t; @@ -63,6 +64,7 @@ typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t; typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t; typedef struct _cairo_solid_pattern cairo_solid_pattern_t; typedef struct _cairo_surface_backend cairo_surface_backend_t; +typedef struct _cairo_surface_wrapper cairo_surface_wrapper_t; typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t; typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t; @@ -167,6 +169,7 @@ typedef enum _cairo_internal_surface_type { CAIRO_INTERNAL_SURFACE_TYPE_TEST_META, CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED, + CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING, CAIRO_INTERNAL_SURFACE_TYPE_NULL, CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH } cairo_internal_surface_type_t; @@ -237,12 +240,6 @@ typedef enum _cairo_direction { CAIRO_DIRECTION_REVERSE } cairo_direction_t; -typedef enum _cairo_clip_mode { - CAIRO_CLIP_MODE_PATH, - CAIRO_CLIP_MODE_REGION, - CAIRO_CLIP_MODE_MASK -} cairo_clip_mode_t; - typedef struct _cairo_edge { cairo_line_t edge; int dir; diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c index 1adfd7d64..42e8bae29 100644 --- a/src/cairo-user-font.c +++ b/src/cairo-user-font.c @@ -85,7 +85,7 @@ _cairo_user_scaled_font_create_meta_context (cairo_user_scaled_font_t *scaled_fo CAIRO_CONTENT_COLOR_ALPHA : CAIRO_CONTENT_ALPHA; - meta_surface = cairo_meta_surface_create (content, -1, -1); + meta_surface = cairo_meta_surface_create (content, NULL); cr = cairo_create (meta_surface); cairo_surface_destroy (meta_surface); @@ -114,11 +114,11 @@ _cairo_user_scaled_glyph_init (void *abstract_font, cr = _cairo_user_scaled_font_create_meta_context (scaled_font); - if (face->scaled_font_methods.render_glyph) + if (face->scaled_font_methods.render_glyph) { status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font, _cairo_scaled_glyph_index(scaled_glyph), cr, &extents); - else + } else status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; if (status == CAIRO_STATUS_SUCCESS) @@ -141,27 +141,16 @@ _cairo_user_scaled_glyph_init (void *abstract_font, /* set metrics */ if (extents.width == 0.) { - /* Compute extents.x/y/width/height from meta_surface, in font space */ - cairo_box_t bbox; double x1, y1, x2, y2; double x_scale, y_scale; - cairo_surface_t *null_surface; - cairo_surface_t *analysis_surface; - - null_surface = _cairo_null_surface_create (cairo_surface_get_content (meta_surface)); - analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1); - cairo_surface_destroy (null_surface); - status = analysis_surface->status; - if (unlikely (status)) - return status; - - _cairo_analysis_surface_set_ctm (analysis_surface, - &scaled_font->extent_scale); - status = cairo_meta_surface_replay (meta_surface, analysis_surface); - _cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox); - cairo_surface_destroy (analysis_surface); + /* Compute extents.x/y/width/height from meta_surface, + * in font space. + */ + status = _cairo_meta_surface_get_bbox ((cairo_meta_surface_t *) meta_surface, + &bbox, + &scaled_font->extent_scale); if (unlikely (status)) return status; @@ -231,7 +220,6 @@ _cairo_user_scaled_glyph_init (void *abstract_font, return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _cairo_meta_surface_get_path (meta_surface, path); - if (unlikely (status)) { _cairo_path_fixed_destroy (path); return status; diff --git a/src/cairo-vg-surface.c b/src/cairo-vg-surface.c index de3d0c6fb..232450d57 100644 --- a/src/cairo-vg-surface.c +++ b/src/cairo-vg-surface.c @@ -40,6 +40,7 @@ #include "cairo-path-fixed-private.h" #include "cairo-meta-surface-private.h" +#include "cairo-surface-clipper-private.h" #include "cairo-cache-private.h" #include @@ -94,7 +95,7 @@ struct _cairo_vg_surface { cairo_cache_entry_t snapshot_cache_entry; - cairo_bool_t clipped; + cairo_surface_clipper_t clipper; unsigned long target_id; }; @@ -397,21 +398,21 @@ _vg_surface_create_similar (void *abstract_surface, return cairo_vg_surface_create (surface->context, content, width, height); } -static cairo_int_status_t -_vg_surface_intersect_clip_path (void *abstract_surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) +static cairo_status_t +_vg_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias) { - cairo_vg_surface_t *surface = abstract_surface; + cairo_vg_surface_t *surface = cairo_container_of (clipper, + cairo_vg_surface_t, + clipper); cairo_vg_surface_t *mask; - cairo_rectangle_int_t extents, clip_extents; cairo_solid_pattern_t white; cairo_status_t status; if (path == NULL) { - surface->clipped = FALSE; vgMask (VG_INVALID_HANDLE, VG_FILL_MASK, 0, 0, surface->width, surface->height); vgSeti (VG_MASKING, VG_FALSE); @@ -419,16 +420,6 @@ _vg_surface_intersect_clip_path (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } - extents.x = extents.y = 0; - extents.width = surface->width; - extents.height = surface->height; - _cairo_path_fixed_approximate_clip_extents (path, &clip_extents); - if (! _cairo_rectangle_intersect (&clip_extents, &extents)) - surface->clipped = TRUE; - - if (surface->clipped) - return CAIRO_STATUS_SUCCESS; - mask = (cairo_vg_surface_t *) _vg_surface_create_similar (surface, CAIRO_CONTENT_ALPHA, surface->width, surface->height); @@ -456,7 +447,7 @@ _vg_surface_intersect_clip_path (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t +static cairo_bool_t _vg_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *extents) { @@ -467,7 +458,7 @@ _vg_surface_get_extents (void *abstract_surface, extents->width = surface->width; extents->height = surface->height; - return CAIRO_STATUS_SUCCESS; + return TRUE; } #define MAX_SEG 16 /* max number of knots to upload in a batch */ @@ -589,7 +580,7 @@ _vg_close_path (void *closure) static void _vg_path_from_cairo (vg_path_t *vg_path, - cairo_path_fixed_t *path) + const cairo_path_fixed_t *path) { cairo_status_t status; @@ -805,7 +796,7 @@ _vg_setup_linear_source (cairo_vg_context_t *context, static cairo_status_t _vg_setup_radial_source (cairo_vg_context_t *context, - cairo_radial_pattern_t *rpat) + const cairo_radial_pattern_t *rpat) { VGfloat radial[5]; @@ -832,7 +823,7 @@ _vg_setup_radial_source (cairo_vg_context_t *context, static cairo_status_t _vg_setup_solid_source (cairo_vg_context_t *context, - cairo_solid_pattern_t *spat) + const cairo_solid_pattern_t *spat) { VGfloat color[] = { spat->color.red, @@ -960,7 +951,7 @@ _vg_surface_remove_from_cache (cairo_surface_t *abstract_surface) static cairo_status_t _vg_setup_surface_source (cairo_vg_context_t *context, - cairo_surface_pattern_t *spat) + const cairo_surface_pattern_t *spat) { cairo_surface_t *snapshot; cairo_vg_surface_t *clone; @@ -1077,7 +1068,7 @@ _vg_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_vg_surface_t *surface = abstract_surface; cairo_vg_context_t *context; @@ -1086,9 +1077,6 @@ _vg_surface_stroke (void *abstract_surface, VGfloat strokeTransform[9]; vg_path_t vg_path; - if (surface->clipped) - return CAIRO_STATUS_SUCCESS; - if (! _vg_is_supported_operator (op)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1105,6 +1093,12 @@ _vg_surface_stroke (void *abstract_surface, return status; } + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) { + _vg_context_unlock (context); + return status; + } + vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, @@ -1148,16 +1142,13 @@ _vg_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_vg_surface_t *surface = abstract_surface; cairo_vg_context_t *context; cairo_status_t status; vg_path_t vg_path; - if (surface->clipped) - return CAIRO_STATUS_SUCCESS; - if (op == CAIRO_OPERATOR_DEST) return CAIRO_STATUS_SUCCESS; @@ -1177,6 +1168,12 @@ _vg_surface_fill (void *abstract_surface, return status; } + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) { + _vg_context_unlock (context); + return status; + } + vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, @@ -1208,15 +1205,12 @@ static cairo_int_status_t _vg_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_vg_surface_t *surface = abstract_surface; cairo_vg_context_t *context; cairo_status_t status; - if (surface->clipped) - return CAIRO_STATUS_SUCCESS; - if (op == CAIRO_OPERATOR_DEST) return CAIRO_STATUS_SUCCESS; @@ -1236,6 +1230,12 @@ _vg_surface_paint (void *abstract_surface, return status; } + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (unlikely (status)) { + _vg_context_unlock (context); + return status; + } + vgSeti (VG_BLEND_MODE, _vg_operator (op)); vgSetPaint (context->paint, VG_FILL_PATH); @@ -1273,14 +1273,11 @@ _vg_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_vg_surface_t *surface = abstract_surface; cairo_status_t status; - if (surface->clipped) - return CAIRO_STATUS_SUCCESS; - if (! _vg_is_supported_operator (op)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1291,7 +1288,7 @@ _vg_surface_mask (void *abstract_surface, double alpha = context->alpha; context->alpha = solid->color.alpha; - status = _vg_surface_paint (abstract_surface, op, source, extents); + status = _vg_surface_paint (abstract_surface, op, source, clip); context->alpha = alpha; _vg_context_unlock (context); @@ -1312,14 +1309,14 @@ _vg_surface_get_font_options (void *abstract_surface, } static cairo_int_status_t -_vg_surface_show_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) +_vg_surface_show_glyphs (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_scaled_font_t *scaled_font, + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_path_fixed_t path; @@ -1342,7 +1339,7 @@ _vg_surface_show_glyphs (void *abstract_surface, CAIRO_FILL_RULE_WINDING, CAIRO_GSTATE_TOLERANCE_DEFAULT, CAIRO_ANTIALIAS_SUBPIXEL, - extents); + clip); BAIL: _cairo_path_fixed_fini (&path); return status; @@ -1510,12 +1507,6 @@ _vg_surface_release_dest_image (void *abstract_surface, cairo_vg_surface_t *surface = abstract_surface; cairo_bool_t needs_unpremultiply; - /* XXX clipping is incorrect - * We can either composite through the current clip mask using fill, - * or what for the clipping overhaul patches, due to land any time - * soon now... - */ - _vg_format_to_pixman (surface->format, &needs_unpremultiply); if (needs_unpremultiply) { unpremultiply_argb (image->data, @@ -1545,6 +1536,8 @@ _vg_surface_finish (void *abstract_surface) surface->snapshot_cache_entry.hash = 0; } + _cairo_surface_clipper_reset (&surface->clipper); + if (surface->own_image) vgDestroyImage (surface->image); @@ -1561,20 +1554,21 @@ static const cairo_surface_backend_t cairo_vg_surface_backend = { CAIRO_SURFACE_TYPE_VG, _vg_surface_create_similar, _vg_surface_finish, + _vg_surface_acquire_source_image, _vg_surface_release_source_image, _vg_surface_acquire_dest_image, _vg_surface_release_dest_image, + NULL, /* clone_similar */ NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ NULL, /* create_span_renderer */ NULL, /* check_span_renderer */ + NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - _vg_surface_intersect_clip_path, _vg_surface_get_extents, NULL, /* old_show_glyphs */ _vg_surface_get_font_options, /* get_font_options */ @@ -1591,7 +1585,6 @@ static const cairo_surface_backend_t cairo_vg_surface_backend = { NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ }; static cairo_surface_t * @@ -1617,15 +1610,14 @@ _vg_surface_create_internal (cairo_vg_context_t *context, surface->width = width; surface->height = height; - surface->clipped = FALSE; + + _cairo_surface_clipper_init (&surface->clipper, + _vg_surface_clipper_intersect_clip_path); surface->snapshot_cache_entry.hash = 0; surface->target_id = 0; - /* Force an initial "clip", that resets the mask */ - _vg_surface_intersect_clip_path (surface, NULL, 0, 0.0, 0); - CHECK_VG_ERRORS(); return &surface->base; } diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index e62e88169..2f1127c2c 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -1360,6 +1360,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font, unsigned int height, cairo_glyph_t *glyphs, int num_glyphs, + cairo_region_t *clip_region, int *remaining_glyphs) { cairo_win32_scaled_font_t *scaled_font = abstract_font; @@ -1381,15 +1382,17 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font, */ COLORREF new_color; + status = _cairo_win32_surface_set_clip_region (surface, clip_region); + if (unlikely (status)) + return status; + new_color = RGB (((int)solid_pattern->color.red_short) >> 8, ((int)solid_pattern->color.green_short) >> 8, ((int)solid_pattern->color.blue_short) >> 8); - status = _draw_glyphs_on_surface (surface, scaled_font, new_color, - 0, 0, - glyphs, num_glyphs); - - return status; + return _draw_glyphs_on_surface (surface, scaled_font, new_color, + 0, 0, + glyphs, num_glyphs); } else { /* Otherwise, we need to draw using software fallbacks. We create a mask * surface by drawing the the glyphs onto a DIB, black-on-white then @@ -1458,7 +1461,8 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font, source_x, source_y, 0, 0, dest_x, dest_y, - width, height); + width, height, + clip_region); _cairo_pattern_fini (&mask.base); diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c index 9025bfa7b..17a7b39c0 100644 --- a/src/cairo-win32-printing-surface.c +++ b/src/cairo-win32-printing-surface.c @@ -53,6 +53,7 @@ #include "cairo-meta-surface-private.h" #include "cairo-scaled-font-subsets-private.h" #include "cairo-image-info-private.h" +#include "cairo-surface-clipper-private.h" #include @@ -128,7 +129,7 @@ analyze_surface_pattern_transparency (cairo_surface_pattern_t *pattern) cairo_image_surface_t *image; void *image_extra; cairo_int_status_t status; - int x, y; + cairo_image_transparency_t transparency; status = _cairo_surface_acquire_source_image (pattern->surface, &image, @@ -136,38 +137,20 @@ analyze_surface_pattern_transparency (cairo_surface_pattern_t *pattern) if (status) return status; - if (image->base.status) - return image->base.status; - - if (image->format == CAIRO_FORMAT_RGB24) { + transparency = _cairo_image_analyze_transparency (image); + switch (transparency) { + case CAIRO_IMAGE_UNKNOWN: + ASSERT_NOT_REACHED; + case CAIRO_IMAGE_IS_OPAQUE: status = CAIRO_STATUS_SUCCESS; - goto RELEASE_SOURCE; - } + break; - if (image->format != CAIRO_FORMAT_ARGB32) { - /* If the surface does not support the image format, assume - * that it does have alpha. The image will be converted to - * rgb24 when the surface blends the image into the page - * color to remove the transparency. */ + case CAIRO_IMAGE_HAS_BILEVEL_ALPHA: + case CAIRO_IMAGE_HAS_ALPHA: status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - goto RELEASE_SOURCE; + break; } - for (y = 0; y < image->height; y++) { - int a; - uint32_t *pixel = (uint32_t *) (image->data + y * image->stride); - - for (x = 0; x < image->width; x++, pixel++) { - a = (*pixel & 0xff000000) >> 24; - if (a != 255) { - status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - goto RELEASE_SOURCE; - } - } - } - status = CAIRO_STATUS_SUCCESS; - -RELEASE_SOURCE: _cairo_surface_release_source_image (pattern->surface, image, image_extra); return status; @@ -176,8 +159,6 @@ RELEASE_SOURCE: static cairo_bool_t surface_pattern_supported (const cairo_surface_pattern_t *pattern) { - cairo_extend_t extend; - if (_cairo_surface_is_meta (pattern->surface)) return TRUE; @@ -187,19 +168,7 @@ surface_pattern_supported (const cairo_surface_pattern_t *pattern) return FALSE; } - extend = cairo_pattern_get_extend ((cairo_pattern_t*)&pattern->base); - switch (extend) { - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_REPEAT: - case CAIRO_EXTEND_REFLECT: - /* There's no point returning FALSE for EXTEND_PAD, as the image - * surface does not currently implement it either */ - case CAIRO_EXTEND_PAD: - return TRUE; - } - - ASSERT_NOT_REACHED; - return FALSE; + return TRUE; } static cairo_bool_t @@ -390,7 +359,8 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa XFORM xform; int x_tile, y_tile, left, right, top, bottom; RECT clip; - cairo_surface_t *meta_surface = pattern->surface; + cairo_meta_surface_t *meta_surface = (cairo_meta_surface_t *) pattern->surface; + cairo_box_t bbox; extend = cairo_pattern_get_extend (&pattern->base); @@ -406,7 +376,7 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa SaveDC (surface->dc); _cairo_matrix_to_win32_xform (&p2d, &xform); - status = _cairo_surface_get_extents (meta_surface, &meta_extents); + status = _cairo_meta_surface_get_bbox (meta_surface, &bbox, NULL); if (status) return status; @@ -415,10 +385,10 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa return status; if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) { - left = (int) floor((double)clip.left/meta_extents.width); - right = (int) ceil((double)clip.right/meta_extents.width); - top = (int) floor((double)clip.top/meta_extents.height); - bottom = (int) ceil((double)clip.bottom/meta_extents.height); + left = (int) floor (clip.left / _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x)); + right = (int) ceil (clip.right / _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x)); + top = (int) floor (clip.top / _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y)); + bottom = (int) ceil (clip.bottom / _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y)); } else { left = 0; right = 1; @@ -427,7 +397,7 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa } old_content = surface->content; - if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) { + if (meta_surface->base.content == CAIRO_CONTENT_COLOR) { cairo_pattern_t *source; cairo_solid_pattern_t black; @@ -490,7 +460,8 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa SelectClipPath (surface->dc, RGN_AND); SaveDC (surface->dc); /* Allow clip path to be reset during replay */ - status = _cairo_meta_surface_replay_region (meta_surface, &surface->base, + status = _cairo_meta_surface_replay_region (&meta_surface->base, + &surface->base, CAIRO_META_REGION_NATIVE); assert (status != CAIRO_INT_STATUS_UNSUPPORTED); /* Restore both the clip save and our earlier path SaveDC */ @@ -594,7 +565,6 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf cairo_extend_t extend; cairo_image_surface_t *image; void *image_extra; - cairo_surface_t *opaque_surface; cairo_image_surface_t *opaque_image = NULL; BITMAPINFO bi; cairo_matrix_t m; @@ -651,13 +621,15 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf &mime_size, &mime_info); } - if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) + if (_cairo_status_is_error (status)) return status; use_mime = (status == CAIRO_STATUS_SUCCESS); if (!use_mime && image->format != CAIRO_FORMAT_RGB24) { - cairo_surface_pattern_t opaque_pattern; + cairo_surface_t *opaque_surface; + cairo_surface_pattern_t image_pattern; + cairo_solid_pattern_t background_pattern; opaque_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, image->width, @@ -667,36 +639,27 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf goto CLEANUP_OPAQUE_IMAGE; } - _cairo_pattern_init_for_surface (&opaque_pattern, &image->base); - - status = _cairo_surface_fill_rectangle (opaque_surface, - CAIRO_OPERATOR_SOURCE, - background_color, - 0, 0, - image->width, image->height); - if (status) { - _cairo_pattern_fini (&opaque_pattern.base); + _cairo_pattern_init_solid (&background_pattern, + background_color, + CAIRO_CONTENT_COLOR); + status = _cairo_surface_paint (opaque_surface, + CAIRO_OPERATOR_SOURCE, + &background_pattern.base, + NULL); + if (status) goto CLEANUP_OPAQUE_IMAGE; - } - status = _cairo_surface_composite (CAIRO_OPERATOR_OVER, - &opaque_pattern.base, - NULL, - opaque_surface, - 0, 0, - 0, 0, - 0, 0, - image->width, - image->height); - if (status) { - _cairo_pattern_fini (&opaque_pattern.base); + _cairo_pattern_init_for_surface (&image_pattern, &image->base); + status = _cairo_surface_paint (opaque_surface, + CAIRO_OPERATOR_OVER, + &image_pattern.base, + NULL); + _cairo_pattern_fini (&image_pattern.base); + if (status) goto CLEANUP_OPAQUE_IMAGE; - } - _cairo_pattern_fini (&opaque_pattern.base); opaque_image = (cairo_image_surface_t *) opaque_surface; } else { - opaque_surface = &image->base; opaque_image = image; } @@ -767,7 +730,7 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf CLEANUP_OPAQUE_IMAGE: if (opaque_image != image) - cairo_surface_destroy (opaque_surface); + cairo_surface_destroy (&opaque_image->base); CLEANUP_IMAGE: _cairo_surface_release_source_image (pattern->surface, image, image_extra); @@ -1085,17 +1048,15 @@ _cairo_win32_printing_surface_emit_path (cairo_win32_surface_t *surface, cairo_path_fixed_t *path) { win32_path_info_t path_info; - cairo_status_t status; path_info.surface = surface; - status = _cairo_path_fixed_interpret (path, - CAIRO_DIRECTION_FORWARD, - _cairo_win32_printing_surface_path_move_to, - _cairo_win32_printing_surface_path_line_to, - _cairo_win32_printing_surface_path_curve_to, - _cairo_win32_printing_surface_path_close_path, - &path_info); - return status; + return _cairo_path_fixed_interpret (path, + CAIRO_DIRECTION_FORWARD, + _cairo_win32_printing_surface_path_move_to, + _cairo_win32_printing_surface_path_line_to, + _cairo_win32_printing_surface_path_curve_to, + _cairo_win32_printing_surface_path_close_path, + &path_info); } static cairo_int_status_t @@ -1109,14 +1070,16 @@ _cairo_win32_printing_surface_show_page (void *abstract_surface) return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface, +static cairo_status_t +_cairo_win32_printing_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias) { - cairo_win32_surface_t *surface = abstract_surface; + cairo_win32_surface_t *surface = cairo_container_of (clipper, + cairo_win32_surface_t, + clipper); cairo_status_t status; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) @@ -1164,10 +1127,15 @@ static cairo_int_status_t _cairo_win32_printing_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_win32_surface_t *surface = abstract_surface; cairo_solid_pattern_t clear; + cairo_status_t status; + + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (status) + return status; if (op == CAIRO_OPERATOR_CLEAR) { _cairo_win32_printing_surface_init_clear_color (surface, &clear); @@ -1242,7 +1210,7 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, cairo_matrix_t *stroke_ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_win32_surface_t *surface = abstract_surface; cairo_int_status_t status; @@ -1258,6 +1226,10 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, cairo_matrix_t mat; double scale; + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (status) + return status; + if (op == CAIRO_OPERATOR_CLEAR) { _cairo_win32_printing_surface_init_clear_color (surface, &clear); source = (cairo_pattern_t*) &clear; @@ -1364,12 +1336,16 @@ _cairo_win32_printing_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { cairo_win32_surface_t *surface = abstract_surface; cairo_int_status_t status; cairo_solid_pattern_t clear; + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (status) + return status; + if (op == CAIRO_OPERATOR_CLEAR) { _cairo_win32_printing_surface_init_clear_color (surface, &clear); source = (cairo_pattern_t*) &clear; @@ -1423,8 +1399,8 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_win32_surface_t *surface = abstract_surface; cairo_status_t status = CAIRO_STATUS_SUCCESS; @@ -1435,6 +1411,10 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac cairo_bool_t old_has_ctm; cairo_solid_pattern_t clear; + status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); + if (status) + return status; + if (op == CAIRO_OPERATOR_CLEAR) { _cairo_win32_printing_surface_init_clear_color (surface, &clear); source = (cairo_pattern_t*) &clear; @@ -1547,8 +1527,8 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac status = _cairo_win32_surface_show_glyphs (surface, op, source, glyphs, num_glyphs, scaled_font, - remaining_glyphs, - extents); + clip, + remaining_glyphs); if (surface->has_ctm) cairo_scaled_font_destroy (scaled_font); @@ -1607,7 +1587,12 @@ _cairo_win32_printing_surface_create_similar (void *abstract_surface, int width, int height) { - return cairo_meta_surface_create (content, width, height); + cairo_rectangle_t extents; + + extents.x = extents.y = 0; + extents.width = width; + extents.height = height; + return cairo_meta_surface_create (content, &extents); } static cairo_int_status_t @@ -1698,6 +1683,9 @@ cairo_win32_printing_surface_create (HDC hdc) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); } + _cairo_surface_clipper_init (&surface->clipper, + _cairo_win32_printing_surface_clipper_intersect_clip_path); + surface->image = NULL; surface->format = CAIRO_FORMAT_RGB24; surface->content = CAIRO_CONTENT_COLOR_ALPHA; @@ -1725,13 +1713,12 @@ cairo_win32_printing_surface_create (HDC hdc) _cairo_win32_printing_surface_init_ps_mode (surface); _cairo_win32_printing_surface_init_image_support (surface); - _cairo_surface_init (&surface->base, &cairo_win32_printing_surface_backend, + _cairo_surface_init (&surface->base, + &cairo_win32_printing_surface_backend, CAIRO_CONTENT_COLOR_ALPHA); paginated = _cairo_paginated_surface_create (&surface->base, CAIRO_CONTENT_COLOR_ALPHA, - surface->extents.width, - surface->extents.height, &cairo_win32_surface_paginated_backend); /* paginated keeps the only reference to surface now, drop ours */ @@ -1762,8 +1749,6 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ _cairo_win32_printing_surface_show_page, - NULL, /* set_clip_region */ - _cairo_win32_printing_surface_intersect_clip_path, _cairo_win32_surface_get_extents, NULL, /* old_show_glyphs */ _cairo_win32_printing_surface_get_font_options, @@ -1779,7 +1764,6 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = { _cairo_win32_printing_surface_show_glyphs, NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ }; diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h index 40ed20efb..c1040e836 100644 --- a/src/cairo-win32-private.h +++ b/src/cairo-win32-private.h @@ -38,6 +38,7 @@ #include "cairo-win32.h" #include "cairoint.h" +#include "cairo-surface-clipper-private.h" #ifndef SHADEBLENDCAPS #define SHADEBLENDCAPS 120 @@ -81,6 +82,10 @@ typedef struct _cairo_win32_surface { cairo_rectangle_int_t clip_rect; HRGN initial_clip_rgn; cairo_bool_t had_simple_clip; + cairo_region_t *clip_region; + + /* For path clipping to the printing-surface */ + cairo_surface_clipper_t clipper; /* Surface DC flags */ uint32_t flags; @@ -137,13 +142,17 @@ _cairo_surface_is_win32_printing (cairo_surface_t *surface); cairo_status_t _cairo_win32_surface_finish (void *abstract_surface); -cairo_int_status_t +cairo_bool_t _cairo_win32_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle); uint32_t _cairo_win32_flags_for_dc (HDC dc); +cairo_status_t +_cairo_win32_surface_set_clip_region (void *abstract_surface, + cairo_region_t *region); + cairo_int_status_t _cairo_win32_surface_show_glyphs (void *surface, cairo_operator_t op, @@ -151,8 +160,8 @@ _cairo_win32_surface_show_glyphs (void *surface, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip, + int *remaining_glyphs); cairo_surface_t * _cairo_win32_surface_create_similar (void *abstract_src, diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index 5bbc8f866..12219e953 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -468,7 +468,8 @@ _cairo_win32_surface_clone_similar (void *abstract_surface, src_x, src_y, 0, 0, 0, 0, - width, height); + width, height, + NULL); _cairo_pattern_fini (&pattern.base); @@ -693,6 +694,91 @@ _cairo_win32_surface_release_dest_image (void *abstract_surfa cairo_surface_destroy ((cairo_surface_t *)local); } +cairo_status_t +_cairo_win32_surface_set_clip_region (void *abstract_surface, + cairo_region_t *region) +{ + cairo_win32_surface_t *surface = abstract_surface; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + + if (surface->clip_region == region) + return CAIRO_STATUS_SUCCESS; + + cairo_region_destroy (surface->clip_region); + surface->clip_region = cairo_region_reference (region); + + /* The semantics we want is that any clip set by cairo combines + * is intersected with the clip on device context that the + * surface was created for. To implement this, we need to + * save the original clip when first setting a clip on surface. + */ + + /* Clear any clip set by cairo, return to the original first */ + status = _cairo_win32_restore_initial_clip (surface); + + /* Then combine any new region with it */ + if (region) { + cairo_rectangle_int_t extents; + int num_rects; + RGNDATA *data; + size_t data_size; + RECT *rects; + int i; + HRGN gdi_region; + + /* Create a GDI region for the cairo region */ + + cairo_region_get_extents (region, &extents); + num_rects = cairo_region_num_rectangles (region); + /* XXX see notes in _cairo_win32_save_initial_clip -- + * this code will interact badly with a HDC which had an initial + * world transform -- we should probably manually transform the + * region rects, because SelectClipRgn takes device units, not + * logical units (unlike IntersectClipRect). + */ + + data_size = sizeof (RGNDATAHEADER) + num_rects * sizeof (RECT); + data = malloc (data_size); + if (!data) + return _cairo_error(CAIRO_STATUS_NO_MEMORY); + rects = (RECT *)data->Buffer; + + data->rdh.dwSize = sizeof (RGNDATAHEADER); + data->rdh.iType = RDH_RECTANGLES; + data->rdh.nCount = num_rects; + data->rdh.nRgnSize = num_rects * sizeof (RECT); + data->rdh.rcBound.left = extents.x; + data->rdh.rcBound.top = extents.y; + data->rdh.rcBound.right = extents.x + extents.width; + data->rdh.rcBound.bottom = extents.y + extents.height; + + for (i = 0; i < num_rects; i++) { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (region, i, &rect); + + rects[i].left = rect.x; + rects[i].top = rect.y; + rects[i].right = rect.x + rect.width; + rects[i].bottom = rect.y + rect.height; + } + + gdi_region = ExtCreateRegion (NULL, data_size, data); + free (data); + + if (!gdi_region) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + /* AND the new region into our DC */ + if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR) + status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region"); + + DeleteObject (gdi_region); + } + + return status; +} + #if !defined(AC_SRC_OVER) #define AC_SRC_OVER 0x00 #pragma pack(1) @@ -889,7 +975,8 @@ _cairo_win32_surface_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_win32_surface_t *dst = abstract_dst; cairo_win32_surface_t *src; @@ -1030,7 +1117,7 @@ _cairo_win32_surface_composite (cairo_operator_t op, fflush (stderr); #endif - /* If the src recangle doesn't wholly lie within the src extents, + /* If the src rectangle doesn't wholly lie within the src extents, * fudge things. We really need to do fixup on the unpainted * region -- e.g. the SOURCE operator is broken for areas outside * of the extents, because it won't clear that area to transparent @@ -1150,6 +1237,10 @@ _cairo_win32_surface_composite (cairo_operator_t op, fflush (stderr); #endif + status = _cairo_win32_surface_set_clip_region (dst, clip_region); + if (status) + return status; + /* If we need to repeat, we turn the repeated blit into * a bunch of piece-by-piece blits. */ @@ -1283,7 +1374,8 @@ UNSUPPORTED: src_x, src_y, mask_x, mask_y, dst_x, dst_y, - width, height); + width, height, + clip_region); } return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1387,6 +1479,10 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface, if (surface->format != CAIRO_FORMAT_RGB24) return CAIRO_INT_STATUS_UNSUPPORTED; + status = _cairo_win32_surface_set_clip_region (surface, NULL); + if (status) + return status; + /* Optimize for no destination alpha (surface->pixman_image is non-NULL for all * surfaces with alpha.) */ @@ -1432,133 +1528,20 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface, return status; } -static cairo_int_status_t -_cairo_win32_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - cairo_win32_surface_t *surface = abstract_surface; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - /* If we are in-memory, then we set the clip on the image surface - * as well as on the underlying GDI surface. - */ - if (surface->image) { - unsigned int serial; - - serial = _cairo_surface_allocate_clip_serial (surface->image); - status = _cairo_surface_set_clip_region (surface->image, region, serial); - if (status) - return status; - } - - /* The semantics we want is that any clip set by cairo combines - * is intersected with the clip on device context that the - * surface was created for. To implement this, we need to - * save the original clip when first setting a clip on surface. - */ - - /* Clear any clip set by cairo, return to the original first */ - status = _cairo_win32_restore_initial_clip (surface); - - /* Then combine any new region with it */ - if (region) { - cairo_rectangle_int_t extents; - int num_rects; - RGNDATA *data; - size_t data_size; - RECT *rects; - int i; - HRGN gdi_region; - cairo_rectangle_int_t rect0; - - /* Create a GDI region for the cairo region */ - - cairo_region_get_extents (region, &extents); - num_rects = cairo_region_num_rectangles (region); - - if (num_rects == 1) - cairo_region_get_rectangle (region, 0, &rect0); - - if (num_rects == 1 && - rect0.x == 0 && - rect0.y == 0 && - rect0.width == surface->extents.width && - rect0.width == surface->extents.height) - { - gdi_region = NULL; - - SelectClipRgn (surface->dc, NULL); - IntersectClipRect (surface->dc, - rect0.x, - rect0.y, - rect0.x + rect0.width, - rect0.y + rect0.height); - } else { - /* XXX see notes in _cairo_win32_save_initial_clip -- - * this code will interact badly with a HDC which had an initial - * world transform -- we should probably manually transform the - * region rects, because SelectClipRgn takes device units, not - * logical units (unlike IntersectClipRect). - */ - - data_size = sizeof (RGNDATAHEADER) + num_rects * sizeof (RECT); - data = malloc (data_size); - if (!data) - return _cairo_error(CAIRO_STATUS_NO_MEMORY); - rects = (RECT *)data->Buffer; - - data->rdh.dwSize = sizeof (RGNDATAHEADER); - data->rdh.iType = RDH_RECTANGLES; - data->rdh.nCount = num_rects; - data->rdh.nRgnSize = num_rects * sizeof (RECT); - data->rdh.rcBound.left = extents.x; - data->rdh.rcBound.top = extents.y; - data->rdh.rcBound.right = extents.x + extents.width; - data->rdh.rcBound.bottom = extents.y + extents.height; - - for (i = 0; i < num_rects; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - - rects[i].left = rect.x; - rects[i].top = rect.y; - rects[i].right = rect.x + rect.width; - rects[i].bottom = rect.y + rect.height; - } - - gdi_region = ExtCreateRegion (NULL, data_size, data); - free (data); - - if (!gdi_region) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* AND the new region into our DC */ - if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR) - status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region"); - - DeleteObject (gdi_region); - } - } - - return status; -} - -cairo_int_status_t +cairo_bool_t _cairo_win32_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { cairo_win32_surface_t *surface = abstract_surface; *rectangle = surface->extents; - - return CAIRO_STATUS_SUCCESS; + return TRUE; } static cairo_status_t _cairo_win32_surface_flush (void *abstract_surface) { - return _cairo_surface_reset_clip (abstract_surface); + return _cairo_win32_surface_set_clip_region (abstract_surface, NULL); } #define STACK_GLYPH_SIZE 256 @@ -1570,8 +1553,8 @@ _cairo_win32_surface_show_glyphs (void *surface, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { #if CAIRO_HAS_WIN32_FONT cairo_win32_surface_t *dst = surface; @@ -1611,11 +1594,19 @@ _cairo_win32_surface_show_glyphs (void *surface, /* If we have a fallback mask clip set on the dst, we have * to go through the fallback path, but only if we're not * doing this for printing */ - if (dst->base.clip && - !(dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) && - (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION || - dst->base.clip->surface != NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (clip != NULL) { + if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) == 0) { + cairo_region_t *clip_region; + cairo_status_t status; + + status = _cairo_clip_get_region (clip, &clip_region); + assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO); + if (status) + return status; + + _cairo_win32_surface_set_clip_region (surface, clip_region); + } + } solid_pattern = (cairo_solid_pattern_t *)source; color = RGB(((int)solid_pattern->color.red_short) >> 8, @@ -1957,19 +1948,6 @@ _cairo_win32_surface_is_similar (void *surface_a, return a->dc == b->dc; } -static cairo_status_t -_cairo_win32_surface_reset (void *abstract_surface) -{ - cairo_win32_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_win32_surface_set_clip_region (surface, NULL); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; -} - typedef struct _cairo_win32_surface_span_renderer { cairo_span_renderer_t base; @@ -1979,6 +1957,7 @@ typedef struct _cairo_win32_surface_span_renderer { cairo_image_surface_t *mask; cairo_win32_surface_t *dst; + cairo_region_t *clip_region; cairo_composite_rectangles_t composite_rectangles; } cairo_win32_surface_span_renderer_t; @@ -2031,18 +2010,20 @@ _cairo_win32_surface_span_renderer_finish (void *abstract_renderer) rects->src.y, 0, 0, /* mask.x, mask.y */ rects->dst.x, rects->dst.y, - rects->width, rects->height); + rects->width, rects->height, + renderer->clip_region); } else { /* otherwise go through the fallback_composite path which * will do the appropriate surface acquisition */ status = _cairo_surface_fallback_composite ( renderer->op, - renderer->pattern, mask_pattern, dst, + renderer->pattern, mask_pattern, &dst->base, rects->src.x, rects->src.y, 0, 0, /* mask.x, mask.y */ rects->dst.x, rects->dst.y, - rects->width, rects->height); + rects->width, rects->height, + renderer->clip_region); } cairo_pattern_destroy (mask_pattern); @@ -2073,15 +2054,16 @@ _cairo_win32_surface_create_span_renderer (cairo_operator_t op, const cairo_pattern_t *pattern, void *abstract_dst, cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects) + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region) { cairo_win32_surface_t *dst = abstract_dst; - cairo_win32_surface_span_renderer_t *renderer - = calloc(1, sizeof(*renderer)); + cairo_win32_surface_span_renderer_t *renderer; cairo_status_t status; int width = rects->width; int height = rects->height; + renderer = calloc(1, sizeof(*renderer)); if (renderer == NULL) return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); @@ -2093,6 +2075,7 @@ _cairo_win32_surface_create_span_renderer (cairo_operator_t op, renderer->pattern = pattern; renderer->antialias = antialias; renderer->dst = dst; + renderer->clip_region = clip_region; renderer->composite_rectangles = *rects; @@ -2128,8 +2111,6 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = { _cairo_win32_surface_check_span_renderer, NULL, /* copy_page */ NULL, /* show_page */ - _cairo_win32_surface_set_clip_region, - NULL, /* intersect_clip_path */ _cairo_win32_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -2146,8 +2127,6 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = { NULL, /* snapshot */ _cairo_win32_surface_is_similar, - - _cairo_win32_surface_reset }; /* Notes: diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index a7340cf94..0650f8f67 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -75,6 +75,7 @@ typedef struct cairo_xcb_surface { cairo_bool_t have_clip_rects; xcb_rectangle_t *clip_rects; int num_clip_rects; + cairo_region_t *clip_region; xcb_render_picture_t src_picture, dst_picture; xcb_render_pictforminfo_t xrender_format; @@ -166,6 +167,93 @@ _xcb_render_format_to_content (xcb_render_pictforminfo_t *xrender_format) return CAIRO_CONTENT_COLOR; } +static void +_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface) +{ + if (surface->have_clip_rects) + xcb_set_clip_rectangles(surface->dpy, XCB_CLIP_ORDERING_YX_SORTED, surface->gc, + 0, 0, + surface->num_clip_rects, + surface->clip_rects ); +} + +static void +_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface) +{ + if (surface->have_clip_rects) + xcb_render_set_picture_clip_rectangles (surface->dpy, surface->dst_picture, + 0, 0, + surface->num_clip_rects, + surface->clip_rects); +} + +static cairo_status_t +_cairo_xcb_surface_set_clip_region (void *abstract_surface, + cairo_region_t *region) +{ + cairo_xcb_surface_t *surface = abstract_surface; + + if (region == surface->clip_region) + return CAIRO_STATUS_SUCCESS; + + cairo_region_destroy (surface->clip_region); + region = cairo_region_reference (region); + + if (surface->clip_rects) { + free (surface->clip_rects); + surface->clip_rects = NULL; + } + + surface->have_clip_rects = FALSE; + surface->num_clip_rects = 0; + + if (region == NULL) { + uint32_t none[] = { XCB_NONE }; + if (surface->gc) + xcb_change_gc (surface->dpy, surface->gc, XCB_GC_CLIP_MASK, none); + + if (surface->xrender_format.id != XCB_NONE && surface->dst_picture) + xcb_render_change_picture (surface->dpy, surface->dst_picture, + XCB_RENDER_CP_CLIP_MASK, none); + } else { + xcb_rectangle_t *rects = NULL; + int n_rects, i; + + n_rects = cairo_region_num_rectangles (region); + + if (n_rects > 0) { + rects = _cairo_malloc_ab (n_rects, sizeof(xcb_rectangle_t)); + if (rects == NULL) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } else { + rects = NULL; + } + + for (i = 0; i < n_rects; i++) { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (region, i, &rect); + + rects[i].x = rect.x; + rects[i].y = rect.y; + rects[i].width = rect.width; + rects[i].height = rect.height; + } + + surface->have_clip_rects = TRUE; + surface->clip_rects = rects; + surface->num_clip_rects = n_rects; + + if (surface->gc) + _cairo_xcb_surface_set_gc_clip_rects (surface); + + if (surface->dst_picture) + _cairo_xcb_surface_set_picture_clip_rects (surface); + } + + return CAIRO_STATUS_SUCCESS; +} + static cairo_surface_t * _cairo_xcb_surface_create_similar (void *abstract_src, cairo_content_t content, @@ -223,6 +311,7 @@ _cairo_xcb_surface_finish (void *abstract_surface) xcb_free_gc (surface->dpy, surface->gc); free (surface->clip_rects); + cairo_region_destroy (surface->clip_region); surface->dpy = NULL; @@ -475,26 +564,6 @@ _cairo_xcb_surface_ensure_src_picture (cairo_xcb_surface_t *surface) } } -static void -_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface) -{ - if (surface->have_clip_rects) - xcb_render_set_picture_clip_rectangles (surface->dpy, surface->dst_picture, - 0, 0, - surface->num_clip_rects, - surface->clip_rects); -} - -static void -_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface) -{ - if (surface->have_clip_rects) - xcb_set_clip_rectangles(surface->dpy, XCB_CLIP_ORDERING_YX_SORTED, surface->gc, - 0, 0, - surface->num_clip_rects, - surface->clip_rects ); -} - static void _cairo_xcb_surface_ensure_dst_picture (cairo_xcb_surface_t *surface) { @@ -1124,7 +1193,8 @@ _cairo_xcb_surface_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_surface_attributes_t src_attr, mask_attr; cairo_xcb_surface_t *dst = abstract_dst; @@ -1163,6 +1233,10 @@ _cairo_xcb_surface_composite (cairo_operator_t op, goto BAIL; } + status = _cairo_xcb_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + goto BAIL; + status = _cairo_xcb_surface_set_attributes (src, &src_attr); if (status) goto BAIL; @@ -1257,7 +1331,8 @@ _cairo_xcb_surface_composite (cairo_operator_t op, mask ? mask->height : 0, src_x, src_y, mask_x, mask_y, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); BAIL: if (mask) @@ -1279,6 +1354,7 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface, xcb_render_color_t render_color; xcb_rectangle_t static_xrects[16]; xcb_rectangle_t *xrects = static_xrects; + cairo_status_t status; int i; if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) @@ -1289,6 +1365,9 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface, render_color.blue = color->blue_short; render_color.alpha = color->alpha_short; + status = _cairo_xcb_surface_set_clip_region (surface, NULL); + assert (status == CAIRO_STATUS_SUCCESS); + if (num_rects > ARRAY_LENGTH(static_xrects)) { xrects = _cairo_malloc_ab (num_rects, sizeof(xcb_rectangle_t)); if (xrects == NULL) @@ -1415,7 +1494,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps) + int num_traps, + cairo_region_t *clip_region) { cairo_surface_attributes_t attributes; cairo_xcb_surface_t *dst = abstract_dst; @@ -1475,6 +1555,11 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op, render_src_y = src_y + render_reference_y - dst_y; _cairo_xcb_surface_ensure_dst_picture (dst); + + status = _cairo_xcb_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + goto BAIL; + status = _cairo_xcb_surface_set_attributes (src, &attributes); if (status) goto BAIL; @@ -1516,7 +1601,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op, width, height, src_x, src_y, 0, 0, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); } else { xcb_render_trapezoid_t xtraps_stack[16]; @@ -1562,68 +1648,7 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op, return status; } -static cairo_int_status_t -_cairo_xcb_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - cairo_xcb_surface_t *surface = abstract_surface; - - if (surface->clip_rects) { - free (surface->clip_rects); - surface->clip_rects = NULL; - } - - surface->have_clip_rects = FALSE; - surface->num_clip_rects = 0; - - if (region == NULL) { - uint32_t none[] = { XCB_NONE }; - if (surface->gc) - xcb_change_gc (surface->dpy, surface->gc, XCB_GC_CLIP_MASK, none); - - if (surface->xrender_format.id != XCB_NONE && surface->dst_picture) - xcb_render_change_picture (surface->dpy, surface->dst_picture, - XCB_RENDER_CP_CLIP_MASK, none); - } else { - xcb_rectangle_t *rects = NULL; - int n_rects, i; - - n_rects = cairo_region_num_rectangles (region); - - if (n_rects > 0) { - rects = _cairo_malloc_ab (n_rects, sizeof(xcb_rectangle_t)); - if (rects == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else { - rects = NULL; - } - - for (i = 0; i < n_rects; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - - rects[i].x = rect.x; - rects[i].y = rect.y; - rects[i].width = rect.width; - rects[i].height = rect.height; - } - - surface->have_clip_rects = TRUE; - surface->clip_rects = rects; - surface->num_clip_rects = n_rects; - - if (surface->gc) - _cairo_xcb_surface_set_gc_clip_rects (surface); - - if (surface->dst_picture) - _cairo_xcb_surface_set_picture_clip_rects (surface); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t +static cairo_bool_t _cairo_xcb_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -1635,7 +1660,7 @@ _cairo_xcb_surface_get_extents (void *abstract_surface, rectangle->width = surface->width; rectangle->height = surface->height; - return CAIRO_STATUS_SUCCESS; + return TRUE; } /* XXX: _cairo_xcb_surface_get_font_options */ @@ -1654,8 +1679,8 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip, + int *remaining_glyphs); static cairo_bool_t _cairo_xcb_surface_is_similar (void *surface_a, @@ -1682,40 +1707,29 @@ _cairo_xcb_surface_is_similar (void *surface_a, return a->xrender_format.id == xrender_format->id; } -static cairo_status_t -_cairo_xcb_surface_reset (void *abstract_surface) -{ - cairo_xcb_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_xcb_surface_set_clip_region (surface, NULL); - if (status) - return status; - - return CAIRO_STATUS_SUCCESS; -} - - /* XXX: move this to the bottom of the file, XCB and Xlib */ static const cairo_surface_backend_t cairo_xcb_surface_backend = { CAIRO_SURFACE_TYPE_XCB, + _cairo_xcb_surface_create_similar, _cairo_xcb_surface_finish, _cairo_xcb_surface_acquire_source_image, _cairo_xcb_surface_release_source_image, + _cairo_xcb_surface_acquire_dest_image, _cairo_xcb_surface_release_dest_image, + _cairo_xcb_surface_clone_similar, _cairo_xcb_surface_composite, _cairo_xcb_surface_fill_rectangles, _cairo_xcb_surface_composite_trapezoids, NULL, /* create_span_renderer */ NULL, /* check_span_renderer */ + NULL, /* copy_page */ NULL, /* show_page */ - _cairo_xcb_surface_set_clip_region, - NULL, /* intersect_clip_path */ + _cairo_xcb_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -1733,8 +1747,6 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = { _cairo_xcb_surface_snapshot, _cairo_xcb_surface_is_similar, - - _cairo_xcb_surface_reset }; /** @@ -1853,8 +1865,9 @@ _cairo_xcb_surface_create_internal (xcb_connection_t *dpy, surface->have_clip_rects = FALSE; surface->clip_rects = NULL; surface->num_clip_rects = 0; + surface->clip_region = NULL; - return (cairo_surface_t *) surface; + return &surface->base; } static xcb_screen_t * @@ -2463,8 +2476,8 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_int_status_t status = CAIRO_STATUS_SUCCESS; cairo_xcb_surface_t *dst = abstract_dst; @@ -2474,6 +2487,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, cairo_xcb_surface_t *src = NULL; cairo_solid_pattern_t solid_pattern; + cairo_region_t *clip_region = NULL; if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || dst->xrender_format.id == XCB_NONE) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -2497,10 +2511,12 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, * fallback clip masking, we have to go through the full * fallback path. */ - if (dst->base.clip && - (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION || - dst->base.clip->surface != NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO); + if (status) + return status; + } operation = _categorize_composite_operation (dst, op, src_pattern, TRUE); if (operation == DO_UNSUPPORTED) @@ -2564,6 +2580,10 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, goto BAIL; } + status = _cairo_xcb_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + goto BAIL; + status = _cairo_xcb_surface_set_attributes (src, &attributes); if (status) goto BAIL; diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h index 164fe15f2..53701e249 100644 --- a/src/cairo-xlib-surface-private.h +++ b/src/cairo-xlib-surface-private.h @@ -85,11 +85,11 @@ struct _cairo_xlib_surface { Picture dst_picture, src_picture; unsigned int clip_dirty; - cairo_bool_t have_clip_rects; cairo_bool_t gc_has_clip_rects; XRectangle embedded_clip_rects[8]; XRectangle *clip_rects; int num_clip_rects; + cairo_region_t *clip_region; XRenderPictFormat *xrender_format; cairo_filter_t filter; diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 1aae28850..647e61fb3 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -45,11 +45,25 @@ #include "cairo-xlib-surface-private.h" #include "cairo-clip-private.h" #include "cairo-scaled-font-private.h" +#include "cairo-region-private.h" #include /* for XDestroyImage */ #define XLIB_COORD_MAX 32767 +#define DEBUG 0 + +#if DEBUG +#define UNSUPPORTED(reason) ({ \ + fprintf (stderr, \ + "cairo-xlib: hit unsupported operation %s(), line %d: %s\n", \ + __FUNCTION__, __LINE__, reason); \ + CAIRO_INT_STATUS_UNSUPPORTED; \ +}) +#else +#define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED +#endif + /* Xlib doesn't define a typedef, so define one ourselves */ typedef int (*cairo_xlib_error_func_t) (Display *display, XErrorEvent *event); @@ -65,7 +79,8 @@ _cairo_xlib_surface_create_internal (Display *dpy, int depth); static cairo_status_t -_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface); +_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface, + cairo_bool_t set_clip); static void _cairo_xlib_surface_maybe_put_gc (cairo_xlib_surface_t *surface); @@ -89,8 +104,8 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip, + int *remaining_glyphs); /* XXX temporarily used by cairo-qt-surface.c */ slim_hidden_proto (cairo_xlib_surface_create); @@ -135,12 +150,68 @@ static const XTransform identity = { { #if RENDER_MAJOR > 0 || RENDER_MINOR >= 11 #define CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR(surface, op) \ - (CAIRO_SURFACE_RENDER_HAS_PDF_OPERATORS (surface) ? (op) <= CAIRO_OPERATOR_HSL_LUMINOSITY : (op) <= CAIRO_OPERATOR_SATURATE) + (((op) <= CAIRO_OPERATOR_SATURATE) ? TRUE : (CAIRO_SURFACE_RENDER_HAS_PDF_OPERATORS (surface) ? (op) <= CAIRO_OPERATOR_HSL_LUMINOSITY : FALSE)) #else #define CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR(surface, op) \ ((op) <= CAIRO_OPERATOR_SATURATE) #endif +static cairo_status_t +_cairo_xlib_surface_set_clip_region (cairo_xlib_surface_t *surface, + cairo_region_t *region) +{ + cairo_bool_t had_clip_rects = surface->clip_region != NULL; + + if (had_clip_rects == FALSE && region == NULL) + return CAIRO_STATUS_SUCCESS; + + if (surface->clip_region == region) + return CAIRO_STATUS_SUCCESS; + + if (cairo_region_equal (surface->clip_region, region)) + return CAIRO_STATUS_SUCCESS; + + cairo_region_destroy (surface->clip_region); + surface->clip_region = cairo_region_reference (region); + + if (surface->clip_rects != surface->embedded_clip_rects) { + free (surface->clip_rects); + surface->clip_rects = surface->embedded_clip_rects; + } + surface->num_clip_rects = 0; + + if (region != NULL) { + XRectangle *rects = NULL; + int n_rects, i; + + n_rects = cairo_region_num_rectangles (region); + if (n_rects > ARRAY_LENGTH (surface->embedded_clip_rects)) { + rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); + if (unlikely (rects == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } else { + rects = surface->embedded_clip_rects; + } + + for (i = 0; i < n_rects; i++) { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (region, i, &rect); + + rects[i].x = rect.x; + rects[i].y = rect.y; + rects[i].width = rect.width; + rects[i].height = rect.height; + } + + surface->clip_rects = rects; + surface->num_clip_rects = n_rects; + } + + surface->clip_dirty = CAIRO_XLIB_SURFACE_CLIP_DIRTY_ALL; + return CAIRO_STATUS_SUCCESS; +} + static cairo_surface_t * _cairo_xlib_surface_create_similar_with_format (void *abstract_src, cairo_format_t format, @@ -178,7 +249,7 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src, xrender_format, width, height, xrender_format->depth); - if (surface->base.status) { + if (unlikely (surface->base.status)) { XFreePixmap (dpy, pix); return &surface->base; } @@ -256,7 +327,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src, xrender_format, width, height, xrender_format->depth); - if (surface->base.status != CAIRO_STATUS_SUCCESS) { + if (unlikely (surface->base.status)) { XFreePixmap (src->dpy, pix); return &surface->base; } @@ -280,9 +351,7 @@ _cairo_xlib_surface_finish (void *abstract_surface) status2 = _cairo_xlib_display_queue_resource (display, XRenderFreePicture, surface->dst_picture); - if (status2 == CAIRO_STATUS_SUCCESS) - surface->dst_picture = None; - else if (status == CAIRO_STATUS_SUCCESS) + if (status == CAIRO_STATUS_SUCCESS) status = status2; } @@ -290,19 +359,14 @@ _cairo_xlib_surface_finish (void *abstract_surface) status2 = _cairo_xlib_display_queue_resource (display, XRenderFreePicture, surface->src_picture); - if (status2 == CAIRO_STATUS_SUCCESS) - surface->src_picture = None; - else if (status == CAIRO_STATUS_SUCCESS) + if (status == CAIRO_STATUS_SUCCESS) status = status2; } status2 = _cairo_xlib_display_queue_resource (display, (cairo_xlib_notify_resource_func) XFreePixmap, surface->drawable); - if (status2 == CAIRO_STATUS_SUCCESS) { - surface->owns_pixmap = FALSE; - surface->drawable = None; - } else if (status == CAIRO_STATUS_SUCCESS) + if (status == CAIRO_STATUS_SUCCESS) status = status2; } else { if (surface->dst_picture != None) @@ -332,6 +396,7 @@ _cairo_xlib_surface_finish (void *abstract_surface) _cairo_xlib_display_destroy (surface->display); } + cairo_region_destroy (surface->clip_region); surface->dpy = NULL; return status; @@ -667,8 +732,7 @@ _get_image_surface (cairo_xlib_surface_t *surface, ximage = NULL; } - if (!ximage) { - + if (ximage == NULL) { /* XGetImage from a window is dangerous because it can * produce errors if the window is unmapped or partially * outside the screen. We could check for errors and @@ -677,7 +741,7 @@ _get_image_surface (cairo_xlib_surface_t *surface, */ Pixmap pixmap; - status = _cairo_xlib_surface_ensure_gc (surface); + status = _cairo_xlib_surface_ensure_gc (surface, FALSE); if (unlikely (status)) return status; @@ -700,7 +764,7 @@ _get_image_surface (cairo_xlib_surface_t *surface, XFreePixmap (surface->dpy, pixmap); } - if (!ximage) + if (ximage == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_xlib_surface_maybe_put_gc (surface); @@ -714,10 +778,14 @@ _get_image_surface (cairo_xlib_surface_t *surface, xlib_masks.green_mask = surface->g_mask; xlib_masks.blue_mask = surface->b_mask; - if (_pixman_format_from_masks (&xlib_masks, &pixman_format) && - xlib_masks.bpp >= 24 && - ximage->bitmap_unit == 32 && - ximage->bitmap_pad == 32) + /* We can't use pixman to simply write to image if: + * (a) the pixels are not appropriately aligned, + * (b) pixman does not the pixel format, or + * (c) if the image is palettized and we need to convert. + */ + if (ximage->bitmap_unit == 32 && ximage->bitmap_pad == 32 && + _pixman_format_from_masks (&xlib_masks, &pixman_format) && + (surface->visual == NULL || surface->visual->class == TrueColor)) { image = (cairo_image_surface_t*) _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data, @@ -861,7 +929,7 @@ _cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface) static void _cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_surface_t *surface) { - if (surface->have_clip_rects) { + if (surface->clip_region != NULL) { XRenderSetPictureClipRectangles (surface->dpy, surface->dst_picture, 0, 0, surface->clip_rects, @@ -879,8 +947,8 @@ _cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_surface_t *surface) static void _cairo_xlib_surface_set_gc_clip_rects (cairo_xlib_surface_t *surface) { - surface->gc_has_clip_rects = surface->have_clip_rects; - if (surface->have_clip_rects) { + surface->gc_has_clip_rects = surface->clip_region != NULL; + if (surface->clip_region != NULL) { XSetClipRectangles(surface->dpy, surface->gc, 0, 0, surface->clip_rects, @@ -906,7 +974,8 @@ _cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface) } static cairo_status_t -_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface) +_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface, + cairo_bool_t set_clip) { if (surface->gc == NULL) { @@ -916,10 +985,22 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface) &surface->clip_dirty); if (unlikely (surface->gc == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + surface->gc_has_clip_rects = + surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC; } - if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC) - _cairo_xlib_surface_set_gc_clip_rects (surface); + if (set_clip) { + if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC) + _cairo_xlib_surface_set_gc_clip_rects (surface); + } else { + if (surface->gc_has_clip_rects) { + surface->gc_has_clip_rects = FALSE; + XSetClipMask (surface->dpy, surface->gc, None); + + surface->clip_dirty |= CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC; + } + } return CAIRO_STATUS_SUCCESS; } @@ -928,7 +1009,6 @@ static void _cairo_xlib_surface_maybe_put_gc (cairo_xlib_surface_t *surface) { /* return the GC back to the common pool if clean */ - if (surface->gc_has_clip_rects) return; @@ -984,7 +1064,9 @@ _draw_image_surface (cairo_xlib_surface_t *surface, ret = XInitImage (&ximage); assert (ret != 0); - } else { + } + else + { unsigned int stride, rowstride; int x, y, x0, y0, x_off, y_off; uint32_t in_pixel, out_pixel, *row; @@ -1089,13 +1171,14 @@ _draw_image_surface (cairo_xlib_surface_t *surface, } } - status = _cairo_xlib_surface_ensure_gc (surface); + /* XXX set clip? */ + status = _cairo_xlib_surface_ensure_gc (surface, FALSE); if (unlikely (status)) goto BAIL; - XPutImage(surface->dpy, surface->drawable, surface->gc, - &ximage, src_x, src_y, dst_x, dst_y, - width, height); + XPutImage (surface->dpy, surface->drawable, surface->gc, + &ximage, src_x, src_y, dst_x, dst_y, + width, height); _cairo_xlib_surface_maybe_put_gc (surface); @@ -1103,7 +1186,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface, if (own_data) free (ximage.data); - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_status_t @@ -1197,11 +1280,11 @@ _cairo_xlib_surface_release_dest_image (void *abstract_surfac * screen. Both core and Render drawing require this * when using multiple drawables in an operation. */ -static cairo_bool_t +static inline cairo_bool_t _cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst, cairo_xlib_surface_t *src) { - return dst->dpy == src->dpy && dst->screen == src->screen; + return dst->screen_info == src->screen_info; } static cairo_status_t @@ -1237,7 +1320,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, cairo_format_t format; if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("roi too large for xlib"); format = image_src->format; if (format == CAIRO_FORMAT_INVALID || @@ -1250,9 +1333,9 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, format, width, height); if (clone == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("unhandled image format, no similar surface"); - if (clone->base.status) + if (unlikely (clone->base.status)) return clone->base.status; status = _draw_image_surface (clone, image_src, @@ -1299,9 +1382,6 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac if (CAIRO_SURFACE_RENDER_HAS_COMPOSITE (other)) return NULL; - if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) - return NULL; - image = (cairo_image_surface_t *) _cairo_image_surface_create_with_content (solid_pattern->content, width, height); @@ -1327,7 +1407,8 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac status = _cairo_surface_paint (&image->base, CAIRO_OPERATOR_SOURCE, - &solid_pattern->base, NULL); + &solid_pattern->base, + NULL); if (unlikely (status)) goto BAIL; @@ -1361,7 +1442,6 @@ _cairo_xlib_surface_can_repaint_solid_pattern_surface (void *abstract_surface, return CAIRO_SURFACE_RENDER_HAS_COMPOSITE (other); } - static cairo_status_t _cairo_xlib_surface_set_matrix (cairo_xlib_surface_t *surface, cairo_matrix_t *matrix, @@ -1380,8 +1460,8 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_surface_t *surface, if (memcmp (&xtransform, &surface->xtransform, sizeof (XTransform)) == 0) return CAIRO_STATUS_SUCCESS; - if (!CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface)) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (! CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface)) + return UNSUPPORTED ("XRender does not support picture transforms"); XRenderSetPictureTransform (surface->dpy, surface->src_picture, &xtransform); surface->xtransform = xtransform; @@ -1398,12 +1478,11 @@ _cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface, if (surface->filter == filter) return CAIRO_STATUS_SUCCESS; - if (!CAIRO_SURFACE_RENDER_HAS_FILTERS (surface)) - { + if (!CAIRO_SURFACE_RENDER_HAS_FILTERS (surface)) { if (filter == CAIRO_FILTER_FAST || filter == CAIRO_FILTER_NEAREST) return CAIRO_STATUS_SUCCESS; - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("XRender does not support filter"); } switch (filter) { @@ -1463,6 +1542,7 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface, double yc) { cairo_int_status_t status; + int repeat; _cairo_xlib_surface_ensure_src_picture (surface); @@ -1473,24 +1553,28 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface, switch (attributes->extend) { case CAIRO_EXTEND_NONE: - _cairo_xlib_surface_set_repeat (surface, RepeatNone); + repeat = RepeatNone; break; case CAIRO_EXTEND_REPEAT: - _cairo_xlib_surface_set_repeat (surface, RepeatNormal); + repeat = RepeatNormal; break; case CAIRO_EXTEND_REFLECT: if (surface->buggy_pad_reflect) - return CAIRO_INT_STATUS_UNSUPPORTED; - _cairo_xlib_surface_set_repeat (surface, RepeatReflect); + return UNSUPPORTED ("buggy reflect"); + + repeat = RepeatReflect; break; case CAIRO_EXTEND_PAD: if (surface->buggy_pad_reflect) - return CAIRO_INT_STATUS_UNSUPPORTED; - _cairo_xlib_surface_set_repeat (surface, RepeatPad); + return UNSUPPORTED ("buggy reflect"); + + repeat = RepeatPad; break; default: + ASSERT_NOT_REACHED; return CAIRO_INT_STATUS_UNSUPPORTED; } + _cairo_xlib_surface_set_repeat (surface, repeat); status = _cairo_xlib_surface_set_filter (surface, attributes->filter); if (unlikely (status)) @@ -1508,7 +1592,7 @@ _surfaces_compatible (cairo_xlib_surface_t *dst, cairo_xlib_surface_t *src) { /* same screen */ - if (!_cairo_xlib_surface_same_screen (dst, src)) + if (! _cairo_xlib_surface_same_screen (dst, src)) return FALSE; /* same depth (for core) */ @@ -1538,7 +1622,6 @@ _surface_has_alpha (cairo_xlib_surface_t *surface) else return FALSE; } else { - /* In the no-render case, we never have alpha */ return FALSE; } @@ -1601,7 +1684,7 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst, if (!CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR (dst, op)) return DO_UNSUPPORTED; - if (!dst->buggy_repeat) + if (! dst->buggy_repeat) return DO_RENDER; if (src_pattern->type == CAIRO_PATTERN_TYPE_SURFACE) @@ -1665,9 +1748,6 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst, _cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL); cairo_bool_t needs_alpha_composite; - if (! _cairo_surface_is_xlib (&src->base)) - return DO_UNSUPPORTED; - needs_alpha_composite = _operator_needs_alpha_composite (op, _surface_has_alpha (dst), @@ -1810,7 +1890,8 @@ _cairo_xlib_surface_composite (cairo_operator_t op, int dst_x, int dst_y, unsigned int width, - unsigned int height) + unsigned int height, + cairo_region_t *clip_region) { cairo_surface_attributes_t src_attr, mask_attr; cairo_xlib_surface_t *dst = abstract_dst; @@ -1823,12 +1904,13 @@ _cairo_xlib_surface_composite (cairo_operator_t op, cairo_bool_t needs_alpha_composite; cairo_content_t src_content; - _cairo_xlib_display_notify (dst->display); + if (mask_pattern != NULL && ! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst)) + return UNSUPPORTED ("no support for masks"); operation = _categorize_composite_operation (dst, op, src_pattern, mask_pattern != NULL); if (operation == DO_UNSUPPORTED) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("unsupported operation"); needs_alpha_composite = _operator_needs_alpha_composite (op, @@ -1838,6 +1920,8 @@ _cairo_xlib_surface_composite (cairo_operator_t op, if (! needs_alpha_composite) src_content &= ~CAIRO_CONTENT_ALPHA; + _cairo_xlib_display_notify (dst->display); + status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern, &dst->base, src_content, @@ -1854,25 +1938,25 @@ _cairo_xlib_surface_composite (cairo_operator_t op, return status; /* check for fallback surfaces that we cannot handle ... */ - if (!_cairo_surface_is_xlib (&src->base)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL; - } - if (mask != NULL && - (! _cairo_surface_is_xlib (&mask->base) || - ! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst))) - { - status = CAIRO_INT_STATUS_UNSUPPORTED; + assert (_cairo_surface_is_xlib (&src->base)); + assert (mask == NULL || _cairo_surface_is_xlib (&mask->base)); + + if (mask != NULL && ! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (mask)) { + status = UNSUPPORTED ("unsupported mask"); goto BAIL; } operation = _recategorize_composite_operation (dst, op, src, &src_attr, mask_pattern != NULL); if (operation == DO_UNSUPPORTED) { - status = CAIRO_INT_STATUS_UNSUPPORTED; + status = UNSUPPORTED ("unsupported operation"); goto BAIL; } + status = _cairo_xlib_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + goto BAIL; + switch (operation) { case DO_RENDER: @@ -1917,7 +2001,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, break; case DO_XCOPYAREA: - status = _cairo_xlib_surface_ensure_gc (dst); + status = _cairo_xlib_surface_ensure_gc (dst, TRUE); if (unlikely (status)) goto BAIL; @@ -1947,7 +2031,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, * _recategorize_composite_operation. */ - status = _cairo_xlib_surface_ensure_gc (dst); + status = _cairo_xlib_surface_ensure_gc (dst, TRUE); if (unlikely (status)) goto BAIL; is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr.matrix, @@ -1979,7 +2063,8 @@ _cairo_xlib_surface_composite (cairo_operator_t op, mask ? mask->height : 0, src_x, src_y, mask_x, mask_y, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); BAIL: if (mask) @@ -2004,7 +2089,7 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface, _cairo_pattern_init_solid (&solid, color, CAIRO_CONTENT_COLOR); - status = _cairo_xlib_surface_ensure_gc (surface); + status = _cairo_xlib_surface_ensure_gc (surface, FALSE); if (unlikely (status)) return status; @@ -2019,10 +2104,7 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface, if (unlikely (status)) return status; - if (! _cairo_surface_is_xlib (solid_surface)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL; - } + assert (_cairo_surface_is_xlib (solid_surface)); XSetTSOrigin (surface->dpy, surface->gc, - (surface->base.device_transform.x0 + attrs.x_offset), @@ -2039,10 +2121,9 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface, _cairo_xlib_surface_maybe_put_gc (surface); - BAIL: _cairo_pattern_release_surface (&solid.base, solid_surface, &attrs); - return status; + return CAIRO_STATUS_SUCCESS; } static cairo_int_status_t @@ -2054,6 +2135,7 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface, { cairo_xlib_surface_t *surface = abstract_surface; XRenderColor render_color; + cairo_status_t status; int i; _cairo_xlib_display_notify (surface->display); @@ -2070,7 +2152,7 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface, rects, num_rects); } - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("no support for FillRectangles with this op"); } render_color.red = color->red_short; @@ -2078,6 +2160,9 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface, render_color.blue = color->blue_short; render_color.alpha = color->alpha_short; + status = _cairo_xlib_surface_set_clip_region (surface, NULL); + assert (status == CAIRO_STATUS_SUCCESS); + _cairo_xlib_surface_ensure_dst_picture (surface); if (num_rects == 1) { /* Take advantage of the protocol compaction that libXrender performs @@ -2245,7 +2330,8 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps) + int num_traps, + cairo_region_t *clip_region) { cairo_surface_attributes_t attributes; cairo_xlib_surface_t *dst = abstract_dst; @@ -2258,12 +2344,12 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, _cairo_xlib_display_notify (dst->display); - if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (! CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)) + return UNSUPPORTED ("XRender does not support CompositeTrapezoids"); operation = _categorize_composite_operation (dst, op, pattern, TRUE); if (operation == DO_UNSUPPORTED) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("unsupported operation"); status = _cairo_pattern_acquire_surface (pattern, &dst->base, CAIRO_CONTENT_COLOR_ALPHA, @@ -2279,7 +2365,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE); if (operation == DO_UNSUPPORTED) { - status = CAIRO_INT_STATUS_UNSUPPORTED; + status = UNSUPPORTED ("unsupported operation"); goto BAIL; } @@ -2310,7 +2396,12 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, render_src_x = src_x + render_reference_x - dst_x; render_src_y = src_y + render_reference_y - dst_y; + status = _cairo_xlib_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + goto BAIL; + _cairo_xlib_surface_ensure_dst_picture (dst); + status = _cairo_xlib_surface_set_attributes (src, &attributes, dst_x + width / 2., dst_y + height / 2.); @@ -2353,7 +2444,8 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, width, height, src_x, src_y, 0, 0, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + clip_region); } else { XTrapezoid xtraps_stack[CAIRO_STACK_ARRAY_LENGTH (XTrapezoid)]; @@ -2399,115 +2491,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, return status; } -static cairo_region_t * -_surface_maybe_clip_region (cairo_xlib_surface_t *surface, - cairo_region_t *clip, - cairo_region_t *bounded) -{ - cairo_rectangle_int_t rect; - - cairo_region_get_extents (clip, &rect); - if (rect.x >= 0 && - rect.y >= 0 && - rect.x + rect.width <= surface->width && - rect.y + rect.height <= surface->height) - { - return clip; - } - - rect.x = rect.y = 0; - rect.width = surface->width; - rect.height = surface->height; - _cairo_region_init_rectangle (bounded, &rect); - - bounded->status = cairo_region_intersect (bounded, clip); - - return bounded; -} - -static cairo_int_status_t -_cairo_xlib_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_bool_t had_clip_rects = surface->have_clip_rects; - - if (had_clip_rects == FALSE && region == NULL) - return CAIRO_STATUS_SUCCESS; - - if (surface->clip_rects != surface->embedded_clip_rects) { - free (surface->clip_rects); - surface->clip_rects = surface->embedded_clip_rects; - } - - surface->have_clip_rects = FALSE; - surface->num_clip_rects = 0; - - if (region != NULL) { - XRectangle *rects = NULL; - int n_rects, i; - cairo_region_t bounded; - - /* Intersect the region with the bounds of the surface. This - * is necessary so we don't wrap around when we convert cairo's - * 32 bit region into 16 bit rectangles. - */ - region = _surface_maybe_clip_region (surface, region, &bounded); - if (unlikely (region->status)) - return region->status; - - n_rects = cairo_region_num_rectangles (region); - if (n_rects > ARRAY_LENGTH (surface->embedded_clip_rects)) { - rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); - if (unlikely (rects == NULL)) { - if (unlikely (region == &bounded)) - _cairo_region_fini (&bounded); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } else { - rects = surface->embedded_clip_rects; - } - - for (i = 0; i < n_rects; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - - rects[i].x = rect.x; - rects[i].y = rect.y; - rects[i].width = rect.width; - rects[i].height = rect.height; - } - - if (unlikely (region == &bounded)) - _cairo_region_fini (&bounded); - - surface->have_clip_rects = TRUE; - surface->clip_rects = rects; - surface->num_clip_rects = n_rects; - - /* Discard the trivial clip rectangle that covers the entire surface */ - if (n_rects == 1 && - rects[0].x == 0 && - rects[0].y == 0 && - rects[0].width == surface->width && - rects[0].height == surface->height) - { - surface->have_clip_rects = FALSE; - surface->num_clip_rects = 0; - - if (! had_clip_rects) - goto DONE; - } - } - - surface->clip_dirty = CAIRO_XLIB_SURFACE_CLIP_DIRTY_ALL; - DONE: - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t +static cairo_bool_t _cairo_xlib_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -2519,7 +2503,7 @@ _cairo_xlib_surface_get_extents (void *abstract_surface, rectangle->width = surface->width; rectangle->height = surface->height; - return CAIRO_STATUS_SUCCESS; + return TRUE; } static void @@ -2547,7 +2531,7 @@ _cairo_xlib_surface_is_similar (void *surface_a, cairo_xlib_surface_t *b = surface_b; XRenderPictFormat *xrender_format = b->xrender_format; - if (!_cairo_xlib_surface_same_screen (a, b)) + if (! _cairo_xlib_surface_same_screen (a, b)) return FALSE; /* now inspect the content to check that a is similar to b */ @@ -2566,19 +2550,6 @@ _cairo_xlib_surface_is_similar (void *surface_a, return a->xrender_format == xrender_format; } -static cairo_status_t -_cairo_xlib_surface_reset (void *abstract_surface) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_xlib_surface_set_clip_region (surface, NULL); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - static const cairo_surface_backend_t cairo_xlib_surface_backend = { CAIRO_SURFACE_TYPE_XLIB, _cairo_xlib_surface_create_similar, @@ -2595,8 +2566,6 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - _cairo_xlib_surface_set_clip_region, - NULL, /* intersect_clip_path */ _cairo_xlib_surface_get_extents, NULL, /* old_show_glyphs */ _cairo_xlib_surface_get_font_options, @@ -2612,10 +2581,10 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = { _cairo_xlib_surface_show_glyphs, _cairo_xlib_surface_snapshot, - _cairo_xlib_surface_is_similar, - _cairo_xlib_surface_reset, + NULL, /* fill_stroke */ + _cairo_xlib_surface_create_solid_pattern_surface, _cairo_xlib_surface_can_repaint_solid_pattern_surface }; @@ -2771,7 +2740,7 @@ _cairo_xlib_surface_create_internal (Display *dpy, surface->height = height; surface->buggy_repeat = screen_info->display->buggy_repeat; - if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES (surface)) { + if (! CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES (surface)) { /* so we can use the XTile fallback */ surface->buggy_repeat = TRUE; } @@ -2787,7 +2756,7 @@ _cairo_xlib_surface_create_internal (Display *dpy, surface->repeat = FALSE; surface->xtransform = identity; - surface->have_clip_rects = FALSE; + surface->clip_region = NULL; surface->gc_has_clip_rects = FALSE; surface->clip_rects = surface->embedded_clip_rects; surface->num_clip_rects = 0; @@ -2833,23 +2802,25 @@ _cairo_xlib_surface_create_internal (Display *dpy, static Screen * _cairo_xlib_screen_from_visual (Display *dpy, Visual *visual) { - int s; - int d; - int v; - Screen *screen; - Depth *depth; + int s, d, v; for (s = 0; s < ScreenCount (dpy); s++) { + Screen *screen; + screen = ScreenOfDisplay (dpy, s); if (visual == DefaultVisualOfScreen (screen)) return screen; + for (d = 0; d < screen->ndepths; d++) { + Depth *depth; + depth = &screen->depths[d]; for (v = 0; v < depth->nvisuals; v++) if (visual == &depth->visuals[v]) return screen; } } + return NULL; } @@ -3624,7 +3595,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, sz_xGlyphInfo - 8; if (len >= max_request_size) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("glyph too large for XRequest"); } /* If the glyph surface has zero height or width, we create @@ -3975,7 +3946,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (status != CAIRO_STATUS_SUCCESS) + if (unlikely (status)) return status; this_x = _cairo_lround (glyphs[i].d.x); @@ -4055,7 +4026,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst, status = _emit_glyphs_chunk (dst, glyphs, i, scaled_font, op, src, attributes, num_elts, old_width, glyphset_info); - if (status != CAIRO_STATUS_SUCCESS) + if (unlikely (status)) return status; glyphs += i; @@ -4094,13 +4065,14 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst, request_size += width; } - if (num_elts) + if (num_elts) { status = _emit_glyphs_chunk (dst, glyphs, i, scaled_font, op, src, attributes, num_elts, width, glyphset_info); + } *remaining_glyphs = num_glyphs - i; - if (*remaining_glyphs && status == CAIRO_STATUS_SUCCESS) + if (*remaining_glyphs != 0 && status == CAIRO_STATUS_SUCCESS) status = CAIRO_INT_STATUS_UNSUPPORTED; return status; @@ -4130,8 +4102,8 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip, + int *remaining_glyphs) { cairo_int_status_t status = CAIRO_STATUS_SUCCESS; cairo_xlib_surface_t *dst = (cairo_xlib_surface_t*) abstract_dst; @@ -4139,16 +4111,17 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, composite_operation_t operation; cairo_surface_attributes_t attributes; cairo_xlib_surface_t *src = NULL; + cairo_region_t *clip_region = NULL; cairo_solid_pattern_t solid_pattern; if (! CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst)) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("XRender does not support CompositeText"); /* Just let unbounded operators go through the fallback code * instead of trying to do the fixups here */ - if (!_cairo_operator_bounded_by_mask (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (! _cairo_operator_bounded_by_mask (op)) + return UNSUPPORTED ("unsupported unbounded op"); /* Render <= 0.10 seems to have a bug with PictOpSrc and glyphs -- * the solid source seems to be multiplied by the glyph mask, and @@ -4156,25 +4129,33 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, * including the fully transparent "background" of the rectangular * glyph surface. */ if (op == CAIRO_OPERATOR_SOURCE && - !CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11)) - return CAIRO_INT_STATUS_UNSUPPORTED; + ! CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11)) + { + return UNSUPPORTED ("known bug in Render"); + } /* We can only use our code if we either have no clip or * have a real native clip region set. If we're using * fallback clip masking, we have to go through the full * fallback path. */ - if (dst->base.clip && - (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION || - dst->base.clip->surface != NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; + if (clip != NULL) { + status = _cairo_clip_get_region (clip, &clip_region); + assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO); + if (status) + return status; + } operation = _categorize_composite_operation (dst, op, src_pattern, TRUE); if (operation == DO_UNSUPPORTED) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("unsupported op"); if (! _cairo_xlib_surface_owns_font (dst, scaled_font)) - return CAIRO_INT_STATUS_UNSUPPORTED; + return UNSUPPORTED ("unowned font"); + + status = _cairo_xlib_surface_set_clip_region (dst, clip_region); + if (unlikely (status)) + return status; /* After passing all those tests, we're now committed to rendering * these glyphs or to fail trying. We first upload any glyphs to @@ -4213,6 +4194,14 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, if (unlikely (status)) goto BAIL0; + if (clip != NULL) { + if (! _cairo_rectangle_intersect (&glyph_extents, + _cairo_clip_get_extents (clip))) + { + goto BAIL0; + } + } + status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, CAIRO_CONTENT_COLOR_ALPHA, glyph_extents.x, glyph_extents.y, @@ -4229,7 +4218,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE); if (operation == DO_UNSUPPORTED) { - status = CAIRO_INT_STATUS_UNSUPPORTED; + status = UNSUPPORTED ("unsupported op"); goto BAIL1; } @@ -4247,15 +4236,14 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, src, &attributes, remaining_glyphs); - } else - status = CAIRO_INT_STATUS_UNSUPPORTED; + } else { + status = UNSUPPORTED ("unowned font"); + } _cairo_scaled_font_thaw_cache (scaled_font); BAIL1: if (src) _cairo_pattern_release_surface (src_pattern, &src->base, &attributes); - if (src_pattern == &solid_pattern.base) - _cairo_pattern_fini (&solid_pattern.base); BAIL0: _cairo_xlib_display_notify (dst->display); diff --git a/src/cairo.c b/src/cairo.c index 3e590496a..2470b0d69 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -44,6 +44,10 @@ #define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1) +#if !defined(INFINITY) +#define INFINITY HUGE_VAL +#endif + static const cairo_t _cairo_nil = { CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ CAIRO_STATUS_NO_MEMORY, /* status */ @@ -57,7 +61,8 @@ static const cairo_t _cairo_nil = { FALSE, /* has_current_point */ FALSE, /* has_curve_to */ FALSE, /* is_box */ - FALSE, /* is_region */ + FALSE, /* maybe_fill_region */ + TRUE, /* is_empty_fill */ {{{NULL,NULL}}} /* link */ }} }; @@ -496,25 +501,28 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) { cairo_status_t status; cairo_rectangle_int_t extents; + const cairo_rectangle_int_t *clip_extents; cairo_surface_t *parent_surface, *group_surface = NULL; + cairo_bool_t is_empty; if (unlikely (cr->status)) return; parent_surface = _cairo_gstate_get_target (cr->gstate); - /* Get the extents that we'll use in creating our new group surface */ - status = _cairo_surface_get_extents (parent_surface, &extents); - if (unlikely (status)) - goto bail; - status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents); - if (unlikely (status)) - goto bail; - group_surface = cairo_surface_create_similar (parent_surface, - content, - extents.width, - extents.height); - status = cairo_surface_status (group_surface); + /* Get the extents that we'll use in creating our new group surface */ + is_empty = _cairo_surface_get_extents (parent_surface, &extents); + clip_extents = _cairo_clip_get_extents (_cairo_gstate_get_clip (cr->gstate)); + if (clip_extents != NULL) + is_empty = _cairo_rectangle_intersect (&extents, clip_extents); + + group_surface = _cairo_surface_create_similar_solid (parent_surface, + content, + extents.width, + extents.height, + CAIRO_COLOR_TRANSPARENT, + TRUE); + status = group_surface->status; if (unlikely (status)) goto bail; @@ -2340,7 +2348,7 @@ cairo_in_stroke (cairo_t *cr, double x, double y) cairo_bool_t inside = FALSE; if (unlikely (cr->status)) - return 0; + return FALSE; status = _cairo_gstate_in_stroke (cr->gstate, cr->path, @@ -2370,16 +2378,10 @@ cairo_in_stroke (cairo_t *cr, double x, double y) cairo_bool_t cairo_in_fill (cairo_t *cr, double x, double y) { - cairo_bool_t inside; - if (unlikely (cr->status)) - return 0; + return FALSE; - _cairo_gstate_in_fill (cr->gstate, - cr->path, - x, y, &inside); - - return inside; + return _cairo_gstate_in_fill (cr->gstate, cr->path, x, y); } /** @@ -2600,8 +2602,6 @@ cairo_clip_extents (cairo_t *cr, double *x1, double *y1, double *x2, double *y2) { - cairo_status_t status; - if (unlikely (cr->status)) { if (x1) *x1 = 0.0; @@ -2615,9 +2615,38 @@ cairo_clip_extents (cairo_t *cr, return; } - status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2); - if (unlikely (status)) - _cairo_set_error (cr, status); + if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) { + *x1 = -INFINITY; + *y1 = -INFINITY; + *x2 = +INFINITY; + *y2 = +INFINITY; + } +} + +/** + * cairo_in_clip: + * @cr: a cairo context + * @x: X coordinate of the point to test + * @y: Y coordinate of the point to test + * + * Tests whether the given point is inside the area that would be + * visible through the current clip, i.e. the area that would be filled by + * a cairo_paint() operation. + * + * See cairo_clip(), and cairo_clip_preserve(). + * + * Return value: A non-zero value if the point is inside, or zero if + * outside. + * + * Since: 1.10 + **/ +cairo_bool_t +cairo_in_clip (cairo_t *cr, double x, double y) +{ + if (unlikely (cr->status)) + return FALSE; + + return _cairo_gstate_in_clip (cr->gstate, x, y); } static cairo_rectangle_list_t * diff --git a/src/cairo.h b/src/cairo.h index bd4eb661d..4e930604f 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -788,6 +788,9 @@ cairo_in_stroke (cairo_t *cr, double x, double y); cairo_public cairo_bool_t cairo_in_fill (cairo_t *cr, double x, double y); +cairo_public cairo_bool_t +cairo_in_clip (cairo_t *cr, double x, double y); + /* Rectangular extents */ cairo_public void cairo_stroke_extents (cairo_t *cr, @@ -2169,8 +2172,7 @@ cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func, cairo_public cairo_surface_t * cairo_meta_surface_create (cairo_content_t content, - double width_pixels, - double height_pixels); + const cairo_rectangle_t *extents); cairo_public void cairo_meta_surface_ink_extents (cairo_surface_t *surface, @@ -2451,39 +2453,45 @@ cairo_public cairo_region_t * cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle); cairo_public cairo_region_t * -cairo_region_create_rectangles (cairo_rectangle_int_t *rects, +cairo_region_create_rectangles (const cairo_rectangle_int_t *rects, int count); cairo_public cairo_region_t * -cairo_region_copy (cairo_region_t *original); +cairo_region_copy (const cairo_region_t *original); + +cairo_public cairo_region_t * +cairo_region_reference (cairo_region_t *); cairo_public void cairo_region_destroy (cairo_region_t *region); +cairo_public cairo_bool_t +cairo_region_equal (const cairo_region_t *a, const cairo_region_t *b); + cairo_public cairo_status_t -cairo_region_status (cairo_region_t *region); +cairo_region_status (const cairo_region_t *region); cairo_public void -cairo_region_get_extents (cairo_region_t *region, +cairo_region_get_extents (const cairo_region_t *region, cairo_rectangle_int_t *extents); cairo_public int -cairo_region_num_rectangles (cairo_region_t *region); +cairo_region_num_rectangles (const cairo_region_t *region); cairo_public void -cairo_region_get_rectangle (cairo_region_t *region, +cairo_region_get_rectangle (const cairo_region_t *region, int nth_rectangle, cairo_rectangle_int_t *rectangle); cairo_public cairo_bool_t -cairo_region_is_empty (cairo_region_t *region); +cairo_region_is_empty (const cairo_region_t *region); cairo_public cairo_region_overlap_t -cairo_region_contains_rectangle (cairo_region_t *region, +cairo_region_contains_rectangle (const cairo_region_t *region, const cairo_rectangle_int_t *rectangle); cairo_public cairo_bool_t -cairo_region_contains_point (cairo_region_t *region, int x, int y); +cairo_region_contains_point (const cairo_region_t *region, int x, int y); cairo_public void cairo_region_translate (cairo_region_t *region, int dx, int dy); diff --git a/src/cairoint.h b/src/cairoint.h index cb30f6dee..5782f0711 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -125,7 +125,7 @@ _cairo_win32_tmpfile (void); #define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string) #define STRINGIFY_ARG(contents) #contents -#ifdef __GNUC__ +#if defined (__GNUC__) #define cairo_container_of(ptr, type, member) ({ \ const __typeof__ (((type *) 0)->member) *mptr__ = (ptr); \ (type *) ((char *) mptr__ - offsetof (type, member)); \ @@ -252,6 +252,15 @@ cairo_private void _cairo_box_round_to_rectangle (const cairo_box_t *box, cairo_rectangle_int_t *rectangle); +static inline void +_cairo_unbounded_rectangle_init (cairo_rectangle_int_t *rect) +{ + rect->x = CAIRO_RECT_INT_MIN; + rect->y = CAIRO_RECT_INT_MIN; + rect->width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; + rect->height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN; +} + cairo_private cairo_bool_t _cairo_rectangle_intersect (cairo_rectangle_int_t *dst, const cairo_rectangle_int_t *src); @@ -489,6 +498,7 @@ struct _cairo_scaled_font_backend { unsigned int height, cairo_glyph_t *glyphs, int num_glyphs, + cairo_region_t *clip_region, int *remaining_glyphs); cairo_warn cairo_int_status_t @@ -615,6 +625,7 @@ struct _cairo_surface_backend { int *clone_offset_y, cairo_surface_t **clone_out); + /* XXX remove to a separate cairo_surface_compositor_t */ /* XXX: dst should be the first argument for consistency */ cairo_warn cairo_int_status_t (*composite) (cairo_operator_t op, @@ -628,7 +639,8 @@ struct _cairo_surface_backend { int dst_x, int dst_y, unsigned int width, - unsigned int height); + unsigned int height, + cairo_region_t *clip_region); cairo_warn cairo_int_status_t (*fill_rectangles) (void *surface, @@ -650,14 +662,16 @@ struct _cairo_surface_backend { unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int num_traps); + int num_traps, + cairo_region_t *region); cairo_warn cairo_span_renderer_t * (*create_span_renderer) (cairo_operator_t op, const cairo_pattern_t *pattern, void *dst, cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects); + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region); cairo_warn cairo_bool_t (*check_span_renderer) (cairo_operator_t op, @@ -672,59 +686,15 @@ struct _cairo_surface_backend { cairo_warn cairo_int_status_t (*show_page) (void *surface); - /* Set given region as the clip region for the surface, replacing - * any previously set clip region. Passing in a NULL region will - * clear the surface clip region. - * - * The surface is expected to store the clip region and clip all - * following drawing operations against it until the clip region - * is cleared of replaced by another clip region. - * - * Cairo will call this function whenever a clip path can be - * represented as a device pixel aligned set of rectangles. When - * this is not possible, cairo will use mask surfaces for - * clipping. - */ - cairo_warn cairo_int_status_t - (*set_clip_region) (void *surface, - cairo_region_t *region); - - /* Intersect the given path against the clip path currently set in - * the surface, using the given fill_rule and tolerance, and set - * the result as the new clipping path for the surface. Passing - * in a NULL path will clear the surface clipping path. - * - * The surface is expected to store the resulting clip path and - * clip all following drawing operations against it until the clip - * path cleared or intersected with a new path. - * - * If a surface implements this function, set_clip_region() will - * never be called and should not be implemented. If this - * function is not implemented cairo will use set_clip_region() - * (if available) and mask surfaces for clipping. - */ - cairo_warn cairo_int_status_t - (*intersect_clip_path) (void *dst, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias); - /* Get the extents of the current surface. For many surface types * this will be as simple as { x=0, y=0, width=surface->width, * height=surface->height}. * - * This function need not take account of any clipping from - * set_clip_region since the generic version of set_clip_region - * saves those, and the generic get_clip_extents will only call - * into the specific surface->get_extents if there is no current - * clip. - * * If this function is not implemented, or if it returns - * %CAIRO_INT_STATUS_UNSUPPORTED, the surface is considered to be - * boundless and inifnite bounds are used for it. + * FALSE the surface is considered to be + * boundless and infinite bounds are used for it. */ - cairo_warn cairo_int_status_t + cairo_warn cairo_bool_t (*get_extents) (void *surface, cairo_rectangle_int_t *extents); @@ -745,7 +715,8 @@ struct _cairo_surface_backend { unsigned int width, unsigned int height, cairo_glyph_t *glyphs, - int num_glyphs); + int num_glyphs, + cairo_region_t *clip_region); void (*get_font_options) (void *surface, @@ -775,14 +746,14 @@ struct _cairo_surface_backend { (*paint) (void *surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_warn cairo_int_status_t (*mask) (void *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_warn cairo_int_status_t (*stroke) (void *surface, @@ -794,7 +765,7 @@ struct _cairo_surface_backend { cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_warn cairo_int_status_t (*fill) (void *surface, @@ -804,7 +775,7 @@ struct _cairo_surface_backend { cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_warn cairo_int_status_t (*show_glyphs) (void *surface, @@ -813,8 +784,8 @@ struct _cairo_surface_backend { cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip, + int *remaining_glyphs); cairo_surface_t * (*snapshot) (void *surface); @@ -824,9 +795,6 @@ struct _cairo_surface_backend { void *surface_b, cairo_content_t content); - cairo_warn cairo_status_t - (*reset) (void *surface); - cairo_warn cairo_int_status_t (*fill_stroke) (void *surface, cairo_operator_t fill_op, @@ -842,7 +810,7 @@ struct _cairo_surface_backend { cairo_matrix_t *stroke_ctm_inverse, double stroke_tolerance, cairo_antialias_t stroke_antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_surface_t * (*create_solid_pattern_surface) @@ -869,7 +837,7 @@ struct _cairo_surface_backend { int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); }; #include "cairo-surface-private.h" @@ -887,9 +855,9 @@ struct _cairo_image_surface { int depth; pixman_image_t *pixman_image; + cairo_region_t *clip_region; unsigned owns_data : 1; - unsigned has_clip : 1; unsigned transparency : 2; }; @@ -983,6 +951,8 @@ typedef struct _cairo_traps { cairo_box_t extents; + unsigned int maybe_region : 1; /* hint: 0 implies that it cannot be */ + int num_traps; int traps_size; cairo_trapezoid_t *traps; @@ -1245,12 +1215,16 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate, double y, cairo_bool_t *inside_ret); -cairo_private void +cairo_private cairo_bool_t _cairo_gstate_in_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path, double x, - double y, - cairo_bool_t *inside_ret); + double y); + +cairo_private cairo_bool_t +_cairo_gstate_in_clip (cairo_gstate_t *gstate, + double x, + double y); cairo_private cairo_status_t _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path); @@ -1258,12 +1232,12 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path); cairo_private cairo_status_t _cairo_gstate_reset_clip (cairo_gstate_t *gstate); -cairo_private cairo_status_t +cairo_private cairo_bool_t _cairo_gstate_clip_extents (cairo_gstate_t *gstate, double *x1, double *y1, - double *x2, - double *y2); + double *x2, + double *y2); cairo_private cairo_rectangle_list_t* _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate); @@ -1480,19 +1454,19 @@ cairo_private void _cairo_intern_string_reset_static_data (void); /* cairo-path-fixed.c */ +cairo_private cairo_path_fixed_t * +_cairo_path_fixed_create (void); + cairo_private void _cairo_path_fixed_init (cairo_path_fixed_t *path); cairo_private cairo_status_t _cairo_path_fixed_init_copy (cairo_path_fixed_t *path, - cairo_path_fixed_t *other); + const cairo_path_fixed_t *other); cairo_private cairo_bool_t -_cairo_path_fixed_is_equal (cairo_path_fixed_t *path, - cairo_path_fixed_t *other); - -cairo_private cairo_path_fixed_t * -_cairo_path_fixed_create (void); +_cairo_path_fixed_is_equal (const cairo_path_fixed_t *path, + const cairo_path_fixed_t *other); cairo_private void _cairo_path_fixed_fini (cairo_path_fixed_t *path); @@ -1578,64 +1552,69 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path, void *closure, double tolerance); -cairo_private cairo_status_t -_cairo_path_fixed_append (cairo_path_fixed_t *path, - const cairo_path_fixed_t *other, - cairo_direction_t dir); - cairo_private void -_cairo_path_fixed_approximate_clip_extents (cairo_path_fixed_t *path, +_cairo_path_fixed_approximate_clip_extents (const cairo_path_fixed_t *path, cairo_rectangle_int_t *extents); cairo_private void -_cairo_path_fixed_approximate_fill_extents (cairo_path_fixed_t *path, +_cairo_path_fixed_approximate_fill_extents (const cairo_path_fixed_t *path, cairo_rectangle_int_t *extents); cairo_private void -_cairo_path_fixed_approximate_stroke_extents (cairo_path_fixed_t *path, +_cairo_path_fixed_fill_extents (const cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_rectangle_int_t *extents); + +cairo_private void +_cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path, cairo_stroke_style_t *style, const cairo_matrix_t *ctm, cairo_rectangle_int_t *extents); +cairo_private cairo_status_t +_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t *path, + cairo_stroke_style_t *style, + const cairo_matrix_t *ctm, + const cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_rectangle_int_t *extents); + cairo_private void -_cairo_path_fixed_bounds (cairo_path_fixed_t *path, +_cairo_path_fixed_bounds (const cairo_path_fixed_t *path, double *x1, double *y1, double *x2, double *y2); cairo_private void _cairo_path_fixed_transform (cairo_path_fixed_t *path, - cairo_matrix_t *matrix); + const cairo_matrix_t *matrix); cairo_private cairo_bool_t -_cairo_path_fixed_is_empty (cairo_path_fixed_t *path); - -cairo_private cairo_bool_t -_cairo_path_fixed_is_box (cairo_path_fixed_t *path, +_cairo_path_fixed_is_box (const cairo_path_fixed_t *path, cairo_box_t *box); cairo_private cairo_bool_t -_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path, +_cairo_path_fixed_is_rectangle (const cairo_path_fixed_t *path, cairo_box_t *box); /* cairo-path-in-fill.c */ -cairo_private void -_cairo_path_fixed_in_fill (cairo_path_fixed_t *path, +cairo_private cairo_bool_t +_cairo_path_fixed_in_fill (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, double x, - double y, - cairo_bool_t *is_inside); + double y); /* cairo-path-fill.c */ cairo_private cairo_status_t -_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, +_cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_traps_t *traps); /* cairo-path-stroke.c */ cairo_private cairo_status_t -_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, +_cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path, cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, @@ -1707,7 +1686,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, unsigned int width, unsigned int height, cairo_glyph_t *glyphs, - int num_glyphs); + int num_glyphs, + cairo_region_t *clip_region); cairo_private cairo_status_t _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, @@ -1789,11 +1769,12 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other, int height); cairo_private cairo_surface_t * -_cairo_surface_create_similar_solid (cairo_surface_t *other, - cairo_content_t content, - int width, - int height, - const cairo_color_t *color); +_cairo_surface_create_similar_solid (cairo_surface_t *other, + cairo_content_t content, + int width, + int height, + const cairo_color_t *color, + cairo_bool_t allow_fallback); cairo_private cairo_surface_t * _cairo_surface_create_solid_pattern_surface (cairo_surface_t *other, @@ -1813,22 +1794,20 @@ cairo_private void _cairo_surface_set_font_options (cairo_surface_t *surface, cairo_font_options_t *options); -cairo_private cairo_clip_mode_t -_cairo_surface_get_clip_mode (cairo_surface_t *surface); - cairo_private cairo_status_t _cairo_surface_composite (cairo_operator_t op, const cairo_pattern_t *src, const cairo_pattern_t *mask, cairo_surface_t *dst, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - unsigned int width, - unsigned int height); + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height, + cairo_region_t *clip_region); cairo_private cairo_status_t _cairo_surface_fill_rectangle (cairo_surface_t *surface, @@ -1856,14 +1835,14 @@ cairo_private cairo_status_t _cairo_surface_paint (cairo_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_mask (cairo_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_fill_stroke (cairo_surface_t *surface, @@ -1880,7 +1859,7 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface, cairo_matrix_t *stroke_ctm_inverse, double stroke_tolerance, cairo_antialias_t stroke_antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_stroke (cairo_surface_t *surface, @@ -1892,7 +1871,7 @@ _cairo_surface_stroke (cairo_surface_t *surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_fill (cairo_surface_t *surface, @@ -1902,7 +1881,7 @@ _cairo_surface_fill (cairo_surface_t *surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_show_text_glyphs (cairo_surface_t *surface, @@ -1916,7 +1895,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_composite_trapezoids (cairo_operator_t op, @@ -1930,23 +1909,23 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, unsigned int width, unsigned int height, cairo_trapezoid_t *traps, - int ntraps); + int ntraps, + cairo_region_t *clip_region); cairo_private cairo_span_renderer_t * -_cairo_surface_create_span_renderer ( - cairo_operator_t op, - const cairo_pattern_t *pattern, - cairo_surface_t *dst, - cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects); +_cairo_surface_create_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_surface_t *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects, + cairo_region_t *clip_region); cairo_private cairo_bool_t -_cairo_surface_check_span_renderer ( - cairo_operator_t op, - const cairo_pattern_t *pattern, - cairo_surface_t *dst, - cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects); +_cairo_surface_check_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_surface_t *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects); cairo_private cairo_status_t _cairo_surface_acquire_source_image (cairo_surface_t *surface, @@ -2005,37 +1984,7 @@ _cairo_surface_is_similar (cairo_surface_t *surface_a, cairo_surface_t *surface_b, cairo_content_t content); -cairo_private cairo_status_t -_cairo_surface_reset (cairo_surface_t *surface); - -cairo_private unsigned int -_cairo_surface_get_current_clip_serial (cairo_surface_t *surface); - -cairo_private unsigned int -_cairo_surface_allocate_clip_serial (cairo_surface_t *surface); - -cairo_private cairo_status_t -_cairo_surface_reset_clip (cairo_surface_t *surface); - -cairo_private cairo_status_t -_cairo_surface_set_clip_region (cairo_surface_t *surface, - cairo_region_t *region, - unsigned int serial); - -cairo_private cairo_int_status_t -_cairo_surface_intersect_clip_path (cairo_surface_t *surface, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias); - -cairo_private cairo_clip_t * -_cairo_surface_get_clip (cairo_surface_t *surface); - -cairo_private cairo_status_t -_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip); - -cairo_private cairo_int_status_t +cairo_private cairo_bool_t _cairo_surface_get_extents (cairo_surface_t *surface, cairo_rectangle_int_t *extents); @@ -2051,7 +2000,8 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, unsigned int width, unsigned int height, cairo_glyph_t *glyphs, - int num_glyphs); + int num_glyphs, + cairo_region_t *clip_region); cairo_private cairo_status_t _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst, @@ -2068,7 +2018,8 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst, int dst_x, int dst_y, unsigned int width, - unsigned int height); + unsigned int height, + cairo_region_t *clip_region); cairo_private cairo_status_t _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst, @@ -2084,7 +2035,8 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst, int dst_x, int dst_y, unsigned int width, - unsigned int height); + unsigned int height, + cairo_region_t *clip_region); cairo_private cairo_bool_t _cairo_surface_is_opaque (const cairo_surface_t *surface); @@ -2193,19 +2145,6 @@ _cairo_image_surface_create_for_data_with_content (unsigned char *data, cairo_private void _cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface); -/* XXX: It's a nasty kludge that this appears here. Backend functions - * like this should really be static. But we're doing this to work - * around some general defects in the backend clipping interfaces, - * (see some notes in test-paginated-surface.c). - * - * I want to fix the real defects, but it's "hard" as they touch many - * backends, so doing that will require synchronizing several backend - * maintainers. - */ -cairo_private cairo_int_status_t -_cairo_image_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region); - cairo_private cairo_image_surface_t * _cairo_image_surface_coerce (cairo_image_surface_t *surface, cairo_format_t format); @@ -2439,8 +2378,8 @@ _cairo_traps_extents (const cairo_traps_t *traps, cairo_box_t *extents); cairo_private cairo_int_status_t -_cairo_traps_extract_region (const cairo_traps_t *tr, - cairo_region_t **region); +_cairo_traps_extract_region (cairo_traps_t *traps, + cairo_region_t **region); cairo_private cairo_status_t _cairo_traps_path (const cairo_traps_t *traps, @@ -2560,7 +2499,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, cairo_surface_attributes_t *src_attributes, cairo_surface_attributes_t *mask_attributes); -cairo_private cairo_status_t +cairo_private void _cairo_pattern_get_extents (const cairo_pattern_t *pattern, cairo_rectangle_int_t *extents); @@ -2577,23 +2516,8 @@ _cairo_pattern_equal (const cairo_pattern_t *a, cairo_private void _cairo_pattern_reset_static_data (void); -/* cairo-region.c */ - -struct _cairo_region { - cairo_status_t status; - - pixman_region32_t rgn; -}; - cairo_private void -_cairo_region_init (cairo_region_t *region); - -cairo_private void -_cairo_region_init_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *rectangle); - -cairo_private void -_cairo_region_fini (cairo_region_t *region); +_cairo_clip_reset_static_data (void); /* cairo-unicode.c */ @@ -2725,7 +2649,6 @@ slim_hidden_proto (cairo_status); slim_hidden_proto (cairo_stroke); slim_hidden_proto (cairo_stroke_preserve); slim_hidden_proto (cairo_surface_copy_page); -slim_hidden_proto (cairo_surface_create_similar); slim_hidden_proto (cairo_surface_destroy); slim_hidden_proto (cairo_surface_finish); slim_hidden_proto (cairo_surface_flush); @@ -2760,7 +2683,9 @@ slim_hidden_proto (cairo_region_create); slim_hidden_proto (cairo_region_create_rectangle); slim_hidden_proto (cairo_region_create_rectangles); slim_hidden_proto (cairo_region_copy); +slim_hidden_proto (cairo_region_reference); slim_hidden_proto (cairo_region_destroy); +slim_hidden_proto (cairo_region_equal); slim_hidden_proto (cairo_region_status); slim_hidden_proto (cairo_region_get_extents); slim_hidden_proto (cairo_region_num_rectangles); diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c index 2a7f14891..f331cf255 100644 --- a/src/test-fallback-surface.c +++ b/src/test-fallback-surface.c @@ -194,7 +194,7 @@ _test_fallback_surface_clone_similar (void *abstract_surface, return CAIRO_INT_STATUS_UNSUPPORTED; } -static cairo_int_status_t +static cairo_bool_t _test_fallback_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -219,8 +219,6 @@ static const cairo_surface_backend_t test_fallback_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - NULL, /* intersect_clip_path */ _test_fallback_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ diff --git a/src/test-fallback16-surface.c b/src/test-fallback16-surface.c index 07c061059..5f6bee4ae 100644 --- a/src/test-fallback16-surface.c +++ b/src/test-fallback16-surface.c @@ -193,7 +193,7 @@ _test_fallback16_surface_clone_similar (void *abstract_surface, } } -static cairo_int_status_t +static cairo_bool_t _test_fallback16_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -218,8 +218,6 @@ static const cairo_surface_backend_t test_fallback16_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - NULL, /* set_clip_region */ - NULL, /* intersect_clip_path */ _test_fallback16_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ diff --git a/src/test-null-surface.c b/src/test-null-surface.c index 2c71f853b..59761a397 100644 --- a/src/test-null-surface.c +++ b/src/test-null-surface.c @@ -50,26 +50,17 @@ _return_success (void) /* These typedefs are just to silence the compiler... */ typedef cairo_int_status_t -(*_set_clip_region_func) (void *surface, - cairo_region_t *region); -typedef cairo_int_status_t -(*_intersect_clip_path_func) (void *dst, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias); -typedef cairo_int_status_t (*_paint_func) (void *surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_mask_func) (void *surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_stroke_func) (void *surface, @@ -81,7 +72,7 @@ typedef cairo_int_status_t cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_fill_func) (void *surface, @@ -91,7 +82,7 @@ typedef cairo_int_status_t cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); typedef cairo_int_status_t (*_show_glyphs_func) (void *surface, @@ -100,8 +91,8 @@ typedef cairo_int_status_t cairo_glyph_t *glyphs, int num_glyphs, cairo_scaled_font_t *scaled_font, - int *remaining_glyphs, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip, + int *remaining_glyphs); typedef cairo_int_status_t (*_show_text_glyphs_func) (void *surface, @@ -115,7 +106,7 @@ typedef cairo_int_status_t int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents); + cairo_clip_t *clip); static cairo_surface_t * _cairo_null_surface_create_similar (void *other, @@ -125,16 +116,11 @@ _cairo_null_surface_create_similar (void *other, return _cairo_test_null_surface_create (content); } -static cairo_int_status_t +static cairo_bool_t _cairo_null_surface_get_extents (void *surface, cairo_rectangle_int_t *extents) { - extents->x = 0; - extents->y = 0; - extents->width = 0; - extents->height = 0; - - return CAIRO_STATUS_SUCCESS; + return FALSE; } static cairo_bool_t @@ -160,8 +146,6 @@ static const cairo_surface_backend_t null_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - (_set_clip_region_func) _return_success, /* set_clip_region */ - (_intersect_clip_path_func) _return_success, /* intersect_clip_path */ _cairo_null_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -176,7 +160,6 @@ static const cairo_surface_backend_t null_surface_backend = { (_show_glyphs_func) _return_success, /* show_glyphs */ NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c index d42700c8a..164d4a714 100644 --- a/src/test-paginated-surface.c +++ b/src/test-paginated-surface.c @@ -61,37 +61,27 @@ static const cairo_surface_backend_t test_paginated_surface_backend; static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend; cairo_surface_t * -_cairo_test_paginated_surface_create_for_data (unsigned char *data, - cairo_content_t content, - int width, - int height, - int stride) +_cairo_test_paginated_surface_create (cairo_surface_t *target) { cairo_status_t status; - cairo_surface_t *target; cairo_surface_t *paginated; test_paginated_surface_t *surface; - target = _cairo_image_surface_create_for_data_with_content (data, content, - width, height, - stride); status = cairo_surface_status (target); - if (status) - return target; + if (unlikely (status)) + return _cairo_surface_create_in_error (status); surface = malloc (sizeof (test_paginated_surface_t)); - if (unlikely (surface == NULL)) { - cairo_surface_destroy (target); + if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } _cairo_surface_init (&surface->base, &test_paginated_surface_backend, - content); + target->content); - surface->target = target; + surface->target = cairo_surface_reference (target); paginated = _cairo_paginated_surface_create (&surface->base, - content, width, height, + target->content, &test_paginated_surface_paginated_backend); status = paginated->status; if (status == CAIRO_STATUS_SUCCESS) { @@ -115,49 +105,7 @@ _test_paginated_surface_finish (void *abstract_surface) return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_test_paginated_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - test_paginated_surface_t *surface = abstract_surface; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_STATUS_SUCCESS; - - /* XXX: The whole surface backend clipping interface is a giant - * disaster right now. In particular, its uncleanness shows up - * when trying to implement one surface that wraps another one (as - * we are doing here). - * - * Here are two of the problems that show up: - * - * 1. The most critical piece of information in all this stuff, - * the "clip" isn't getting passed to the backend - * functions. Instead the generic surface layer is caching that as - * surface->clip. This is a problem for surfaces like this one - * that do wrapping. Our base surface will have the clip set, but - * our target's surface will not. - * - * 2. We're here in our backend's set_clip_region function, and we - * want to call into our target surface's set_clip_region. - * Generally, we would do this by calling an equivalent - * _cairo_surface function, but _cairo_surface_set_clip_region - * does not have the same signature/semantics, (it has the - * clip_serial stuff as well). - * - * We kludge around each of these by manually copying the clip - * object from our base surface into the target's base surface - * (yuck!) and by reaching directly into the image surface's - * set_clip_region instead of calling into the generic - * _cairo_surface_set_clip_region (double yuck!). - */ - - surface->target->clip = surface->base.clip; - - return _cairo_image_surface_set_clip_region (surface->target, region); -} - -static cairo_int_status_t +static cairo_bool_t _test_paginated_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle) { @@ -170,14 +118,14 @@ static cairo_int_status_t _test_paginated_surface_paint (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { test_paginated_surface_t *surface = abstract_surface; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return CAIRO_STATUS_SUCCESS; - return _cairo_surface_paint (surface->target, op, source, extents); + return _cairo_surface_paint (surface->target, op, source, clip); } static cairo_int_status_t @@ -185,14 +133,15 @@ _test_paginated_surface_mask (void *abstract_surface, cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { test_paginated_surface_t *surface = abstract_surface; if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) return CAIRO_STATUS_SUCCESS; - return _cairo_surface_mask (surface->target, op, source, mask, extents); + return _cairo_surface_mask (surface->target, + op, source, mask, clip); } static cairo_int_status_t @@ -205,7 +154,7 @@ _test_paginated_surface_stroke (void *abstract_surface, cairo_matrix_t *ctm_inverse, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { test_paginated_surface_t *surface = abstract_surface; @@ -215,7 +164,8 @@ _test_paginated_surface_stroke (void *abstract_surface, return _cairo_surface_stroke (surface->target, op, source, path, style, ctm, ctm_inverse, - tolerance, antialias, extents); + tolerance, antialias, + clip); } static cairo_int_status_t @@ -226,7 +176,7 @@ _test_paginated_surface_fill (void *abstract_surface, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { test_paginated_surface_t *surface = abstract_surface; @@ -235,7 +185,8 @@ _test_paginated_surface_fill (void *abstract_surface, return _cairo_surface_fill (surface->target, op, source, path, fill_rule, - tolerance, antialias, extents); + tolerance, antialias, + clip); } static cairo_bool_t @@ -258,7 +209,7 @@ _test_paginated_surface_show_text_glyphs (void *abstract_surface, int num_clusters, cairo_text_cluster_flags_t cluster_flags, cairo_scaled_font_t *scaled_font, - cairo_rectangle_int_t *extents) + cairo_clip_t *clip) { test_paginated_surface_t *surface = abstract_surface; @@ -268,8 +219,10 @@ _test_paginated_surface_show_text_glyphs (void *abstract_surface, return _cairo_surface_show_text_glyphs (surface->target, op, source, utf8, utf8_len, glyphs, num_glyphs, - clusters, num_clusters, cluster_flags, - scaled_font, extents); + clusters, num_clusters, + cluster_flags, + scaled_font, + clip); } @@ -302,8 +255,6 @@ static const cairo_surface_backend_t test_paginated_surface_backend = { NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ - _test_paginated_surface_set_clip_region, - NULL, /* intersect_clip_path */ _test_paginated_surface_get_extents, NULL, /* old_show_glyphs */ NULL, /* get_font_options */ @@ -319,11 +270,10 @@ static const cairo_surface_backend_t test_paginated_surface_backend = { _test_paginated_surface_mask, _test_paginated_surface_stroke, _test_paginated_surface_fill, - NULL, /* show_glyphs */ + NULL, /* replaced by show_text_glyphs */ NULL, /* snapshot */ NULL, /* is_similar */ - NULL, /* reset */ NULL, /* fill_stroke */ NULL, /* create_solid_pattern_surface */ NULL, /* can_repaint_solid_pattern_surface */ diff --git a/src/test-paginated-surface.h b/src/test-paginated-surface.h index 4879cfcd1..76ce6890e 100644 --- a/src/test-paginated-surface.h +++ b/src/test-paginated-surface.h @@ -41,11 +41,7 @@ CAIRO_BEGIN_DECLS cairo_surface_t * -_cairo_test_paginated_surface_create_for_data (unsigned char *data, - cairo_content_t content, - int width, - int height, - int stride); +_cairo_test_paginated_surface_create (cairo_surface_t *target); CAIRO_END_DECLS diff --git a/src/test-wrapping-surface.c b/src/test-wrapping-surface.c new file mode 100644 index 000000000..a634b48a8 --- /dev/null +++ b/src/test-wrapping-surface.c @@ -0,0 +1,272 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc + * Copyright © Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl Worth + * Chris Wilson + */ + +/* Another mythical surface that exists to simply wrap another - do nothing + * itself but forward the calls onto a target surface. + */ + +#include "cairoint.h" + +#include "test-wrapping-surface.h" + +#include "cairo-surface-wrapper-private.h" + +typedef struct _test_wrapping_surface { + cairo_surface_t base; + cairo_surface_wrapper_t wrapper; +} test_wrapping_surface_t; + +static const cairo_surface_backend_t test_wrapping_surface_backend; + +slim_hidden_proto (_cairo_test_wrapping_surface_create); + +cairo_surface_t * +_cairo_test_wrapping_surface_create (cairo_surface_t *target) +{ + test_wrapping_surface_t *surface; + + if (unlikely (target->status)) + return _cairo_surface_create_in_error (target->status); + + surface = malloc (sizeof (test_wrapping_surface_t)); + if (unlikely (surface == NULL)) + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); + + _cairo_surface_init (&surface->base, + &test_wrapping_surface_backend, + target->content); + + _cairo_surface_wrapper_init (&surface->wrapper, target); + + return &surface->base; +} +slim_hidden_def (_cairo_test_wrapping_surface_create); + +static cairo_surface_t * +_test_wrapping_surface_create_similar (void *abstract_surface, + cairo_content_t content, + int width, + int height) +{ + + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_test_wrapping_surface_create ( + _cairo_surface_wrapper_create_similar (&surface->wrapper, + content, width, height)); +} + +static cairo_status_t +_test_wrapping_surface_finish (void *abstract_surface) +{ + test_wrapping_surface_t *surface = abstract_surface; + + _cairo_surface_wrapper_fini (&surface->wrapper); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_test_wrapping_surface_acquire_source_image (void *abstract_surface, + cairo_image_surface_t **image_out, + void **image_extra) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_acquire_source_image (&surface->wrapper, + image_out, image_extra); +} + +static void +_test_wrapping_surface_release_source_image (void *abstract_surface, + cairo_image_surface_t *image, + void *image_extra) +{ + test_wrapping_surface_t *surface = abstract_surface; + + _cairo_surface_wrapper_release_source_image (&surface->wrapper, + image, image_extra); +} + +static cairo_bool_t +_test_wrapping_surface_get_extents (void *abstract_surface, + cairo_rectangle_int_t *rectangle) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_get_extents (&surface->wrapper, rectangle); +} + +static cairo_int_status_t +_test_wrapping_surface_paint (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_clip_t *clip) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_paint (&surface->wrapper, op, source, clip); +} + +static cairo_int_status_t +_test_wrapping_surface_mask (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_pattern_t *mask, + cairo_clip_t *clip) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_mask (&surface->wrapper, + op, source, mask, clip); +} + +static cairo_int_status_t +_test_wrapping_surface_stroke (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_stroke_style_t *style, + cairo_matrix_t *ctm, + cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_stroke (&surface->wrapper, + op, source, + path, style, + ctm, ctm_inverse, + tolerance, antialias, + clip); +} + +static cairo_int_status_t +_test_wrapping_surface_fill (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + cairo_clip_t *clip) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_fill (&surface->wrapper, + op, source, + path, fill_rule, + tolerance, antialias, + clip); +} + +static cairo_bool_t +_test_wrapping_surface_has_show_text_glyphs (void *abstract_surface) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_has_show_text_glyphs (&surface->wrapper); +} + +static cairo_int_status_t +_test_wrapping_surface_show_text_glyphs (void *abstract_surface, + cairo_operator_t op, + const cairo_pattern_t *source, + const char *utf8, + int utf8_len, + cairo_glyph_t *glyphs, + int num_glyphs, + const cairo_text_cluster_t *clusters, + int num_clusters, + cairo_text_cluster_flags_t cluster_flags, + cairo_scaled_font_t *scaled_font, + cairo_clip_t *clip) +{ + test_wrapping_surface_t *surface = abstract_surface; + + return _cairo_surface_wrapper_show_text_glyphs (&surface->wrapper, + op, source, + utf8, utf8_len, + glyphs, num_glyphs, + clusters, num_clusters, + cluster_flags, + scaled_font, + clip); +} + +static const cairo_surface_backend_t test_wrapping_surface_backend = { + CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING, + _test_wrapping_surface_create_similar, + _test_wrapping_surface_finish, + _test_wrapping_surface_acquire_source_image, + _test_wrapping_surface_release_source_image, + NULL, NULL, /* dest_image */ + NULL, /* clone_similar */ + NULL, /* composite */ + NULL, /* fill_rectangles */ + NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ + NULL, /* copy_page */ + NULL, /* show_page */ + _test_wrapping_surface_get_extents, + NULL, /* old_show_glyphs */ + NULL, /* get_font_options */ + NULL, /* flush */ + NULL, /* mark_dirty_rectangle */ + NULL, /* scaled_font_fini */ + NULL, /* scaled_glyph_fini */ + + _test_wrapping_surface_paint, + _test_wrapping_surface_mask, + _test_wrapping_surface_stroke, + _test_wrapping_surface_fill, + NULL, /* replaced by show_text_glyphs */ + + NULL, /* snapshot */ + NULL, /* is_similar */ + NULL, /* fill_stroke */ + NULL, /* create_solid_pattern_surface */ + NULL, /* can_repaint_solid_pattern_surface */ + + _test_wrapping_surface_has_show_text_glyphs, + _test_wrapping_surface_show_text_glyphs + + /* XXX wrap fill-stroke and show_glyphs */ +}; diff --git a/src/test-wrapping-surface.h b/src/test-wrapping-surface.h new file mode 100644 index 000000000..32d2ca3a4 --- /dev/null +++ b/src/test-wrapping-surface.h @@ -0,0 +1,51 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc + * Copyright © 2009 Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl Worth + * Chris Wilson + */ + +#ifndef TEST_WRAPPING_SURFACE_H +#define TEST_WRAPPING_SURFACE_H + +#include "cairo.h" + +CAIRO_BEGIN_DECLS + +cairo_surface_t * +_cairo_test_wrapping_surface_create (cairo_surface_t *target); + +CAIRO_END_DECLS + +#endif /* TEST_WRAPPING_SURFACE_H */ + diff --git a/test/Makefile.am b/test/Makefile.am index 2e0eb106a..ec5dfac90 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -185,8 +185,8 @@ REFERENCE_IMAGES = \ clip-nesting.rgb24.ref.png \ clip-nesting.test-paginated.rgb24.ref.png \ clip-nesting.xlib.rgb24.ref.png \ - clip-operator.pdf.argb32.xfail.png \ - clip-operator.pdf.rgb24.xfail.png \ + clip-operator.pdf.argb32.ref.png \ + clip-operator.pdf.rgb24.ref.png \ clip-operator.ps2.rgb24.ref.png \ clip-operator.ps3.argb32.ref.png \ clip-operator.ps3.ref.png \ @@ -198,15 +198,21 @@ REFERENCE_IMAGES = \ clip-operator.svg12.argb32.xfail.png \ clip-operator.svg12.rgb24.xfail.png \ clip-operator.test-paginated.argb32.ref.png \ - clip-operator.xlib-fallback.rgb24.ref.png \ + clip-operator.xlib-fallback.ref.png \ clip-operator.xlib.ref.png \ clip-operator.xlib.rgb24.ref.png \ + clip-unbounded.ref.png \ + clip-unbounded.rgb24.ref.png \ + clip-unbounded.svg12.rgb24.xfail.png \ + clipped-surface.ref.png \ + clip-push-group.pdf.ref.png \ clip-push-group.ps2.argb32.ref.png \ clip-push-group.ps2.rgb24.ref.png \ clip-push-group.ps3.argb32.ref.png \ clip-push-group.ps3.rgb24.ref.png \ clip-push-group.quartz.ref.png \ clip-push-group.ref.png \ + clip-push-group.xlib.ref.png \ clip-twice.pdf.argb32.ref.png \ clip-twice.ps2.argb32.ref.png \ clip-twice.ps2.rgb24.ref.png \ @@ -220,8 +226,7 @@ REFERENCE_IMAGES = \ clip-twice.test-paginated.rgb24.ref.png \ clip-twice.xlib.ref.png \ clip-twice.xlib.rgb24.ref.png \ - clipped-group.pdf.argb32.ref.png \ - clipped-group.pdf.rgb24.ref.png \ + clipped-group.pdf.ref.png \ clipped-group.ps2.ref.png \ clipped-group.ps3.ref.png \ clipped-group.ref.png \ @@ -240,6 +245,8 @@ REFERENCE_IMAGES = \ composite-integer-translate-source.ps2.ref.png \ composite-integer-translate-source.ps3.ref.png \ composite-integer-translate-source.ref.png \ + composite-integer-translate-source.svg12.argb32.xfail.png \ + composite-integer-translate-source.svg12.rgb24.xfail.png \ copy-path.ps2.ref.png \ copy-path.ps3.ref.png \ copy-path.ref.png \ @@ -299,7 +306,7 @@ REFERENCE_IMAGES = \ device-offset-fractional.gl.xfail.png \ device-offset-fractional.pdf.argb32.ref.png \ device-offset-fractional.pdf.ref.png \ - device-offset-fractional.pdf.rgb24.ref.png \ + device-offset-fractional.pdf.xfail.png \ device-offset-fractional.ps2.ref.png \ device-offset-fractional.ps3.ref.png \ device-offset-fractional.ref.png \ @@ -311,8 +318,12 @@ REFERENCE_IMAGES = \ device-offset.rgb24.ref.png \ extended-blend.argb32.ref.png \ extended-blend.rgb24.ref.png \ + extended-blend.svg12.argb32.xfail.png \ + extended-blend.svg12.rgb24.xfail.png \ extended-blend-alpha.argb32.ref.png \ extended-blend-alpha.rgb24.ref.png \ + extended-blend-alpha.svg12.argb32.xfail.png \ + extended-blend-alpha.svg12.rgb24.xfail.png \ extend-pad-border.ps.ref.png \ extend-pad-border.ref.png \ extend-pad-border.svg.xfail.png \ @@ -377,6 +388,9 @@ REFERENCE_IMAGES = \ fill-degenerate-sort-order.rgb24.ref.png \ fill-degenerate-sort-order.xlib.ref.png \ fill-degenerate-sort-order.xlib.rgb24.ref.png \ + fill-empty.argb32.ref.png \ + fill-empty.rgb24.ref.png \ + fill-empty.svg12.rgb24.xfail.png \ fill-image.ps.ref.png \ fill-image.ref.png \ fill-image.xlib.ref.png \ @@ -443,17 +457,13 @@ REFERENCE_IMAGES = \ ft-text-antialias-none.ps2.argb32.ref.png \ ft-text-antialias-none.ps3.argb32.ref.png \ ft-text-antialias-none.ref.png \ - ft-text-vertical-layout-type1.pdf.argb32.ref.png \ ft-text-vertical-layout-type1.pdf.ref.png \ - ft-text-vertical-layout-type1.pdf.rgb24.ref.png \ ft-text-vertical-layout-type1.ps2.ref.png \ ft-text-vertical-layout-type1.ps3.ref.png \ ft-text-vertical-layout-type1.ref.png \ ft-text-vertical-layout-type1.svg.ref.png \ ft-text-vertical-layout-type1.xlib.ref.png \ - ft-text-vertical-layout-type3.pdf.argb32.ref.png \ ft-text-vertical-layout-type3.pdf.ref.png \ - ft-text-vertical-layout-type3.pdf.rgb24.ref.png \ ft-text-vertical-layout-type3.ps2.ref.png \ ft-text-vertical-layout-type3.ps3.ref.png \ ft-text-vertical-layout-type3.ref.png \ @@ -498,6 +508,8 @@ REFERENCE_IMAGES = \ image-surface-source.ps2.ref.png \ image-surface-source.ps3.ref.png \ image-surface-source.ref.png \ + image-surface-source.svg12.argb32.xfail.png \ + image-surface-source.svg12.rgb24.xfail.png \ infinite-join.ps2.ref.png \ infinite-join.ps3.ref.png \ infinite-join.ref.png \ @@ -558,15 +570,14 @@ REFERENCE_IMAGES = \ mask-transformed-similar.pdf.ref.png \ mask-transformed-similar.ref.png \ mask-transformed-similar.svg.ref.png \ - mask.pdf.argb32.xfail.png \ - mask.pdf.rgb24.xfail.png \ + mask.pdf.argb32.ref.png \ + mask.pdf.rgb24.ref.png \ mask.quartz.ref.png \ mask.quartz.rgb24.ref.png \ mask.ref.png \ mask.rgb24.ref.png \ mask.svg.argb32.xfail.png \ mask.svg.rgb24.xfail.png \ - mask.xlib-fallback.rgb24.ref.png \ mask.xlib.ref.png \ mask.xlib.rgb24.ref.png \ meta-surface-pattern.gl.argb32.ref.png \ @@ -613,15 +624,16 @@ REFERENCE_IMAGES = \ operator-clear.rgb24.ref.png \ operator-clear.svg12.argb32.xfail.png \ operator-clear.svg12.rgb24.xfail.png \ - operator-clear.xlib.ref.png \ - operator-source.pdf.rgb24.xfail.png \ + operator-clear.xlib.argb32.ref.png \ + operator-clear.xlib.rgb24.ref.png \ + operator-source.pdf.rgb24.ref.png \ operator-source.quartz.ref.png \ operator-source.quartz.rgb24.ref.png \ operator-source.ref.png \ operator-source.rgb24.ref.png \ operator-source.svg12.argb32.xfail.png \ operator-source.svg12.rgb24.xfail.png \ - operator-source.xlib-fallback.rgb24.ref.png \ + operator-source.xlib-fallback.ref.png \ operator-source.xlib.ref.png \ operator-source.xlib.rgb24.ref.png \ operator.ref.png \ @@ -682,12 +694,15 @@ REFERENCE_IMAGES = \ path-append.xlib.ref.png \ pattern-getters.ref.png \ pdf-surface-source.ref.png \ + pdf-surface-source.svg12.argb32.xfail.png \ + pdf-surface-source.svg12.rgb24.xfail.png \ pixman-rotate.ref.png \ pixman-rotate.rgb24.ref.png \ ps-surface-source.ref.png \ + ps-surface-source.svg12.argb32.xfail.png \ + ps-surface-source.svg12.rgb24.xfail.png \ push-group.ref.png \ push-group.rgb24.ref.png \ - push-group.xlib-fallback.rgb24.ref.png \ push-group.xlib.ref.png \ push-group.xlib.rgb24.ref.png \ quartz-surface-source.ps2.ref.png \ @@ -727,19 +742,21 @@ REFERENCE_IMAGES = \ rotate-image-surface-paint.svg.ref.png \ scale-down-source-surface-paint.ref.png \ scale-offset-image.gl.ref.png \ - scale-offset-image.pdf.argb32.ref.png \ - scale-offset-image.pdf.rgb24.ref.png \ + scale-offset-image.pdf.xfail.png \ scale-offset-image.ps.ref.png \ scale-offset-image.ref.png \ scale-offset-image.xfail.png \ + scale-offset-image.meta.xfail.png \ scale-offset-image.xlib.xfail.png \ + scale-offset-image.xlib-fallback.xfail.png \ scale-offset-similar.gl.ref.png \ - scale-offset-similar.pdf.argb32.ref.png \ - scale-offset-similar.pdf.rgb24.ref.png \ + scale-offset-similar.pdf.xfail.png \ scale-offset-similar.ps.ref.png \ scale-offset-similar.ref.png \ scale-offset-similar.xfail.png \ + scale-offset-similar.meta.xfail.png \ scale-offset-similar.xlib.xfail.png \ + scale-offset-similar.xlib-fallback.xfail.png \ scale-source-surface-paint.ref.png \ scale-source-surface-paint.rgb24.ref.png \ scale-source-surface-paint.svg.argb32.xfail.png \ @@ -773,7 +790,6 @@ REFERENCE_IMAGES = \ skew-extreme.ref.png \ smask-fill.ref.png \ smask-fill.svg.ref.png \ - smask-fill.xlib-fallback.ref.png \ smask-fill.xlib.ref.png \ smask-image-mask.ref.png \ smask-mask.pdf.xfail.png \ @@ -789,11 +805,13 @@ REFERENCE_IMAGES = \ smask-text.ps3.ref.png \ smask-text.ref.png \ smask-text.svg.ref.png \ + smask-text.xlib.ref.png \ smask.pdf.xfail.png \ smask.ps2.ref.png \ smask.ps3.ref.png \ smask.ref.png \ smask.svg.ref.png \ + smask.xlib.ref.png \ solid-pattern-cache-stress.ref.png \ source-clip-scale.gl.ref.png \ source-clip-scale.pdf.ref.png \ @@ -821,6 +839,7 @@ REFERENCE_IMAGES = \ stroke-image.quartz.ref.png \ stroke-image.ref.png \ surface-pattern-big-scale-down.ref.png \ + surface-pattern-big-scale-down.ps.xfail.png \ surface-pattern-scale-down.pdf.ref.png \ surface-pattern-scale-down.ps2.ref.png \ surface-pattern-scale-down.ps3.ref.png \ @@ -835,8 +854,12 @@ REFERENCE_IMAGES = \ surface-pattern.ref.png \ surface-pattern.svg.xfail.png \ svg-surface-source.ref.png \ + svg-surface-source.svg12.argb32.xfail.png \ + svg-surface-source.svg12.rgb24.xfail.png \ test-fallback16-surface-source.ps.ref.png \ test-fallback16-surface-source.ref.png \ + test-fallback16-surface-source.svg12.argb32.xfail.png \ + test-fallback16-surface-source.svg12.rgb24.xfail.png \ text-antialias-gray.quartz.ref.png \ text-antialias-gray.ref.png \ text-antialias-none.quartz.ref.png \ @@ -846,8 +869,8 @@ REFERENCE_IMAGES = \ text-glyph-range.ps2.ref.png \ text-glyph-range.ps3.ref.png \ text-glyph-range.ref.png \ - text-pattern.pdf.argb32.xfail.png \ - text-pattern.pdf.rgb24.xfail.png \ + text-pattern.pdf.argb32.ref.png \ + text-pattern.pdf.rgb24.ref.png \ text-pattern.ps3.argb32.ref.png \ text-pattern.ps3.rgb24.ref.png \ text-pattern.quartz.ref.png \ @@ -924,6 +947,8 @@ REFERENCE_IMAGES = \ xlib-surface-source.ps2.ref.png \ xlib-surface-source.ps3.ref.png \ xlib-surface-source.ref.png \ + xlib-surface-source.svg12.argb32.xfail.png \ + xlib-surface-source.svg12.rgb24.xfail.png \ zero-alpha.ref.png EXTRA_DIST += \ @@ -1218,7 +1243,7 @@ run: # Check tests under valgrind. Saves log to valgrind-log check-valgrind: - $(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) CAIRO_TEST_MODE="$(MODE),foreground" $(top_builddir)/libtool --mode=execute valgrind $(VALGRIND_FLAGS)' 2>&1 | tee valgrind-log + $(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) CAIRO_TEST_MODE="$(MODE),foreground CAIRO_TEST_TIMEOUT=0" $(top_builddir)/libtool --mode=execute valgrind $(VALGRIND_FLAGS)' 2>&1 | tee valgrind-log %.log: %.c cairo-test-suite -./cairo-test-suite $(<:.c=) diff --git a/test/Makefile.sources b/test/Makefile.sources index 4d87a2768..573ca848a 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -21,6 +21,7 @@ test_sources = \ clip-operator.c \ clip-push-group.c \ clip-twice.c \ + clip-unbounded.c \ clip-zero.c \ clipped-group.c \ clipped-surface.c \ @@ -64,6 +65,7 @@ test_sources = \ fill-and-stroke-alpha.c \ fill-and-stroke-alpha-add.c \ fill-degenerate-sort-order.c \ + fill-empty.c \ fill-image.c \ fill-missed-stop.c \ fill-rule.c \ diff --git a/test/buffer-diff.c b/test/buffer-diff.c index f9b4a9518..8fc3f891e 100644 --- a/test/buffer-diff.c +++ b/test/buffer-diff.c @@ -70,13 +70,12 @@ buffer_diff_core (const unsigned char *_buf_a, int stride_a, stride_a /= sizeof (uint32_t); stride_b /= sizeof (uint32_t); stride_diff /= sizeof (uint32_t); - for (y = 0; y < height; y++) - { + for (y = 0; y < height; y++) { const uint32_t *row_a = buf_a + y * stride_a; const uint32_t *row_b = buf_b + y * stride_b; uint32_t *row = buf_diff + y * stride_diff; - for (x = 0; x < width; x++) - { + + for (x = 0; x < width; x++) { /* check if the pixels are the same */ if ((row_a[x] & mask) != (row_b[x] & mask)) { int channel; @@ -99,6 +98,11 @@ buffer_diff_core (const unsigned char *_buf_a, int stride_a, } result.pixels_changed++; + if ((diff_pixel & 0x00ffffff) == 0) { + /* alpha only difference, convert to luminance */ + uint8_t alpha = diff_pixel >> 24; + diff_pixel = alpha * 0x010101; + } row[x] = diff_pixel; } else { row[x] = 0; diff --git a/test/cairo-test.c b/test/cairo-test.c index ad74d13fb..630036d19 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -566,7 +566,7 @@ cairo_test_file_is_older (const char *filename, while (num_ref_filenames--) { struct stat ref; - char *ref_filename = ref_filenames++; + char *ref_filename = *ref_filenames++; if (ref_filename == NULL) continue; @@ -912,6 +912,11 @@ REPEAT: goto UNWIND_SURFACE; } + cairo_surface_set_user_data (surface, + &cairo_boilerplate_output_basename_key, + base_path, + NULL); + cairo_surface_set_device_offset (surface, dev_offset, dev_offset); cr = cairo_create (surface); @@ -1080,13 +1085,17 @@ REPEAT: ctx->test->width, ctx->test->height); diff_status = cairo_surface_write_to_png (test_image, out_png_path); + cairo_surface_destroy (test_image); if (diff_status) { + if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS) + ret = CAIRO_TEST_CRASHED; + else + ret = CAIRO_TEST_FAILURE; cairo_test_log (ctx, "Error: Failed to write output image: %s\n", cairo_status_to_string (diff_status)); } have_output = TRUE; - cairo_surface_destroy (test_image); ret = CAIRO_TEST_XFAILURE; goto UNWIND_CAIRO; @@ -1167,8 +1176,11 @@ REPEAT: if (cairo_surface_status (test_image)) { cairo_test_log (ctx, "Error: Failed to extract image: %s\n", cairo_status_to_string (cairo_surface_status (test_image))); + if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS) + ret = CAIRO_TEST_CRASHED; + else + ret = CAIRO_TEST_FAILURE; cairo_surface_destroy (test_image); - ret = CAIRO_TEST_FAILURE; goto UNWIND_CAIRO; } diff --git a/test/clip-operator.pdf.argb32.ref.png b/test/clip-operator.pdf.argb32.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..4213499b4d077395f09507e824d0c95675a7f215 GIT binary patch literal 9340 zcmV-?B!kJR}~%BXD8BL$2V9 zI~N~}<7>QEXPA4$j35r((Tfkp$B3gcXS|au!u2t7&L}b>M<9Y252!o>j0j910>c<$ zpeyNgclG1`QPtH|yLLUg1m^sXS-<{ir;4xF+H0-awfC<5)nc;QEc&ERzI)>OdmGRv zee(AakMzIBMnt0!1PB76QLrpRA;ek8xTsFO7>I~y{*^4r%>v*#LU@`?yWtFdDfNdW#$Sa_V!Oe6*?x*I$oIFU|kEPd`ON z1DcyDUdW?Pe02T4H(c8JNgm~`ZSXzSoE&$iP3m}& zA`xBcpE!ZmR)``v4jc!bM`b&A=VNN?jf+D71AVTMSU{R{HFhQ=jKiUQY3dBwjC;FGq7T+S)Y7 zc^>6$+h)CU7m>j-3gU9{&SrK>TVlYsM*%=b2R3a&aWOI(ij@rwOSVpqyl_5wysZtZ zRv{Rqqktv9?H7qKq=o31g-tFL10>1|EJs5#Cbz}UCs1~T$bOy&+S>5WDrACsT>u~g zY`=JdAr4zP16#M^g%?O&4x$X8V_Vy%yH*vaf*HMqA{y?*)|P%Ryh!@6f6w8W!YWsm z(k>71+sDzoxvcFliNdyRKl{rrBJX7jf&T++1deO-SVEy~w^80pLS%ow*RQFedqk4u z%hBBpzh4tMjzi7czi_2RLsV#Cw`YJ~I0GmEXl+GNkx>ROi~jhzH_s<51b|mx#i>(B zr|GCyL(jdyP}+r77mDb)2rS2syK%lBB+90csJCB5`V>I75TOt}40PTwbq1nQy!j?A zUWG>)KD5qo4+T~6@-to-_9Bl1VtKhf zqww-G0B@4_C@&{`D5ri|8OqBIQB6%~YLY{nPD9KkZCU(S`JXo%qAJ5pr4cR)0GSMu z$!~>1GKqNHsB3M)?M=8{$-R6FJ36p!8;XnRs121(Z-qD-AZO1@pTqpU_Hk9EX1Z{uxPs7Ce6o-A+MX5^Ir zyKzv{A7#%o40?Oz<6QLE1PDeJHUfVfIa10E0tKeqB<(SBBy=b__51ZRM6F(px89<7 z1VF!UzBE{W!RqSpTa^(m*9s+Oj!{S^jr_P8H@=10^mB&~BO0ZuTfM*ft?h%TKiQ8@ zf_B5z>k?JBE}Mx6Af+1U@!uRqHcIcVs;f~sNXY~>%GeoZVn532n@RG^!<;<})lw$3 zF#!?sFAmpVB7i7y$0)Ncf~)z@>hll+M<4SfipzFzrBMm4;WQ$HA_qt>s- z`|oRl+TET1ZiuQ4zh52URaW-&I6=i?s?%;aHM!Pf`un)rFzeE3M5Fq{>xJ6)k5wBb zYmjqOyL`PaX9FJfCCvrX0L4Po)}p#vod)?EprJD?#D0|3mzf)B-kybO3HVYrJ+HpZ zI1W^AGy=!&zFVCe>I=pQ1ps&7ZDgUG`aU1!TuTdDTF8j1|MZO*28JQ})RyVtmT~fk zMG^G{V;`lyV8F8aLbNf6=H3j_u~)qsM+B?(U}eBA@34Vs&a;*E_JVOzZ+Jk zK3~-zwbl4IZy{#S#`LT8eU&=(bQ(ztH7`ep+aHkP|#3nkyD>#HJ)v6 z$B`rSSgOZwEQ{omOEG1FpFHb#-%H>eOdhyV zu^;7>cGtkcbs=Q;hF?>IrAyJ!&^32n*LAlW=_16(GAX{)W2H+y;DPPz zCzcM`2{rukrMRa7_s+u|w;SD~HIx3lGYS)%Q6^HKxvHl0<)ygO!a_p4$&4c$-2p@l1h_Ngl^Pl3q__r0Jl3G>X!mj*g*G|Thim}QbhyJ z$2p{htUJkD=ps@d_Of69Oqadm7QU_yB?C?RDx%j1;C3Svve2a$J5f&Q9yYpvbW3Pr z9g58?)Qk7WwZ`jf5cCo3{#Y0>I3lkEFwo; zu<}(^@(IduMf9m}2SrJJ!0lliEN-|j8fdPIDn8ai7j;{XW%eg%matV87V1+UfXCxx zsmC(P`qT&Dx!92p2V0=14;$G_EpmhUEYA|97BclEQ>e@C*(|bI!>&SV0K?=z%AYV^ z{m5j%FmSo@|CPQ-A0w3gQT4Y+WwUU*;qk!Zf!9lZj4YH;J|DbZ_^}I@Ot6*LliZiR7&3CcLsGa3|JQFwEW3r$S+1HzaN>5{E^a6`P1kzwuC}1 zT@{q_T@gy^8?FADi!)Rp-~@$pnEigrp1-q&Vp%6BIBM6q)J0uX{kx->K9*LWd^e?! zrPU|jQIQ8c_uo&lilpy}1mbbZ`muDYm_MI_5(M=2nxP(eK%;^{=_hjzZcBzNEqka1 z3uMCxvQ=*{VlhJt7c8JSP!JG{nV}Xgq&P4dl~MW$@wf5DqDAz0_4J^p$1Y3DrmkQ9 zQlm@J*xhZWYw===0~M5hJxxM|!xRTfsP1k<6v@&eMA?NweR^W~EZrH3x|CsG=q#;5 zP|hqoODO7ckbNnrUDO3DXSy7$@Y+G?^B6YTMMdSQDn??G{dTsI=uvhiNshCh&eAFn zWv5+w3!SygjxNX9PqfRy<2J{-z7=Q9RP=f543$s)QKRGs-H8Me3ADFk-8u*YN=i^u zgDbDZ#*KL64Goy*F?7dkf#Zi1)M5AFce$GYFvwn=SX0Yv+~ltNL;427&>^3{7C3%L zf+Uk9YAiN3d+OdyX;1)g=nzhxgaQkNFm4SV3>bih25j6&@^^S1BX+(L=sbGl{ISxi za6DMdaR{b`mk-XoFn;i7#ZBwd)4bYoKgZ#U9j^pBkG2oUqj(;{wD7wFGcSxEoX0h- zOHcFZ$Nfi-qN4*mk9ZvMxV%2s+lvPu#Qy!uN`Cp=;RzI$)`ks8BrtrqoQBfwtyBv8 z_QCC5_U zZ$L)^1BXNOBk70N3m!5 zZg}aE4b3h+s%+ES7lQu;9FPLg4P<#h5FXvNvkKhpz)l@Yi|65LekaF9&pnOf0YSj7 zonUxmjagb82e%s?9cXFEPZT%~bLOD56gS_D&Q1zjh2!Ay;IH5R!KN9%R%RHyfZJN< zmt{I;4L{h~;}7JX{wis~^D?UWzy4a8op1tf+daQ5({b(hH7HH?2ZI9IPyb zcr(^?!l!41aa;lW$<(@%?ifZ?;rbs!Q6>P}cOc!1t0thwrRPAIIs-S{faS~S@p2Gl z071kC|DbBruQfhgIe&-P(R;(93CsVP;zN#uC)wLkI{1^y|1Rr_f#Wb|Ps)DQ4a@wKGfCWp@$52hfA&`P;9E_2ghESH~upgevY z`;e@|j)(9NtIB%WK; zy)I~cnCuaEys~@9L$lv`m+nKJhdUYbWfK}*j5sOOx^T;lY{13Q_DXOZT)}jj(=vs6 zdTxVoTXi*8?x*h0;W#jX6m%#+Ky@_?P@2^5-yh?~$q%%*Z9_bcjT>?5l;QM9>c0o< z`(SGPF6jokb<|Je3Guy=3%f3;Hrd7Lc4NT452nQLl5|O^b)y!3GoadRM{zKSt}e8; zA|6L?FNO_+D6S7&`~JRxW)rwr3|qINw^tr?Pn`;2{n6p?A1g6JaU4A9V1IOtL#v3m zh~8}&7KgYI*Pg;aBUKzn-}+)M90$=8!|tu z+h-B4LZb{Ih*;MLTU+nyjlt_yY7H4-90wN<9QYjnbQc65hXMo`qw>>S zk4N59A&N*OJ7s#6eZkw8 z^R;}=w(wV5%I0K)5Zn1_Vd%nOZ0|=lu^F4;G>X(Es37@aX`}t>H z{%SJ|IS%e*EX%mWl2Q?DBJ1-8-Eo(%C1&AyHwU3R!;PwvhAx?kB7}TGgk)(EC>IBG zXOKgoq6i@$BKBBXZa0!ioIWi-4lv)Wrl33?^jtCK>pK=mBeQfA=_o8XP&rh`oeQMl zW?Dd2fb~xLU=ThZ%F3j__U^@=b{h*@u^6hWamy`v)G_OJxii5ee5X++4H~mR)`+RD zLK*GEGLc{qtUHF0)%c&c$Rku`sA>gNIRkt5qTR|HMMX}c3?PV@Z%lRBg1isg1q)O# z2v4%NcW`xd=B<)02*^gk(ch+(N4Ys*=omb@z`i$vLAVM>n(Xtqi%)omDYFDt< zgxjS@Vbv;(ACHSJGHXps3m$m{@4c62X{}s|sZ(*juHFPq6x6}SRqsW|w+a`Tc|&KR z!&+LGu8h`96^hR<2vvwPRPAyU4c`OEIsC~#pqE;xq4>bdxwl@6fPx$B~5?@z``|p>xgG+14GKgUS96WFQzh3s> zrsA1I_D_wiX-GdY4j%(xkfoxUxjahBenZqV&p;4RR)&caF=7PSnzd{3*kkzkV*rhj zY$TFH&7UvtQXe-Cm6aq)n!^IfF)h@(+M;ED5+;5mj3B)sti3<}nBGFkK>OJ*qnP;u zxafeP!sX+HP$h{vogr#zsdd?K1|ktvyBtMXvaoFY(1{O@8!?mg;o3Es$DVLebj_a+ zjyvoh_U<=hw|+H<&^2*S|JK_uAmkO;hdLM!pXegm0 zPVCgz5ELc3_+s35A7;$J>eX^Zu}PC~+im%sv5k$SmjP7$ZEM5dW?frW``SedKj3Bp zm>OGi_o>Hg(k(IyVI$Oa{qm?OJ!^gve|(G)N?K3u?8J%{C@;tK=@>m406zQ>&p(gN zn;{4iO2g6;1OWKr3miX=sw!N0B`&xC0HRTJcgxS!{C<+##c=>GM(2H4F$3kRF})e1 z0ZhV&x8eCw*bE4WlNLJUB}q@)kAH#V$8la2F1r$3&O)IZNiVeunmuO#pm5d-jk086 z=hiP)%sO6PTQz;*m7`}~0N}$l(dQrU-rV99zyW?zmmmPR2!H-*#jzRZ5B}HonoVC0 z08lsb^ldkGkNyYgxtd>>Q38PR!1xmfT3-L%vZ4x1nh9Xw&YcUv*UFEq`~-+ob}XDY zfY*PA911&kf+>;8cIbU*IL+O+59u^6zdV0r$r3#Lu>4)!f2(D8>Ev`8qfR#~M;>*B z7iS{osMfN{sgxD!jW@_{YT!Wh^x)%Czi$-uKHWW{zCuQtG$B3H=90(?vpOGJnJqil;p0 zx^&K<=+cXwDC;d8IC*dniau^OvrzB(eTl&-Hh9HQ(aiJA96;HVzyn+}IDnt5I?@O( zlFMU5AA*ZAB|^4XeI%|$(H5lv0K>U&pk)s?+|juH_hrle-#Y>${q32-p-(w z%R4owr;5VAa_La|PW7v=Amn#ZEyKL$@ND1%yB_H{X{rKLfcZ!c6;s&b|awwdPYC~K;H*|re2J+H2%rM1uu zrLLu=Mp;-0(^^_4LR49j)?qAVRaJOZZvQ>4t_)rN-=%pJDaOxH%xY;F>o%#SWnY)3 zNQCVNJ(>z!COgWtm8zW8?XoFElr`19Y+I-iQ_rhwX=&e{X^0|fX{k|W7D7`?%i^7z zYSC9&I(^z40RU@8hu2)Hd27C%>|ZlFyyh~)ckLT>bQZO=4Ei4PT3YsXsjGe2?};^K zh>UtHU8O2#gDX3tkFuH)ZQnwT*!H}35MfwDj;N)jDMMt^>uYOisV^9_)TdTi;(3ca zZk`n0G@8$G4c3BEF%GRlG zRZGjh=d~kY3W{1wOMSu6E#xS*wA2@jVd~qdrKOk8XNEtUWZZL`qs#|vx-QyQEiK&z zXQ!5yeO>C*w?7C`Co$z_ZBVJoS=}ykF^aM}_3c}z5uN9aYH4YEeG+98DZ zI`vJMI3}ro;O6j`GwD^aOvElqyKTyDEv-aC9Rr)SwCw9r_uuySb*WRIMM4uf<4RS| z>UNokNt89!8f{ys5v}JJ+8}pNm1);%B=?&a!()%IW$VX1Zcp%7M*{BvDG_ zo_!YoWtPz>!l-T+b^o)am`9m-dy8VB_czaCf}w?!Ux`Kme7*45Q#FR3*DV;z+5eYE zALVD>Y@~}o<$d_*qcBF9_4>&q7{=l)4CK$vxTb5#i)nsfLF1hCjB8Fk_F{@3SlC^H zWz(U4sV=6l!S1wa>EFDR3SL;)mC3S6z8_;+ODm>h+t|r|N(HWKrt!ai3H*g7y(zVB zS142nS2HJ;QP#g3l)YwJ==qnriVF1Mv}wubUSc>i6lJaanrVq=U*t?Hi%}|YT{De; z_C@o0WM-*v$rjg~9Xl3{jqd5w13gI7s%6ndLB$F|<)pA$T4Tqeu@Td!yMeP&OG}^n zu#x?mB+gmLT3JY4Q$9mX=hmi(a?O znGaPc*st5AMVWKEs3=QrSHAgro1L+=&Ly`C|KV9$=aSon|D-Ifv(4@5V`=rtcU1aV zT7B{z75chrH%-=XPmz)d_1g-iXsJbjZ?TBAN}i6YFiE3UCIVc!FMD$!3%Z3)g1r ziGN1drS*K>6ZQ5oDx%)BT&ML$uhtvPxAP%A^-Y$&sB9GiB|pkgt=>@CDs+_Uv9<C5g5WqRIU{y z$~@ZA*?62pnWw&V)_|p@h|U>wUEhkOWu&Y_0F7Z}&lwiR*o?Ay>Pu%Sxux|ysmsXo zFhzApXZ?-P{^nC>$s|x@i00&HkBM^iek763iJ` zNO+#qW#oC7q9Acl5g}@6+3}$+`|YN_9hR0p9!mq^rS6C)ZpLoW>!NeJ%sV=sx69H} zOEhYSrKM9$*L7xCTI7#JZL+j9_NfA45-*!kHt+R$0}Cw%JVu^3AMhY*i>0OaA&gmC zTefJXWluk?flBiseP8nKnyh+0@$w^-S+B&>imS4J?Ymh;S2T*>JwloFQn+2j3{^YP zYnr#CX<5F>`4$orK<(VC>2LK-f26c)3sjnS-1SLsC zK~!?aoZ>dG)w~aWendk~omelQ(xObAfqC<=Y#BwDvnbbRH9jQfl=FUHzib)B!YvEd zYIGrj3ske-dG%CXTQ+M^T5m|RUJ6Ugkq@ow=B{2%231L7lVGo^3KR2JJ1L?^8H(yx zR^vuB!^lijUD4|O)o*R1qjcWT=pqoxX260T^cbU59awcW(Sd0RO)C4e|IEl61x4BD zc@L+x(5|jy8qXUA%fuUv#+hU0Lm0k!+@e~#p1%Xt#uX#fJEOvHS84X&tMk|hRT#G` z_bV1GEkbgsZ_d)vS!kv!&tWa3*EdGxyhh_d8S$HKsxBzXMq^aY)IvjDrk+XiJ2nmWys!p);2ye?~%JT^iV#_i&H*kNhWe$JAmr8{M& zOJS=Nl={ZqM-(vRKv4_c!}blQpeP%aXy;8WG}LA4dE;?J6b39UOB9u*1=S8V!vT*G ze@CrJUmN1HYr>ye@vZbIC)_TMv&GUPL=fz-wDbcW6J1K`7c}58MhPYyDC$O0*uLrt zin3AabEXy=>JkJamKL-%l?j*;OUoQ(#L|N5f{|07Wl>&^@^bm8G#@gGrENuX*?DA-wJw%LIiD!c zO>MWJUZAY*%c3N4LHoM$C_lr4%}>iV@04e3G*S2ZDrca&8hiFwD=jF>`P65a1XyKi zTYY5bo;}u8?pQxl&a&k>&u@8tr%9BRBxe0gIoR@?H@0lv$r*b?N#cThNT$A8y1MKx z8>{87KM5Cf$Cu>9J%ykYmKH(<@G}&a*4%jopj5id^I1*LwV(YOW~0I|nm5n*ae=H{ zgu`fv6gyyPIjHUy4!gq-J78(q(M6;_>}4c5Y7d9mh_!`Oj^bIWz(qa_vu7bG;jkz2 zOG^~Faup7aj-wEG=g!t=Nr$_Q8y^ zERmeWFfvn7`67KxIEuEIjamx}U^ag1cIm6uDYfe~d`M?L)IAcDIEvJ&bw;{ili8?4 q*mV%KrzMjpaBiw-;Lg0000Ipdie5ssrH_lzPVa6}>q@kEhFfDs`Rh`=z0 z80bnm-Cg~-e^hmK)vjHSE`d3}W7e;K+Nt8}wf0)8cI~}uf3=uwHj6&#lW(86{?-Qc zNuT^}#3TK$z8=vi1ObA8XcR1qPzbRY_V34`Lx{&om~^WkQJp73orhyF>`zo4>KS-; zQKXzYh4yx&QmCjvc{y?Nsi*MJLo`$}iDVKU4}3nj$je?qkroQ4LPC2in%XZ^91_ZH zwu|^;7uA^*I+M|uM@aaD9+ypTm^#C_UG}0(>N=5ZKb%a#Q&H(FA86Z$OtPd{?2fw* z9A*!-8n%n{#=#Rz>sJ7O7~I$XGW#f@^{Xg&0i0lrl2f1Kd@Fo@j@PT@}nF6qwey~kMk&RO`Y%Q#^m_3h04p}!&tQnJ9p;WI&>(OF2%TU()s#& zL?XJ>KY0=@Ef7U;95@aW>_WIdjO~aO_xY+Jt-WMMDE!<;Xp&=B&TVl}Tw(V$&u}x!3#K z2JyDDf|6y=9;{xCGiSi_`GW@!;-;JM^wYTcX36^$)RrwMDk9TU6j4$Fx0^u87GlpF ztajlHkk>U92RGrSd+~Hb{AOyq%tfF5GHTBrtlxr6Q9fn>L;xbZC2`SB{WU9RfZnbG zqb%!MwP*ERTh644c$I|*n{d+<@#)`|+ZjliA2YF!>HD71AVTMSU{R{HFhQ=jKiRz~rNBwjC8u0&%a+S)Y7 zc^+kL&2!$lo5)}p1#zW#S0g*MEiv$$qX3|z16#JBxEPrX#mc(6W!tAjUc8Vz-qwaS zYY+_5QNXfa_m4yv(n561!4?;a0TSf}R-&#EQ`+Je5-2-DWIxXXZEbjG4KhK!E&vb# zwtqaq5QnXtf$iJz;)|p%2T=yl(cHG>?lr}!U`B7Dh`PJ5y{Z3;FOfbR&~s$Au*Q|8 zw95nh`Ux~{Ep0nOqR`y@(?9Pa@?N$O_-Eh);Dk1hB^28B8s)ttME2)<{pxDEMZ2dj|T2vw#ACmKGEh8D;Q_=#QR%^FqQx0C?>+oIZ_o znvQxc^!$qqrCn%op@^P~z)Jk68yEUPqHGF@diyn`PXlxd5emV>K<5opXCNBIn{U$M zRd|#EwEXm1@FsbWvNFPla_X0sqO8mi)zE;32066pG{juemd1~l{b{Qqsv_J_65*l%kjWsK z{6;7wlZeNSy4D8V(SSRY+{?GHqXW&&C@!X>Hdi#f9a2(OL6vgJGQ?pJ0JSc)h4xcF zn?)j#L&ZDrr)Gd|Au1|R5<-+jnL2}%e7kH%S&d2_?}%@0=51K0M)l90Dr;*ta>~Da zFu36lvga8Fy}j~rE_!?-1S1RUfj^8ICFKTz0@H1h_82t^I+UFH{relD)~>}{Z&5q~ zp#Rrj7_7fwZB_WKiU^l$g%UHzC?u0ceq4*2-ojk^xg$pqjZ)REJy`YDCxfX!*`H5> zcEi={5>>Y@n~4Y@r5fn*Umrm>O7E_!s!%al$pkgZ*coPGKg#NxN%D&$oIMNGQYy4D z0zHY>9<2I(bA_Ty9UT7T7mPvb*8|P7W^uHW{K+p2eF$LIEafK|)$mGA{a}!e+O!E9 zH)?{~-JSn#h^h&1tcvg|D|>pJpkguAX}6o2T$?asBd#^fx^x=RsQ&OKp=RUpDx+i# za&Bsuuh->lz@xsTxnLTgScsY$R8^_dAb$fibcTi4kFxqQb0f{$vrsJoU&^NE)t4E^ zf$EKV;P^fFsB=So!5EaNHH|rTQ zFusO}raJX$&af8yQC8p0*x{FP_AFEjJA8;u&#Px)+%?0q5QrK5vmA$o4-mPbxnQmt zPVphfVc`QN7Rsq#Tntf!*PB1Fe?Ru^qxe^Sq`0zNtf}?x_%M%}8{Rh~qQ5JtonRlO zNqv_KB_-;!`|;gB zl><;yg&lbdF?TLzT&wS^)Tys?hApulWp(Pi$_JFxR^dZy3pKhf8z2s?@_wF2?HhK} zzKbZHSEoLIMfs@_gUSwksT_G@*f8#ah+dawm~=%shF=U73d4qhhEj{1`YfyQY(ZkcJ8-)i8#^PLPD3gAI5~ zu_!|L*CvWgeTI?xx-Nve5VCv2udc@O<*2Lcn!ljy`a6tt5#nQ+6kp=8(xo2oz;^Z% zONZ>lYJTN%+*^nH7U0f1jPB8zNq^oMg^A556RFQ!Q(f}Pa@=KMAtB!JW5vgpdluK7 zp1+EfCtZ{Hr>9dtez1N1e12iXNEflH%TBt6|Mf3%Zyj!%4`Y=2g7K(N zcsxiZkxH43BlV&6-1);~?UYo%3X@TUZq#QBMW#Lgw>ur`p8`|ZK=;;L(-Ue_MT5-8 zIi!WGJIPz|p-f8xU4^TWiHDcpA|OmyiVXt4MEke@OIrYOVI2jKHrM2@;( z<*TgV6O`kM=u_Vgijw+(+rv0m+;Cqq$Xpjye5{2o>b4xq>`%}vVJj^x)TcfGkH^VU zk7bngsSm(&sUsf_u|QEDHnNvn+%P?z1aS!A<@U4_&DhRJ`FKViK3 zk;#Bz;Bw{vD}9kZMkxEE>Tiz9X5n_j@U z4^jR+yWRlc^}_FmC~7{bl)T69Eb3wyuq@JP`IE_zUyM+GKQbBlBc-46r_p0<358s` zDk$ZJJpipo<}jKn1S?QA2_qwGwQ9A`hBrBxux zPP_CLI%}65U5>M#XqSV>ZH{$)BhH$s==0baDxdnJN6Qbo6A2^|Xm7`c4G;wM>xb%U zTzxgRZNuu-8Zgge*sj+DCt4NM5%-XHxtjqn$X=URSHpa;#a;XR^o@j}LqB^xaH3U$ zB$Fg+96o6D)V`V0pa7t?6{k)?frUaCKOO+GS!~{n#>QthkBWRemqax;TCu5#? zM(_so97QWN0Gos_G^Aww&4XoK z>tc-`WH#>zeEbRN!=YzBVLfLOAz%DEz9iT$drIFsP$8`m&zRUVc1-r8ox#`s)kUCO zZ@li>-Rc&=rGfz03eGiap4$z#D|^+EwyEHnz`dbkX-O!T09PvL0_Ot9%$mnAa4}h? ztqtI^I)-k3z%yb5SQf{RLlkA#@H_$mtXP4815sCpjT=e+4$ouc?pFhy$Bte&PFfX? z2a7ol!L;zo;n^3*5C62dVMBVlS3Bs)j;R5_JMg6&m))?esgH{#qq-nxP}es z=|26q|JX5fbb#j(k0TzJ*XMeB@z6s!cyL9(Up&=1k;2m2ycvlEMvRctP};qfO5wl( zxZNw>z3i!H+M+(Ar92X*q~8fMc(2?l_j<$Bl@? zABUeU_5$b?QV-2OaPY9Z-{{L)k5GI#{KWe#636)AqT8SH1mk`W&m-VXt+@NZz(MZ1 zmoMAU=+dJ~x4eBZ_>aK>DFEF-mInmku|2yh!QBDu*0HpB9NXw1nk)j zhDX+zrNwb@yV22srl$Nvf#Wc59!g4Z%Pr{aq_9;u4jvEw^4;%knfWVahQSNCy=7r( zren^C!<{|;K4O=iyETJ20dPqvba-030w6t4ko> zf_0tn=^0@hSHONUwXUQ)hLM%H;RjHZ3BV`2knY7b6Vc<+bD&I}fg5kc%9ZqZIfycV zAYwzlS2_Au8XvA+xJ&Hly>ZFJmH$NXA;-a!?CmHS@^Qugly$|xahNx1SBb0lmd7S` zcF{c_hp?}_JoD%?63P_?Ct&Kf^=061uC5kDKd18s$AN)>@(b|jGa4UmTMzIUTMf~# z_hCNurI*vFhl4&JYHRWE!-l)VC07zCHr4aJ_U>KF%zf+sxs2N7NdI6ad3?|}#2 zpBBGcx`A#V{gZe?d~ej^u8XQnc5%Ah7Mb4CUrga_F<8|8O@1xVl}Ke;>XUpMb#C7&5{*4lW)z^cnu)ZU{gQ1qd)k<)^tG zkG!Ws6p={CTSxT#9kO{IWccrhgDa(JlP^>h5BM6(DZCSNRIlFx1pt8nG8uWAmQ2Fu zYx<0B;;*%s-}m-{VbH(7vW=$cQ?EHoi{s!)2QtW{!HP&GkYwRYfNg@AE@!FF^GJGn z(T~BU{gLn?;X{cRK`$;c<3NGp41D&P#Tt(6`2wR1Ab{S?cNn&^e-geVe7+*@XFI+8 zwPqG_9NfuRmT`&wN<^@Utj`;C$6darn1$!v9E9!+H@Z?9x@5|W5b_BTlBGqUTpZAy zK@NrTB7}U1*kftA-AE>J=8XI}z4D8>Jb}Mfb6*-AAfFNSNu~nsu@;+=AEKtE9 zJjvePAyv`Yw@JDnAR7fof16ew<>r84WAWG```!o!;VK-JPksIP+ft+p#_KI?Ka&&y z%YCyH2?mu>y9vXH6xBmfo2XzA9#_zZL_w^8U{FK&F979gSwMK)a*`PzR~+g~*^VAF?cv z7JZp`LArcCK-w94?opae%MM;~A@$z|uXr*;dA$Xr0Knr(r!5#p6iKBVpxmtIys-jU zcgg|E3{uV1j%4I4Z_am@N3>QP07q5wFE+=dMR+=chY zIB%?g4I2Qkjx2PR$IdJ)*oV&Ab-qv(s!A#)vswsli~0y5=ab!n^UKo8WZ-ha?ap(x zlrPdVc@M>fX5232h!IN7?UKGo|6V$Bw%P^2>y;OXlw~4`w55DGi@JP11OiB1W+yceC&B3xqT4V{G! zYiV7+I$AwVD88^DR3Xk#waZbI*UVf!Vd=C>YRr5{(G^+!$HdfqodXNfwSkHJd(E{% zRgJ0Vu@so8_8}9ATA}nl)C_pq+VICe;-im9d~GcrctG9`F0CcYAcg^O_<{-lcEv+m zif0qqKP|SdF8$;S+ZOGPzud6bm>hNx$sg&?4`6q6=l(}G)$FXAvfci)_ z63L+!E|hnvj~|bU3KAvFVFBcr7HVB>(b7K(lRgqglHL&3KM;RhZ=qzM{p^=f%t8TN zbl@=I%JD*|f<&Fk5Vf?_x@-nzZ^{HnlvH3u+B}(sD%Kx9sH~1mkU#76R2?=@kQ`Uh1M9o55WsGl+Y0; zcIs;gijrJZ%^Qfsk>wX-6VyqELT2Jom#Hv*&E5nQ#7&8U{KKu|bynwA+ zAqWym!_pE20QmfKoH&8XN?d(4F1iQ+qEU2r%g@#Pev;e8aR4qw=lxhU6J={LqY+~O zOvZ<|7o(Gq!n#ge&G6Y3Ma%~2l z2gfaYDfCFhW3KCfFen}Exl%CGr8m&L@0U@`Jh{xJ)Ng?k1`LU&i-gW({)i_OPkGFB z>6}5)r58I<)>}Ae%8(uu?PxT!Q1AHzi6JRAc-1h`%=64VK-rVP16(6GfS;l|QV%YY z%VR?yf{QZ!glw_;NL-7eElL9bMvTz>xnc#Lf1bkMA>^vB8`XdQG8q1)JL09iok1;E zc4|;h7lnW6(xLR7>X%Tq`&Z zf~n_qx~6FVtOs7y*V3ZDiy4|aD@H6Wb5U1Wk{(9bk(C#OR~AKB(|0=P<=5rml|>Of zx63@U3~OoWQ(uiTsHJ6Jm$O=08kG6=LRFRMV_3(ZjK zT3Tw9g@rJ!rDY;Sl_hB%#!}W)hS%iw-_z>K(B)q*&!b2&evV>ROUqcdNi8k=x->;1 zY(MDHRNyk%QLe32<*aU(O(CMJsrF^tLXDVuUR_H|`}Ryj6j4h{jWV+knp#>G@7z?2 zzRJ>>Gv){YST`oT?sCmr^X+8+x-sE(R~Wu)->9RrsHJ7l_n6nxvad^B?aO{otSLie z)MM!?RXH16*%5t|)s$%a7HY({=e2_f!y0l#EiFwMB9mTUTT4rQ!I-5!waOCDTjX)$ zsng009e-2vad`18g%>VsJURMVWU;5a#pv?Qm9e3PJOFd zTJ}A!9SKuV)LL5V3x;kXN2#TyzF-Vf-%c$py?i!1ymPW~&uxw}AF%1VXj`?kbQheR zT3YsXsZ-znAVi(Sl$*6dr7CB2yUfKX%Ieg&Z=ptXo;RwcrS0`elu<1$iy@goEiLQR zH(}zKr2e5>!e7j$SH&_ByD06pDZ90_5(#w-Y}V4UuS?y3+uzrvPJI>$P2`L#RXMBM zWg;d~)>Lb>ZJ|cAo;RtbrA_^WI{Qs(X{nQ#w9vSgmc@YQtFH>ErKQM`Wo!O2@s@%r z_5f&qV$I13x7fW}aslu14(LL$-Ftp623<>^>l!u3?j0$o>noV)ifJhaHZzh$DUo~b zIsCUdMxzL$x?R-$&z52yW#a8EiiO^Pd=3*0Eu{QPGz#FW#m}9tHuSu1!BEcrKR@;u zKl>IVT?8uc!^a+jG0LphPbR@I7H?r7e{SY=UCUld^MeW+=cH#|clz;{Qv9I8?h-7U z4)srUF@+6wr%zA+!ycZc)6>nKp#$@o_zjghBHG^*2=G&o_Ovh&a|=^r2^M=)A{FK zGOtHwmim@#an0Fr<4|Ako-rfPgEXyL7F`rntPoUA3ah0xZXD|CF=K`sI2X0F^r;UU z*{@0BoQ15Fh150Wb5u)9llnOeJq7tNhw@pWG^uaf8=BO2grc*w6jBU9Z^>k|E^Cta z+Z4ub$)U~%PbH_TFqBG^YF`RhOZnn<8+M%L+%BpQ;k0g-<8i-Kw@YGaN#(leb-SGT zP=$j1x?Nh7Ik$_7vgCH$9_n ze@54(^?dD_YWc-SH{j1YHVuTq5)Jtfp7@bC$uP2`i`WUgXc0a2 zZARIAU!)%z3l|x9p46rFyh^N4IbCXyGau4Z-)J6VUa3lLXf&En{d$BWFocn)Tq{VF zd9VxPkrgE0ZU5}oipgVz7b2yNLhyf8pFt*Gc1g;8D;a-m(EghOY3=3myzdT zit3Qg`s<;|Cucq^px0lv%%VaYiRuJ^$6Vn^j&DU3vU#TrP?qn{29{w-B*&bR#eCD8 zAOKkQlqV9=`a!EpzmJKk%jUWVSxbv}@JK2X0Knr>I8b(U(e}Zc{WG=bqintOJmIuPi-4RdRjNPKwMdx;zcXT{&m!+ka zXw(i%OQ)Ew>+G~i}I|j#)rh5a=~wBtyn>^aNDBw z8eNFsBGs&S!7Qq-ZCkY{tv94uFNLM$$cNT-bJwmVgQ_I4NwC*chKc#BofOfd3`O-T zYjKmBVPqz%u4wJSs<)cyD4jPnx(I}_8L*%SJ;o?i2Ub-@bYNOSlgd8rKQr=1K~Xk( z-ot4vw5#j5#`8wOGVw;eapsu$5Qc9ax2Tq`=kGwZam5Jr&gk&lm74wc>O3|=6~^t# z{fY%ki;!IEo3pfZ7MkhGb65-M^^H+EuhBSAM*L=*stby;(HNC8wa`$PsppkT+Q=Jv zmX;k9K(e&dD6`b3@^=87J}rNtrcUGJaO0Q=ugh8`kBv};al3dPc34`ppR;6X=}wvH zQrId5rM_|Z5d{o6P}G9=uzkZRD9T19+Idq84Rx7%-gq1lg#k;;5=CWcLA8U;aKK~4 z-%)GQ*M``6UHDTgzLg&3gxke&wpdz(2!b7!mVUrvqDx8rf(AUsD8YmSMcpV0+gDvd zQ8r3_&eTFfU4mf5(t@_8G66GUX_=#pSXxkBFmmd%EXvAIRwf^n=0irYRF0QlsF|Tk zvtG*#zM!1BK=r3I>$SCOU!pz;0tBJGYSz(x`W1JbNE`WbQ``1;b|2kmt&3$*#wW^h zQ`>ErB~VuPWl@s2pnY9=l%L_j=BH&_cgr(2ny7nyl`~LPg?;<1l@=7`eCjhy0<1E% ztvb4U-#+UqcdVZ&W7)Et=eNDE+a$_L60?4$3~X7>8{4+-=8V0eBymALBvW54U0rsU zjn(p(ABPLN<4bb#-a=3cOADa__!$aIYyN@)P%2&K`K+er+RuIsvr%CfEm&ZFHEWoS zDqRlPDwa`J_xfrJoq66|mv#=5V`_nM( zAYju%QWA;OeLqdzZ{c|zDJ+p#bf3{UM-d7~anXH7;~YJTOnp1GnMjv~!%SVIxIk7e z!eP`!iXE`D98`A;huz^v9I&+P=ps@d_A-(jwTHuO#M(kCNAVn0;3A)e*|U(8aM%<1 zg(ZqyxeABbNW>CFu0h#D8TR_H;Z05Ihr@_O3Z|(zL*=Bfc!$H%qxo~hZqcW{9h4^Z zZCglP;Wllrz%n$)+AGE05Q6oLK=(n97Sr?IwM`M$!yf2 q>@XYqSXzDZEtNi&R-b%J<^KbQMdb{ow{2zs0000@O3Df=5|;M?#&!g+VX zJ{VDXVUG1N&g|pc9}!p+-1#v3UTP%^pT$1-h;U>A9)_112X;asdFqR-rs}1K90O-o zfFXDQmJ9KI4R*nC{{%(75=J>oTY=|wQEr(JBdLE14#U;(IVWK?d;>NqO+LV>{T%KJ zvxYf&jMbmx8{cdh3*Z6RFBIBmaST2O-vr+^bck}6w#so)4!U;D`Y=fS3-E@Xun9K#20DYX-NJ>t z^{gVB3Jq2V^fbrfZhiT}EUdF%tXG5OR>C9!$U$#&tRCnKw>=C9ykQ?@k(IWsI`n%- zZ=r0Ave=?(u#)(&!3t9UxB9c!!JjL$>Nb9>YgH6kR|v6!m^rhwEf|SqiAcQ~NK!)a z31yiagxj%hte)icB}tUU2YlML8qU6rlHT)%KAgP|>%msw%_+^PtKm<>m!2 z7ow~IC)PYosmv@J$n_FoUqZL9-Ckkap4B64&nB-jNun&?W@+0JZ!@(wRCzDnBMx_F zqlQ)0Ux#5>x^83l6{>aVVO(UmpkU2+Vhso^tXZ*8)~kUeCF~crvrPSpQ@rh?EPk7% zZL2fbdWEve^UCLa{0(D9kouRP8?Fd{S_U6fU9@rJbuNw5eUHE@vaFzH&39rA2rS0o z9^r3#mKnNwHISr);#1%L(I}?AJxfgetMH~ZF@SxP#neyRRwMOarzAyL*Uk}d5Qi_N zM(S6>o?Q&@)m$+zY*)6?6AU;OSzOSv<~y;(W)jhW5Rf`u09-K&)XEx}XLNV1fR*7&`tFs+;NB zPwi0_6ilp=6Kf#MVl(WAIF=6PdWB$J!v65CWeg$%P?oIT@NV7dVQd-YNb09*t5e+h z36;&1_QRtw?zM^qh-f&5!Kcu?8ah&%iM{<5)^` z#?>ndyAt+GM{HsskGa50W0!zRjI(vkFRbw>7|p>mAUxtJ@bqN#7kil#nr&T+uOg=JAfx%+weX*mP^~tm6d~8s6h>`NFQAZ zJysR2KvnpdSwIac&?``a-PU>oxB@fK9sYDdcdKpHp#q)$r$gG%v1Xvd|9I)wA$$xh z{PP1=ussK5>gz^i&2VE)JF&pX=(FSwaWmd{R1>cO7_e4pS=#!?u&u!2e50*hDhCEEc|6Ty6;%%OSo3u(S)~=h zpueGfqY*n+=*ChGW!R%-DlI*fB}|E>91gNaqIxBo?`^i_Fv4rYlJgjgdMQ{z>KjZN zvfpNyTxQvHlAN=@Wh$*W$R%{EmyIpw?2pvT;dPs{t@Jc&avr;|#MJ+p|MIyPdSNlF zfjqngC*Y^B67CPvOY3=cDboS#EVmxy6F`poC_h-q#5ngJ;x8fvUC(Pvnf49!NUY=I zj2z-Kk+QCbrNZu6I0!%vMqwq4v*VCU-tUm^mhyT|FBQCTmc<8I1JgM!k8)xqKOJY~ zp{O^?Fay&t9p3P^2jPlJC0+8*nSqM1;e7_7rqNa}g?9!%gp0mDIR}3NBd{9&NGjp0 zswjISu;152+1b{At895=#6Qs3DzE42Qm(?R_c_b#L9W7Vj@ePJuB1Lr?vTQVSEWx~ z7%}&X8e)kJo|mBlw?MaF+!9Q~R+xl+uu{_0ls0l|5!1(cuQw`ui9RUjnHppB5Wm{Q zzZ{+OtoZCNZ{!z?m_E*8fmO;gHOA+M_|+z!ILaERMxK!yVUZw#z63xX#$X6GvGr){ zR9YK(c@dT4zBew>3#B~MV{9E_aufTGs=Q%6(Iqm~*?|Qtf`w3mKIroYEBj$DydU0z zTUE*_hbU)htGtm}W0X0n@J7if2UGh{O#N9{2*W~0p$y-GH{k%>q*AMtq4pf_eu#U8 z9!BXgo?gg>Ar8-QlQ4201i0k0Mugr;*=Kz>%nD`ybMR2ODv!ZJ7-G{*>r`4$g4yR- z_)ypzkMXUAyg9^y8Lc<$=Xi;>>|1wYy{6zS{49LJXQ3Mo!4^#k9ip72Ezk41C`VqG zh_>q3VvZ%IeocDkT!nG?ihjm+*?(u*U=2{&$aBkiV#dU(MP5%1P}#`y%lVp~rN97e zgypQ8X{ky}>5T!Z8yR2DSB&*aI=#_jxpi!&rAJ*4{2{yspR})+MU>ram0U9_`uz5z zY8P}X63%(!GL53_>k`bKq-RfJZ|G)X88GEKon{KEaKYbQ28-iLc-bk+ZnmbJ zY)!#zILbDdYBKes?QaWsH_VlU?TyQF4St!l%V4*ep~+a0wyA@j!+U;TO3u2HoaG_0-pZBbrisZ?OHj+OURm18!iRFVEE#_d zKrLw!`>e~!S-5&L8OyhoWgfe+vdpb4Y-Q$o<%mR=uWE^CTf`#~WT|c;+uZ7)@m}52 zY6TnKJNcT5Wzcp7M|3Pv+jT|Ic2zYk+GbQ*-k?n|bTi|>d7aS=xjNgb!ZdV+Kb`(J ziE?L+^``?y}S-%UrBrM8P}UZv$`tF6*%qm4G&XromKTJ1xy z7Va?qCjSKNf+GR(2p`zRrziLWgSKm!i7&Hjt%CI-gSJb>Vi!ypD>DpVhPBY7O6v$i zyI4D6^oCr*Y}eA-058J-+W8~!hD(&Qv~`4?yBM4>dP9hEQ$CDzSeL-Z;bRhi93JO=eAyCXfJ;@7Mi>{2)&~`zny(|@e+{JvPL4=AID-Zj7e1)h3#%>&V^{TQAWW~=U$YR*SFbC`V-e0MkN$5;i7 z^86$G+b}1*6N)C*cLdgt9^qeyIca2Z7$#u1e*=udBQWfrP;8A#%d_>%!+d>$BfD8Q z#t1OVk00UbVc#243DeUh=~y?x1Mmj?5dIT@d*E;2Zpiy*79?)cC}(XeF3NpHwKvSr zuB9d8cIbrv5{^XIoRZ(aALI9-b3~ZfUF1szcEz#ofUe{$2rt7|WJjSDYiX%$-42~2 zf;UvQvRq3`W}SxtxXZ|r5g+9&ZPg`P$H>Frh;XDxzR=ROv}C*--c_oZq8Q;9;%<>I z7Wks1(vn%CJ1Fw79V>()TMI2yY00)i-q6^xf6bW&>-Qk9I&SucO_bkGTO;9J;kTDt zww9I|qME78l2v3&fi1$AuGOscB7aq2i%Q#NX0>uHtt7VG*3!z7g_AdOPOE*n*%DbM zTheciTd~4Wtfgf@M9tK1Q@tV^3T*IMgE40}Sbr(7Y|-+yw366zTO`751ui$1B_iH% zTkXrumiX(LT3b@yTd^d>{N|Qllxn7uIgg8s6u4JanpoCI^1M$;rDbnR z{26rn3ubx4#6szflu|!--7bYKRo-KB!>G`>VGOAszm}GaA|EcWJb6~RvC>*gD~T;J z_3ghy#3Z(7xvkq}hRz#e>ZfhX)VR{*eGE&F_|!KjakNQOl$o`nbLIUnNV{l zR9b?qSZ^rTbB~RI^5=qMS;{fxl-9R;d)Dm|JRj=~W#%Mc=~P;QD5gXDG%h{dpd?VY z2&@D;mEq7{x;mAxtqx&%FHfu0_%T%d!_2Jh(iOv??J}tNo!jCyL8aAuEv(x$9A%lc zT}s4iyXMeBl~$J8F0Of%R+ic>u2Yp(mfEg1+GwMVHm+~z=9i9#XM0AvWp(A`-W;a_ zoeK2T!!yrvTGr3QtR6d7v_Rp%Hl@;%t`_n}J?xF3gxRXJBCPwu=R|6-UE>X_C}(M_ z9=4SWd!ruqMo#MuDQZ0Vk1=bY)brJf>@2jNrG^_Tu3lg~8I6 z7O_dJR5Jw=S9F@1PZs!;UZtgDxoNx7P-*E(sI=v#VRd8aT7Z@pNfc#=(LZNf!7Z)x zys|eI!_px7bF)gaPR(?qzoG1*dU`AQPeC5*SPt5*^w!d{w-u;W5)~un@u7io-W%3; zexfMrmS|7ImMIS{)GCR5*cl@F|Mie zYxuRmy3c4UV1m&En3 zH{yOpOw3+;A4XGO!~*M~+y;utC0am{cR8`rUP~)t%j^wNo@*b2)+!s_ykRyfrheMC z#6HZNEn~mdgI3vSM6|&p{vlS)B!4T-FEEfis|K7{orR3n(z3KQ5Z+Byqv*zxVdIU+ z0CB3eBFdObky0W4%5EA(?Ni@I%@nFe5en3kE~n+U;T%|5tfiI2)_`=xCI(q58)ewk zOMW+!o~_WxRS^nSw&d(hpixvdcw+gD)b}$unNFoS78&SNlGu_{--eZ?vQddxma?0h zlC4JSC-J;n_L@>3Upyx2!NkwprNg}t+dOUsi&V2;vgJ9e?kg4Rf@JZkQKOidveC^O z@~U-JVbwZa37ga?Dp##52L;lwVw8;%9F&c1w9!TzZCuCrKf>wJF06lpI{*Lx07*qo IM6N<$f@7H`egFUf literal 0 HcmV?d00001 diff --git a/test/clip-operator.pdf.rgb24.xfail.png b/test/clip-operator.pdf.rgb24.xfail.png deleted file mode 100644 index 01329b5522d5a1b550d36fd0b3d64462d2bb89b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5155 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 R&p-eG002ovPDHLkV1mdM4XywH diff --git a/test/clip-operator.svg12.argb32.xfail.png b/test/clip-operator.svg12.argb32.xfail.png index 1c21d15f624d7de7eed6e163425be80943610981..be0696e0fa718d5b95b4ef9cee5b78518fb24e59 100644 GIT binary patch literal 8406 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 literal 8404 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 diff --git a/test/clip-operator.svg12.rgb24.xfail.png b/test/clip-operator.svg12.rgb24.xfail.png index f79de48ebc3d488e9f880cbdbc7a59993a3a3cda..494852da4bec6321ef75c1e4bb2067d584f3a0eb 100644 GIT binary patch delta 4528 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 delta 4511 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 M07*qoM6N<$f?}aM&Hw-a literal 0 HcmV?d00001 diff --git a/test/clip-operator.xlib-fallback.rgb24.ref.png b/test/clip-operator.xlib-fallback.rgb24.ref.png deleted file mode 100644 index 4a05f7babd93d01133a8320705a8e36fa2a242f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3254 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 JS?83{1OSnHIJp1- literal 0 HcmV?d00001 diff --git a/test/clip-push-group.ref.png b/test/clip-push-group.ref.png index 327cc90bdb33b596fe6c0e48d5c6b5a2c50c5c5e..86724a23b805fab7620d2516cb31a554b8cbfa02 100644 GIT binary patch delta 129 zcmV-{0Dk|+0i*$t83+OZ0006|Sn81>6>eEcL_t&-m8Flt4S*mFMIY|L3PyIpbVZP1 zh%2y2J%Gxo9_;DmzoyN1iZzRAC!LW%4b+UhUO}M{Z&c7i>@vu9zx+oY3v7j(#&y + */ + +#include "cairo-test.h" + +#define SIZE 10 + +static cairo_surface_t * +create_source (cairo_surface_t *target) +{ + cairo_surface_t *similar; + cairo_t *cr; + + similar = cairo_surface_create_similar (target, + CAIRO_CONTENT_COLOR, SIZE/2, SIZE); + cr = cairo_create (similar); + cairo_surface_destroy (similar); + + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_paint (cr); + + similar = cairo_surface_reference (cairo_get_target (cr)); + cairo_destroy (cr); + + return similar; +} + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *source; + + cairo_set_source_rgb (cr, 0, 0, 1); + cairo_paint (cr); + + cairo_rectangle (cr, 0, 0, SIZE/2, SIZE); + cairo_clip (cr); + + /* Draw a source rectangle outside the image, the effect should be to + * clear only within the clip region. + */ + source = create_source (cairo_get_target (cr)); + cairo_set_source_surface (cr, source, SIZE/2, 0); + cairo_surface_destroy (source); + + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + + return CAIRO_TEST_SUCCESS; +} + +CAIRO_TEST (clip_unbounded, + "Test handling of an unbounded fill outside the clip region", + "clip", /* keywords */ + NULL, /* requirements */ + SIZE, SIZE, + NULL, draw) + diff --git a/test/clip-unbounded.ref.png b/test/clip-unbounded.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..0b65905650f50bef156006d79882f09a95e7a828 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDxedb&7< uNK8#mIl%Srzq@$ip>+bnJz7ipoEU_UF$o=9ex3uUh{4m<&t;ucLK6VE791@A literal 0 HcmV?d00001 diff --git a/test/clip-unbounded.rgb24.ref.png b/test/clip-unbounded.rgb24.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..2baf9f46422d499624133daabbc6de94468ea707 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ihf4u_bxCyDxedb&7< uNK8#mIl%Srzq@$ip>+bnJz7ipoEU_UF$o=9ex3uUh{4m<&t;ucLK6VE791@A literal 0 HcmV?d00001 diff --git a/test/clipped-group.pdf.argb32.ref.png b/test/clipped-group.pdf.argb32.ref.png deleted file mode 100644 index b9975e1224a558c59420f8562a785e9d71e2b7eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^HbCsg!2~4b)f1Y46kC$Fy9>jA5L~c#`DCETeNPw1 zkc`H+Hw?KB88Em#+}6d>^xy$&iOBJ|1KbwX^6M2UnA!CcY?~LqxU^Q!>V-<^#s|*= zILyTAr7G`-WK6Q#H08)=28M>kHJ7_zYRuvJ9hTiI{`&39KVQEb%&DwSb9KAstG{b) z+WO1eeq}8dn=jA5L~c#`DCETYfl%) zkc`H+H*~p}92wdk#@06}MEI~ZUsTBu>QDTjA?E*pm*pUHM+L({rP(}DN0+#sX6s(D zLxP1hF|q7mzhuSyEe7_#H>J+}2(;{hhJD_G`dU=1+B`m9ckuqq&Tm^;E^4`~7Fg@Fg$s${=XP8!C%iq_EV=4Z z4fp!(=Rc=x=I(p$a$0`k#Xy+`S)E;{vwPFpjCFUNHh%u(d~1g2qR@^o#VBNk`r`kk l)6FB+wI4LA6=yh*s9z?dcZJ8FXDZO!44$rjF6*2UngG4{eU1PC literal 0 HcmV?d00001 diff --git a/test/clipped-group.pdf.rgb24.ref.png b/test/clipped-group.pdf.rgb24.ref.png deleted file mode 100644 index b9975e1224a558c59420f8562a785e9d71e2b7eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^HbCsg!2~4b)f1Y46kC$Fy9>jA5L~c#`DCETeNPw1 zkc`H+Hw?KB88Em#+}6d>^xy$&iOBJ|1KbwX^6M2UnA!CcY?~LqxU^Q!>V-<^#s|*= zILyTAr7G`-WK6Q#H08)=28M>kHJ7_zYRuvJ9hTiI{`&39KVQEb%&DwSb9KAstG{b) z+WO1eeq}8dn=haBI6~8Jgiw*YPlQ%OqE@Xb{v@cG}YOm?^zi+-B{uCncn{|J>)!Wyc z^@~C~!W5%gGenUXLXxu88|LPJe>vr?=jW#t`}WLlU;VYHydbKsIzsj+Sdk@L;$433*dtzgf!s Rz))b|@O1TaS?83{1OSN;e)a$W delta 317 zcmdnPbdPC*BnKM<1H%N@?^h=(iq^B2c>21s-{4>u)0AECH9L!efsw(}#WAE}&f8nM z>kc_cv_8Dd)YQV#>=e_ur;Eisf~{%k21y~Yh6KiNp)XfiSlN77+ZZ0YD;_Y}!g9&@ z{o`3BX}@meOL^|nQuw&t{=sFAGWQMEO?L&~=%DpZt-O9E)6A&$O6=B86=$r!^(@x7y(?z9n83kza6|eM%2{?R-;h1{ zu8G@E_R-le>8X!$m^bfEsjsMz`>$^jpI`j8a@QWajZ>C*{9%01n^1m`wRroNp505E wz`D>4(uyrOcyw>{DT9quc0_-Iy7V1e!b*z`6Ss9N0tOU=r>mdKI;Vst0A%ElHvj+t diff --git a/test/composite-integer-translate-source.svg12.argb32.xfail.png b/test/composite-integer-translate-source.svg12.argb32.xfail.png new file mode 100644 index 0000000000000000000000000000000000000000..c4f31970134b41a70dee8f972cf664010f497efa GIT binary patch literal 16392 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

%g-W$`jtf8i} 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

%g-W$`jtf8i} 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 S;@&_%F?hQAxvXxlKmETJe^W}j`7Q@ zzYKdN{DNDTUn!eXx&$@1?eY%m#fEc^IXm<7D)KA`vI?YfcC@#dfXtZ1uRn8EeBQ5O90w`I2={JNH5DiX3sy9ba|i6!m87SZ!hbJM)uWj7HDHz?QZpQLB%B z31I)zSJJ9ytNK1`>LcH2N#;7g_4illEYY5@&S96+gD*$U1vZqlrvKis?%s<{d*1aQ z{`U9n6Pw!xG5gkBZJSxXwdk8#@j7!I=^xFCv5h6HmqeMCm;YaO``gRx%TIXwlfPG7 z+>}!#>Jk26M+jKjBU~Z2aqeQKms~Q_i(-C>UINM~#3~k89bd}TXfJU|)NjiysfxaJ S;@&_%F?hQAxvX5O90w`I6Db?OUGB&KI0#7;URcs_*$$=jZR6w%OdK@9tyQ z)0jRoy5Ob>VWjIJnV@d0Qmon3}SpFq=gj+C9o+H^HYcVkn P=qCnGS3j3^P6cMzpp@QdP9IWRzMf8m6O``I6CA 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 JSo8BY{s$#lWlsPA literal 0 HcmV?d00001 diff --git a/test/extended-blend.svg12.argb32.xfail.png b/test/extended-blend.svg12.argb32.xfail.png new file mode 100644 index 0000000000000000000000000000000000000000..93297a5c4326a707de4bd937dd2208254bc8e5ee GIT binary patch literal 2273 zcmeAS@N?(olHy`uVBq!ia0y~yVDty#5Dqq=$dWtzRskutByV>YhW{YAVDIwD3=AC8 zJY5_^D(1YsdofQsRD|_{q&lNZm(YSe-;{s+w|}I_6ciN|_4(XhkIA*?w;n$i)$g8X zoU>}};(52?rl(r!^+Z@3&+MC+X**NQdd_b~2EB=&SU5EN8ybMr9XpaHwQr znW7G+YT7TZSiZbW?XscK+UuvcJpTD^-OSn_|9+=^i+VZO-IkyvmBRwO*wTAYu=qQcO$yJY%{M-*0fGWPP7dT%@=u$)~W}W9eV~ZFhJ!7 z`(jB@+I`b=7G7F_3JpFt;}gJ`yD2%)4oAvu(;nBigJO;QJUrIk-`g8Kd!dj2Bu)KG zr>8KYMPgp{;lmHVpIh^NSMZrz`=8t0-@Ik>+IjEa&ANGZX4-b^s%iJuJpcD^-^{hI zfBWvAmReb7_gy$f9@WRY*cZ?HEIV=CsPD22NZ*yuFP|-&IrmXV2~g}_PNZG_FUb!=s4>qY+f#LItF6-7 z?B8FFZ>R5_Z}{o=)pM(AcjW$`ZXwYNlx;to`g7OI=ZF5I#`c0g30I0O{#=~-HSYTC z*!R{w+g8%|7>Rr6nzi#!szk9wiT7N4wcy;z)PFl=%?Ul?8mxJJSWaDZ}iLY~j@zA-C zujc9Mz!FYVeU zufDCcOxLb_U81u4lJ{&tL(>1hH@Nky*xuAwZ!&5wTK^6nJLOI7Hz)SbeQ$rO%AhLx zkIwZXgID$c1Akk6dq4FmqXRE;HU3LJy5D2{+26u7e`3ymmFd|gH}QsbDFdvYhh$sv z7qSy0ruiS0x4&L|7nra<+nO7HJBpGBA$jLR(0`^=g#yi7$0VXaBA%{(F6*2UngCxP B*8Bhf literal 0 HcmV?d00001 diff --git a/test/extended-blend.svg12.rgb24.xfail.png b/test/extended-blend.svg12.rgb24.xfail.png new file mode 100644 index 0000000000000000000000000000000000000000..8db02c5545c9971bd348d4738b4b47bf2e5dc800 GIT binary patch literal 1856 zcmeAS@N?(olHy`uVBq!ia0y~yVDty#5Dq4wi1t3szd(vD$=lt9;Xep2*t>i(P~fYl zi(^Q|oVRyx`^AKdIb19@P+9wcV^Ue%U%|is>#y*ixNG58!&$j@b6}t53hm;a?YgHz zbfbf#qn5461R2cGmp!lU=hGYOA8vT}PR#xB@-4^rTYTeY;B$E!u&``JfOSaBH8IhT zw!I(4kKg$54lJ@lR_h9%=w98s2Y#e({CF3p5Gb7UvPWJ_`u<%$(X4i^t$*&4LBo_u@~`Farif)qJ^& z_byA+7xwhN&w~aAQ1`{#mw0>Phe;S=iQH!|A3g*nre~FfCUsubHRaYJkmQoZ4hph{ z!!!2(7s%MLbEoB*kKew1(>VXS{=oupsDjekmpc8scke#R_%kK(&(hzkSD$^ne16?6 zn}6jyKURHyclXrCPuuU$`+Ie5-}}0Mm7jmi&y2F%bsG{XAni9UN$yW6_5S{9Cz9Zo zZ6(Z)CqG1rgGBH28m&91$=1JhH#k*8(yi{?k1Goh5x!!>Qe!(&Hor_AR+_ZUDkXbGkz3ZWcZ+zH3(dFlnjo+<%H({Q=PCx%`ndM;D zdDrZU`BQpzTglWL5eLx5Q*1h}TbAx>SkHpUvJFE8GdUjCX@?XWyZ~lKa>E6BmG`v2( zQpv9oDG3~v+g{S_?!Ei-{Y$#Fcb`pG=liy~WdFK-&*lOxTK{k7uQM_z${%hkX|AoS zdUNYz!oQfmPdb}(UtW8g@4fwBLLYKEd6W^o>)^p@Wye4L{xo;_@7tID?zqFZ&icl* zcNf+D-@H+_t=M(hgYkwvxasSK@7c7wa7u3mZQ9`{#!Br9bR{s=qP%{-wRu2ZiT81A0V%<8QN#-03rzKIp(|fk&n}FWFvu?=JpQ zSe{=fJLlE3yxPp;#&her4qS#75A9vyJC;iGc<&B>@R|GGBP)x^z$n}EUHJSXguUPt bUm#J>ta$EcV$>uqevp8ttDnm{r-UW|SKG7~ literal 0 HcmV?d00001 diff --git a/test/fill-empty.argb32.ref.png b/test/fill-empty.argb32.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..8c26f7ebf01fbbd2fd147d3c2c99e73effabd17a GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDxec)B=- tNK8#mN%--9ej~>Lm!3t8VHRr`7|bp(aWHpJwE?PO@O1TaS?83{1OSw?8yElp literal 0 HcmV?d00001 diff --git a/test/fill-empty.c b/test/fill-empty.c new file mode 100644 index 000000000..0594e57ad --- /dev/null +++ b/test/fill-empty.c @@ -0,0 +1,62 @@ +/* + * Copyright © 2009 Chris Wilson + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Chris Wilson not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Chris Wilson makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Chris Wilson + */ + +#include "cairo-test.h" + +#define SIZE 10 + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_set_source_rgb (cr, 0, 0, 1); + cairo_paint (cr); + + cairo_set_source_rgb (cr, 1, 0, 0); + + /* first drawn an ordinary empty path */ + cairo_save (cr); + cairo_rectangle (cr, 0, 0, SIZE, SIZE/2); + cairo_clip (cr); + cairo_fill (cr); + cairo_restore (cr); + + /* and then an unbounded empty path */ + cairo_save (cr); + cairo_rectangle (cr, 0, SIZE/2, SIZE, SIZE/2); + cairo_clip (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN); + cairo_fill (cr); + cairo_restore (cr); + + return CAIRO_TEST_SUCCESS; +} + +CAIRO_TEST (fill_empty, + "Test filling with an empty path", + "fill", /* keywords */ + NULL, /* requirements */ + SIZE, SIZE, + NULL, draw) + diff --git a/test/fill-empty.rgb24.ref.png b/test/fill-empty.rgb24.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..dc7a8a0e42c07618206558d450b62b63f2d0a5be GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#IhXtvAZ_q);^M7e6xbN7dl)%yp5mMURKeis>gTe~DWM4fKE)d2 literal 0 HcmV?d00001 diff --git a/test/fill-empty.svg12.rgb24.xfail.png b/test/fill-empty.svg12.rgb24.xfail.png new file mode 100644 index 0000000000000000000000000000000000000000..8c26f7ebf01fbbd2fd147d3c2c99e73effabd17a GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4u_bxCyDxec)B=- tNK8#mN%--9ej~>Lm!3t8VHRr`7|bp(aWHpJwE?PO@O1TaS?83{1OSw?8yElp literal 0 HcmV?d00001 diff --git a/test/filter-nearest-offset.pdf.xfail.png b/test/filter-nearest-offset.pdf.xfail.png index 4d436aa179469c8d8bfaf6bf5e1afb6091bd21af..ffe2df129970d8f9e02cffac188ff7c1c7a3f7bd 100644 GIT binary patch delta 1834 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 f$IDpfZw>zqc!SgA)V9en5B$t2b{`J0Wr8I1n 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 C`j}w= diff --git a/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png b/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png deleted file mode 100644 index 242c3be5978eaa42859aa25d230cf050ba91d8a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3632 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 diff --git a/test/ft-text-vertical-layout-type3.pdf.ref.png b/test/ft-text-vertical-layout-type3.pdf.ref.png index 04e679b4871d94596eb2b561e0706408c79d4c47..a05ec1d74fa83315d72f266ad4523f0511edbd66 100644 GIT binary patch literal 3639 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 literal 3634 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 Ymsm0K2Gqt*{saODT_c@$TK8lB53L;E)c^nh diff --git a/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png b/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png deleted file mode 100644 index f232b9a50d75397f14b876af317552c7248647f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3642 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 diff --git a/test/ft-text-vertical-layout-type3.ref.png b/test/ft-text-vertical-layout-type3.ref.png index 6b59c56a9d1b3319f0ceb137b1824edf5a2cde89..1bda421c471970cfe6ff93fda995495cb0b59733 100644 GIT binary patch literal 3608 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 rW}xD6J^0t#>vPgvEHj}5KW7PiuK0w-$ delta 3589 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 diff --git a/test/group-unaligned.svg.argb32.xfail.png b/test/group-unaligned.svg.argb32.xfail.png index 38550376d5f37bb577e8e1123acc56faee5a1a85..01c34bec49f16a5a82538d273668048301c86c7d 100644 GIT binary patch delta 476 zcmV<20VDp31c(HXHh;ZIL_t(oh3%FxOIuMCfWLP&CNV*5ttdEXNf)DAH<#{#fcOV= z6bFBVQjAcLZXNVrbaY6R2O=&am_liZG$0s_pgy10#?!$*gw)qG_db&h?}M}5bNINN zd+xDBMCc51-HlGTRhO+#ha45JIX}DS#eiaTyq9+i6U6#s!GG$A4<)-Sv#D)KT2}({ zS0t?~nR~M>CA;ibqFGj+lv$h3OAPl(iTa4)%Ey`f^T^Dn3;!ii9}AO(U}aV_c`Xqy zK4gt<=uzhI^Ec_@myt|_pYnCHq%EVoMqXJwrbd_1W4I&2`}rT*`Id-?bK)>Kq;QEF z$p9p9sGKR{FMpe^l~Vxr#+N`u02~t7>qV_x1@QgA2}Hz0x1Iv1p56y4Q?1nWWnK-L zHEun+^%THZx;Idnv5ACMo+To3dvVKP{~ec-G#2TzE~#8Z=}Go9oBHsYqJ2@OU+)`> z0L-NJbwnQU#$U-UOOzX<2^{BI%6rG=6L@rLgr&@m(N(Q1XLlKSJFH)zUaw<*ZI6!G zXFS@m=~*KGUdUUx1Lqpbw2+)?e5Q4TGJb?IeuOf9gff1FGJbRetL>KfL*X}tK1*^E SFH0x@0000&Wv=k{6N;e1nFB~1B;Xx@~LLnB4CB;C%)D%o!Uai&BK_7+G*O+^sF~j@dZ1)^K zF6W+mED;fUgKU4h6K>6Af3wK9gC;*tE_pDjn3{{TxVAuaIDZ!qBQ zh!=0tMmO|Vrnqw`ef&0(8Q_o>jP@&*(9nGr+6WBkg=kM8r9ENR2C8 zVn#9m2^^{?ihtNh$F;Hwz~25GhzNi~0(^jF^KR$it*F!^{wzd);A&-~gR zJ+sev+{dP8iTr;d@8S-eZ7b77va0==?h(rP5z6=x%J>n=_z}wZ(GRTOx5PE}AF*;v U1IaCqe*gdg07*qoM6N<$f{7>R(EtDd diff --git a/test/group-unaligned.xlib-fallback.ref.png b/test/group-unaligned.xlib-fallback.ref.png index ed615b228f11d4657770d75299b8f78924464ecd..5ddbc164f50ca3495851f82b797e31e6c05e35f3 100644 GIT binary patch delta 430 zcmV;f0a5<&1KIu68QTga(qir;!^Z?h3VTIYdc~9`!2|%iOMik%N!E0w=h@{S52=>F z;sGrf?&1NR6&in)%4x;Na91U(uuIi_QpT>+JO%bGbuR~D_@I(j;r*d8pq7qzn^cTl zC0V1BrbANzlR;YNX6DEwk(`~|I`1H0*(ftCwl2CPZ#vRr*J5Ct-dmGG8V~2p5@D|+ z#kbiH!1zv>LVrqTL}rP!*B%VZFgLixQ;wuIx!1QBL@|4js8C3@85VSuYOihb6l=m5 z>#80Bi)ujvm`^u-x}9sMdY}ez?%644NU_SEO3rvl7~|UEbrAn2JG!bD<)*|<7YvD; zmSj!WNWYCc9RB@ogbYioclvjx@jQ>k!-=$*t7Q2o*(ap^h@bSo3GNoQl$O#`T1tNT Y0-yH&4{STl2mk;807*qoM6N<$fQA{AxvbmKCy}&>KA!S*V(BmYp)^s*MI2;;MxY(USrW_h~_2f2?#E%b$VkAJIXTiPSJZ_raSDa1ik0*I%8Y+ z6bCvA-Z_?8f-?btBuYz2BRUX=1~0b~+0E6H-V@2@UX))Qz2EDyCazy|@z#EO z>ldYVJ2}3$^l``vS}B#dyy&2op^yKvv}6uG<zopr0G0n^6aWAK literal 0 HcmV?d00001 diff --git a/test/image-surface-source.svg12.rgb24.xfail.png b/test/image-surface-source.svg12.rgb24.xfail.png new file mode 100644 index 0000000000000000000000000000000000000000..6ebcaf9a116187cb7c64a0469e49068962dfaaa0 GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^Q6S901|%(3I5Gh#wj^(N7l!{JxM1({$v~0Qo-U3d z6?5L++Q@s@fQP~H^oM`i+QK_LGWK-e`P$Oa?j^?#RK;*0K6>)Qz2EDyCazy|@z#EO z>ldYVJ2}3$^l``vS}B#dyy&2op^yKvv}6uG<zopr0G0n^6aWAK literal 0 HcmV?d00001 diff --git a/test/in-fill-trapezoid.c b/test/in-fill-trapezoid.c index b05f0002a..84b323a05 100644 --- a/test/in-fill-trapezoid.c +++ b/test/in-fill-trapezoid.c @@ -27,10 +27,15 @@ #include "cairo-test.h" static cairo_test_status_t -draw (cairo_t *cr, int width, int height) +preamble (cairo_test_context_t *ctx) { - const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_test_status_t ret = CAIRO_TEST_SUCCESS; + cairo_surface_t *surface; + cairo_t *cr; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); + cr = cairo_create (surface); + cairo_surface_destroy (surface); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); @@ -80,7 +85,7 @@ draw (cairo_t *cr, int width, int height) cairo_new_path (cr); cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI); if (! cairo_in_fill (cr, 0, 0)) { - cairo_test_log (ctx, "Error: Failed to find point inside circle\n"); + cairo_test_log (ctx, "Error: Failed to find point inside circle [even-odd]\n"); ret = CAIRO_TEST_FAILURE; } @@ -117,7 +122,7 @@ draw (cairo_t *cr, int width, int height) cairo_new_path (cr); cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI); if (! cairo_in_fill (cr, 0, 0)) { - cairo_test_log (ctx, "Error: Failed to find point inside circle\n"); + cairo_test_log (ctx, "Error: Failed to find point inside circle [nonzero]\n"); ret = CAIRO_TEST_FAILURE; } @@ -261,12 +266,14 @@ draw (cairo_t *cr, int width, int height) ret = CAIRO_TEST_FAILURE; } + cairo_destroy (cr); + return ret; } CAIRO_TEST (in_fill_trapezoid, - "Test _cairo_trap_contains via cairo_in_fill", + "Test cairo_in_fill", "in, trap", /* keywords */ NULL, /* requirements */ 0, 0, - NULL, draw) + preamble, NULL) diff --git a/test/mask-glyphs.svg.ref.png b/test/mask-glyphs.svg.ref.png index e99c3ccb730d333c4b9f46dac469d9057af90d70..0058afc15ce3b9aed98ea3f917ed2facac1e3a20 100644 GIT binary patch literal 1211147 zcmV)uK$gFWP){K{2b-Cdn?j`#M>ac-WOtBD$oMp>g^S(asN zuno51S+Id!Fd4H8ERT7>UK<*I$5T^}FJv-`j~EIhmO zdG!z7=hUx%_5YqaryA^e#ygw}Ljz=Tt{=DHFkb0)Ru!S7>Ze1bz_l=phcXGwHX;4=JsG-_hZ?&d^d)CYE-PiDZ-Q0d`t@UM_{0yny zAriiL*QQ(S<{EZn;Y=#hXKIm_b|uyOrd$$8*HJ~|z4yMcvF9U4+R=$3b=wP15+AXG}zwAbrR zM0G}?#nUbteg~~}TMSn==zy18PjR%R7AOm)Mn}zcvJoAg1VDN9%y)K8K4h$*mrs0i z?_-ZuG)Bx@*}BtqP`!|&I`@?u_dV$bZX1>|QKQekaOPW6zRC2cfA8Yzx3Rm%L2q!q zV=)7c?C})uh|%bK%HhYf<_5B|4o7_T!fR+oT3^g-4}Ge;Z~0Dk85V7JX{60V7k~8S zhYlQl>%<90XpDa9&^TvHsFlPrl z&$aUL)1-@a5ADOmj+N8jaqV@=cqVgJb`SbRLt^cRYrPX+qSJq7DIv{H3+8?pS86VQ z^Y@0IeW8+E*4jI8%#}%hM~%&Lz`7{3xvN_v5A>(9^U zYSA)ksX=WY1mUeXoR6QLJ@$N~f?>^f@zFo5*4|YV7m!JR`K)ddv2FD!ZvEu{Hd`Qo z7ZIC9q8KUPsWlC&BqFhOH?wm+?3qX;-w7Q3upqRSUi;?wM}Di4U6&WV5C6HA;ve+ScO=*GfMqQeeUcGhgR9;vqNY&SW- z92&;>Trh6&S!*$e$+-TbAHQvR=wRxd%iP8eYYJm+ORc#|5Q9F6q}A3o4S1DZ5b{2% zwLq%2>UMU%wPlAbdG)$3XFQoWp$G;0t|+!CC7N)Xo~|j|X4G#ddWu*Xm;292v>)OU z3Zv2^L>tccL+0r~VOrOu_> znAM8|&!BIuX0xY<>CCDISozW{&_jFNKHOD#|EcZ}P^bBv}W?X86qOZ@pTE=X%TbXa=S2u!Fhee62r8i^qZ^})rymr>o6C#NKP8slPK*cpDc${B3qO9^<}^NTu4O{qsdXR{iZ1^hr2|!C=Gu~M z1au`0!gK$Ud0w{^C<1+Vdlb{SZBCgz3l3E-qv9gTH6M7FB!%Us1;FWO~sK!ySiV0~^A!g*)T+|w2Wn{_zczp}kx@OI0h zptp=Ft(x-sU29;toLNP20)k+!Rk25=5kgzbtr3*k+BxVP93x0WyPoUX|8#ckR{x_P zQko20yU{s&T74M+;h)8|5T7ZyJ^##EZc+K z>5whn@(KR4X(X zG(0HCo;qyCOwNWRtu!ypN3$D8=XRDB3X7MW%Q=J;e4ORsVe^y}X#0Y07u4!~qG1Qu zRF(-fe+qOMl@Q9USOCwD(zh3&d^>-6yjtI^-Kx>(5(7H;a%%1F7gx;gAHH8Ei|}UM zBvl1|PV=YNUnb|yD{&jtT=pRVyBxlr{C+G?7^3EPPktE&UBdReTKBTRrwazFC@Jq$ zJH37WdQvWR)O6)E<=TPU&DpLX4HGrF%FT`-7BZb%aCR6)?e)d=`D%-wu!J@$w@{}D z>Iw}w2CEnt(ium!0LJQjC=k^!TK&M@4h{~CvtHxuZly>2vA!d!GUQQFTg@s4OCUnv zhCVx?)brRYm8}l79uSILZIhQN7oRwhTy_QSSP;v5nN2*sTz{qP9W?B;YD6QXjzx?4 zIM-@tn%hp8m_#fzF3)tjk7911;kop+O%pS`*Eg6)PlughkMb7O2!2v&$y_h1A5qIr z(~)2O#Ia9&41_hv{*SRMB*g*j0Zg(ZD{q`fLK5iFJmLuAObcwrJ&+n^*^PE9sB?e- zu;1eTjgHX)3eL8&JH<7gtK%hWICc}QXcSe#o+(GH#~>(9Up)b;h-Gm@a;#bW6|ERoj_T+k>>Kelx7<5?NH>+CpjJI?XdJR?R2o0v1*hI77Rv zg6d*gjag~{klqV-!fr)vV^f}n5V8k_pwEVfB4)#+(H^1nBOT81p^rmC0{{TWv@t|# z5DX7aJnkCb6Yq+6S(?NMD3i{u-o#;4CuE(qLgc<@sHIbyWC~a7HH6ZgukvhzZDo17 z)qmu()yxi|G)c0|EG>(YAacAYaQ>m=004*r+pgq;d-ru5I5PFof3NeneUsC>p8KRH z5YpKrLr=dL-haq7GCK01PuTlO&%kBuxFR829t4{ zp_gCal6NlXb|hQ}05@2S?_@9JBwuj#^mjvhVp`g)(%ya3kWN_HY#SEZbJ-ugv98A*wNtm` zRAMBs#Fnl$Gl&L_BXrj;rKmC|Yip{KiPYNwBSI(#h)A0-)36I9ser8F5XIIJdk~Ny zLTc?qGgAbme-~r_?}ov5{ye+6|l8tm133TvwrJbF&Ornw?!1 z1<|b0B{!*#ZE>*^NiC;SpWg-vjV|+UcC~#qb$LM9>EQP_im7mOZ%lHMFlxBF3<49( zW*fe6*XrJfD0#ki)@h^=1&rtrskTj5S3nTLwL%Ns<&@R!lXJ2D!)|CxI-vaHZq5#GUVx6+M8oT#L3bB**#cKN>Nez_5y@7R4`tDFM>5dZ)TQ@9;LR6&}&yFk8W^LOBC z4Jz^z2cLi;c)^J}k$STMUU}!1I3`CnH*C0*XwAPstO@Q?#{N06Ep0x zwotEmRJ@2xV(`wzGtID;Oc&yXIY(44bpmC!8F3oQtcsFT>l!g<5P@1A&}%uzHDnGd zbFfI%HAeM%l-^b@x$9&wmpvuKSd)<{)O}1%bg@fjLp64O%~*-@RItL{?7&7jk?(Uu zHbjx*4Ioj|l-BE<(!O)&Ecx_)Q-!8PnlL)*I1$;qv5J`vwb{#fQ?fUx z9d}+PwN1tKI*d~nGc{zSE}G$;b5Wbs?rg0tT)w56FiHh3JPE1W5vF@q;|l7l_AKM~ z=mys^psjR8sUB@tHUM<2PBeEi@EdEVP?xn64eW>&Z6+xMM`3c&T+mc~Ij#BFg|EDd zkRId2geMhU^`-%|-F7i}C{Q(2-J(9>j%BZGbng2|x+8G=3Ktpruzked+{yM%O#xUR zBveF-4A^aV?<`n)ENEjbjx4NEP(QjWo0CUwI^^wzlVrb?2#H%8mgjbL=U=!!BtvP>p&9s3tGl{ zr=eK{-IJI-sqz)M+h(fUCwMQX@}@QB3Z@ZZ+{rDRh}Jm_UH}1GOWxG4QE}(a_PJ{+ zlp(xbjg#Mw+;@OPF#i27`;gr=8&Z1ZJGQC4*>W3fe1o4`FlqIYdB4)4uxwj7^|3N~ z$8QEq5wTJ%)>w7bl2dBc2uN(?HYh{CtCYSxzt%B(ysgxg^4plst|fpaA+K@ua0Gyx zdmE{{Wwx$vmT9ve-MZV}*q*EAb#Axc)5l`~r`9cf<+nq79`fkSa4oMY6-Nv8djFI` zsPcF3VE%yJF{s$Qi5d3kks_!{nH+m9FrX)?I;ji{+jPKSwY5#zEieZA4|Q-^v&I~% z<`%3W#NcM_d38yYP3>K@YI!s`VVQoSS&8{)rd7nGu18Xt9ihF4>1Ki{xBs;>=bn4+ zx##}~5KTj9GN&%yTv(|^7p|sP5^mg2m0Fo)zdq;&;PGQK;~?sm`o^_h&2s+rlsou$!Dn|?OK+J$A5IoQ~{_Okh>6P z)9O`2pz_q*mNl#Hj!8pg*`}L)TVjv9{8fEF6mU%jaY2Kj7@eXAmO6JmBwAopbugKG z6W5^Vc%oEjL1hcA&RnWo#LS~@#?$6x9kUQ4MpEpnq?S^3NUSYm4vrIt2vA#Ru_dyz zU%=H8F1WjWm}#mZ92RtaT9t^I5Z(WR&1{rMRzp}gt(e%b%5Q7wJ=>*fv>@&M= zq+?DzAS~M(Zh!)?g}XP)OjWWp)N74?Z@Jr$2%y5l6l4e3>MrQ6thE6ELb-Yv>iPa& zW1p61q_A2i0@B8IK`9}ntvNn-OMi1=Jv)!;&5r2HyA-HwA4}QJsRnkjxG1l@L=hAK z09MaYjA|$pcj1tPwr@mfqTN_Vy*Rg+p!UEpO6ZB!$@sZWrB1s83Z7%+rd*5dZgo9m zmoP$ee+CqP{I$Oe>qAvyU8^nH4OG3@Lf-#_oU*FHiiV5tj2ZjQ1j(FjC}8+ky7zf# zZzw%zC;ifm3nr6KkzXzAI@))?N7;LMEsW1ECunCpSGAUKuv+BXVkNU`#L#SAzY)7) z6zgy5teNWd$jrwCAEhu4Vq)T4tF~n_Y}KOIh|;;WI46jRNaFRm=3K)8HI=dD+`OAq zVjv8H5YVsDtk!dFx@ti%3j}KbP{UWCMz>lqEc4k8wXQ01w8Y)5NeahcKwi|MH-I2$MxcRYVdw2r71VAX8@%$ZKfkk;DqLDp$)L*Ftr#3auDzKH^egu5`-r#8 z65J)XC0^l^VEl=ZDPG_((tupPe06QH+8L@Om+J4l^2GFgTrH2c(`}yD^IWphr~xFJ zq4SU=ES?gH8`iRW@zSl-(mB6(?7-MCA)@|Xow>=om6(m{XG^mnFL(JnA*-~X^-`Vt z^V8_3a8F>koAGwy*YE!Xp;5 zt`%t1JfH;RL?@yS-<+3AU`bM6;ByXvFVRxoM-Qu|SVZjWS~#vo1Gbr^5i8YWFs z8C0v6BtuC6K%srRWir*;U)x@5nLvGN{*SZJYSswmb(-y41Yfj@J2f5p781FS%-7hB zr)->8pScUAyfc$eRjU<;Bip{^l@x6rBcH`TB(@>0$gf#@;K!YV#34kuNah+rn_M%*~5Ng!{hn`S( zo_SBYd%owTyLWGG>gOm{RvU;ta zQHgcC+Eg9eM=@2wF_bOj-n?{8YVf&bCGGALGC6@0Fc@+|s!ID+1XV#81%Uw1R$;zT z6v3V4b+y23Aja~-QhYH>i+LBmLBbD`iZZ0sFqqednd+@sIy)z@W761Y}?O194~!*9KP z_3Gkb`__81lGAdByF79%<+1~PTBssyG_w_+74KFu&a@&UVsCx#e6zfPRO)YKqEva6 z+`ggr``+iF1j!-~2)qOUO=V_c?TTG7*!IBQ z`Z;l+%_Y6gnk?6w#GH0T@0rv%7TtLY&$y&#L|^jDyB8o zrR^od;zkBCY`a;AH(R9?F45Iy!>1x0#Vt&dD3zmIP8jP&!R^+7dUG1HseMyc_eMU0 zD#L;l3&}mFTR_cT5{%A3Rfii3+DdbE2MfEB<+9~i{p=>wkdR3XmWo}&!^-fuWD}{6?>rTMD(c2HPm5iv$y;9nu1;jJaaM+T&keFVC>~gk9a) zyEmzSi-HDZN-m05WW|uAwR!cS^tJaK_QQNbtds4cz(mQ`Ce50ADv-05voV+7RjUcU18zRstW>Oi@) zMmw82l6(7{=O->i6^5|ie#;8CmrUy`e6U*me;|LNnxI1WJ{esp> za*ZC#>#Jzb1TJ%?i#Ss%C1t%heZCw~|j zCo8OGHCj>h^_EFZ%IyImg<+bD6~|OvhjP|U1bqNoT+>yHB3{D>dR%%GC@5s*WF>WT ztFY=A7^h0vrD`GK_KCIXPNhH@`l-YU3Pa-XA>>YlciAat06O*KGVMSk)Y8ohL2G`2 zvHH{|yp~>R6eKsm=awl6GWX6p-}>&K&0p%<_b|^iK$X>Y{=NFZgtKSh=9{nJM|y}f zVr^+FVZDsIS;bum8IVd&X??w}AE0TQQEzULg&r%<*^^MCTi?3bB6r%l3Cr@`Ruika zF)fWFu~NI4vNOS}+GuZ8t~)Qx9JLByKN zliK-nGf2b2J^@<_trje)958dRtzoOO1=Fo-jTj`u2w#`lC7sAH4c?!rf*@H2EV7`a zN>L>yxVMi`7sd?+TLah)wbe9C>NRa8w9Idwhhq1mwnQ|!nlOh7^}05OP8axik?!o2_{}QB0cPm#pTFc) z$6-a4TfnRxM`T-vP&VaP`lzN3b7&IGIZA<*8`)Bm_YdD+Z?*15!`nJ{fplIjChEyb z5mu?hS~J$R3}|Tb_G-NplbR4VMSB)+^Q59ONv&;8?)#8UV|LtHE%1ziWvhc zBnJ=;u0;!6X?;H47Uf)N)lmr#7`+jrLy8xSt$f=#sx}Euq;0WU+u6Dk+&-0D(pl8{ zE2$7KQev5ZLxZ8C zi_La?%u2Z)Y34vV>zW7p3*~j~g!M63m*;>{S!B%Fmyv8BwPhgAobK#3NNE1n_y4mP z3}wyM>Uv#tw9LH{b?qmd_xcn&p}s@-kt28==n_PE?g zvuQg}?pm)T^NMe$1W|Nl7U^`oaZLu;B2%%wInUJW8D-$ckN;CU{|c=L-+c9}3SQd+ z_{Er-pQAUbh4j!63+k_D-)U-}5OP=URtwEs-Y*Lmvi15xnjdE7D}_pXGh5EA)hiVI zzUVzvsDkNO)v!k{rJb?(G7HW7NIrGS8Xk*l=uErCleNvn+ASQ0WpD55Tkkf7!A@Dh zHEz@q)lrwW?ONac%$rAOJ~3 zK~%XLt$l}s0YTha?R@Mh*)q|;zMN%RAfa_Na7YR{)Z=-frAAbow!=t}BBAkJz9I|F zxX;m+!6>AtVo5|HH8%`3eu+KK`yys~Nf#>RycDLjN$Y)SrR zDtPqvx^4YVF&jBb1UhbBKi{$pKr@DcPIbeW)r&WaxJj1z?)i%wpbvu)6?rB%I>cwU zZ8&MwW$DE^iPYoO6^+S=nL-qT40U!JP#g+QJoCuYR$XXm>Gtq*pB;bl*IJ8nAPCGp z`dKxEI92+kiN~85IsTE)?K|@DQ=j?|F1Oq08$SMt-AuMXA7W^O?jTC!02fsg;L0FTksxMa|IoLCCOV4+@3UPapkXfI3v zExfQF2DGy1v6nEeUEOIO6f`8jS=+9X&Y3~cS|*jh6~9x{tW@<|by@;i;dXpU!Z}SY zA!o08d85Aw^OkHn3%G4RDZK8)P0IB1P5Cq~N{g_yar3rjzdMgiTSU}*nI7j`R z8^&Rco!$u>RY5S7f=&Kuof-v0}5OK_4DT+(A zRiPyat>zCFSIW|6Q`U!!;k=?;ja`6tgr>-EVGRHT*k&I@lt3c0hBe})b<4*0QN5_< znC4QtA4Sb7(xR-yZ(KAG35~grIP=5yl20RHutN5d8f4JjxYcOwY%}ZqqR45wR27u9 z>XZNg0|r<*rot*h9Z{0g2iDJCT$4AZE>rOFujtE3F7+112=y zNv*pCQZq2LO}d-tGA%e`4SS=hAoT`#NTEbfl>ulESWT!|MYnTQcb;i)G?vu$0}Fz3 zkI4z5Y1_s37~zI2%B6*#6RQ_O1cIuN?tWv3CdT}1Rll2MHI5J?Sc-~ zpDAW_TC&-aB;LWv2CPLPB8W2}%~y1fn7Qpd0Bq$8X@T1%3eAkmTEpd*W=v-phaq)i zajA%vWJ+oYtV(b($@gjVM0r!eyRj00Fw(NC`)DkGR}%NJ%I%UGLW+k1&mcmwT9Md| zUK3qIm~7kLGl6MrL{}^@^x+0mVZmf~LCkFE*3Z0FsxRi59}Ql|x%?l4K(z;t) z78)g@n7g~SN)}l8+8%0km0{tNTf>*wl8(D6ind+E(`(n#t%0OYmQX5@um8+_>L?16_& zezP}yr{I~87+2z@TLOLtqYUNmevdi-hQ|sq_rHl2SGxnv zR)ScY41cJze`oz_boXAnM1zzD1|e1S79^2eE!n(uf%g(J<=(O@`d6zPAg(;JX z*)e5L7dC)lw+dys-4dJ4g=(fbbYpWx=G$wr)q1UJz(`sG)f}G>PUq8$5M_WMII*<_ zz^E*8@pv3$SRS*jY^~;)mJE@}#TyH6y+pSflEBP7@(B>7e(=>V`FA}ybKjw-KKWbw zk3QNrICT6Mzui=W+p^wHy=_>EmtGyj7yigfq>PuFoApO~5bM|Zn= z`u@Sn&u{&c9DDl3f5x}|dH&JbH5!e}?f&W1>kouFI)6F^K`_)2`C$CPI)We{3~(F| zhQa^2!E(LZj9GbZT=rv|1ei08W?dr-KhZ;PQA> zDir_#UVlKTRQ^j}|GzZ2^Zt*DxLVNG+MJk4UULolttm~~rgp+G%EK&ODb^&lJ0Qt0 zZna<#=Hb}L1P7-#QsePEf)}H8-s^E*+reQE5xMB9RuCSt!2TVtj+D4 z-nDT4wTN}k-PN-QJQ6=I##djhEXVnbg`oj)`_=cOXKcCpot2dtrS0X-6}Q&_%5EO# zT(&;xa#7pYE5V_N>+-HP#V8%DAQLxYWRTk_uBbM6tgojqpY;s4^#*kdv?>QO@100! zNsum+3QC!bMmxHDH-+=!&;(*HBArhr+ZXE5wnOaQ-u!XUIZ?w_47&TsoW5D!+9)jb zj)!nIyEMNY)RR&05?3MvdV4D%m@6%)F1KJiBm1ieb9U)M2`P1`z1STnt-Ld4ch@Q0 zTwN~)eO&>za@Hk>bOtHiU@szEHzwZ{?T*WL&JlUybcjj~Kyl0VTQAcJi`Gu3Yx~O9lR9>a zHAF#nA`x35Lt~ohhwh$vTQMD08H{jaTg?wFMw1>T>5~j8!4*(|Ee*<38m4J+={Qj{ zQ_yIkt$Hf90N!HP`VK3Z6kg zHeN2<#-72L`U*Wktx%sI$!07AqhsU%}E=yRmFN z)|R|u^;tYvR>=Zp%O)Hn+?=TmN7*Ll6#$iwmF)9%3|nk(Pm zSX=dVbsDwyxwRV_dw19PzJ<5{i!apYpZ$f^&GWj*K2PrypS}Z0HN@`Y=*rN{Q-$r@ zYI6WYmAF(gg!W6VB#h!Z_h5AKiq#tm?s^ae!0-R{?+)#IN^SCe_pg3Cm5A?}oS8ZH zk*=XJ6y&Gxe^N^+IhG#Zy+5B$%s%;PkgcL9+-NlR95@2XBFi%4GqaJYhgNQ$o!qmp zRxLmBi@z^%_05$+^T?^tI~s-3K2uTP)R5QKhB^cTFVYQLoP*=^LyR^Lm4!v#S@! zu+ZeAojpAUJr#=d4(+~Q=2{d*g}ZxG@tDi)9vYv{rISzpyT9ei+r>iO>+@Hul~6|~ zj$_S6Bh(SW3EXCP)N9qz$(d@Y=<)hc3~jes!BDtsVA$;oq!Y2RsXcmwF_%pre*Oze zm`lc^E{|tud^)nMr_J9`qb9kbOsap-tCvtuxthG!pKp1X?Ucu(J;(QGmpOua*66h-B- z>At}sN~2*Jx~r$(YP09E>4A}57K=@igitu5RFc(dWn%ZNf*{8C9vYrK7G0TBQyL6K z%~q?~Y$=yZPM6DUv6joFP)Ee+_A*S{<#JP6ZM9PI`us+dscT?ZrBre(GrjNrX01GN z@KJ-ofPiwjT$bM> z{t(F3F$@Vr2L9h#JiPzO#T(~7Xt6gK;#hX(z)`JMBZ<5uisQTQD`eA7mpjlA5qK5? z!Qrtf1ctOaU8Hv)8IS4>#)-ZA(~0Oazy7xnoy%rYA2ihK^K13`YNg^21T|W%LP^39 zG_-3n8IJ}-;SVbH2ZEiw{oX*hRw;Evy8PitGPZO0xnH9QFqcVbb^3`t`?IOI)n@Ys z!UOxB%10Ob21l#q;)9?3i`>T5TsGtN`8~b>hNBY?{(=gV60x1Z@jX9ZX?*2|-e{aS z^4tfNcK7wWy#Yz&C-xq+SgpxeG#CoIJiZS)>kWoe@mQq0*Wq*v0w3<^GMY_=T&{m` z#O8FWl*$J_{s+0uTLRCUEfx&J9Zn}rw^b^&%j2WlEngs{RFW2}jU*Lji?v>_8H`4& z)z&>YVltbH`P`m^M*)%dg*&^)_8|b5%VzophdhB`DiI$Zn;6{xOk(YJsH01*R(16B zb?o`@{Ds#=QQS2(V>Ft>eWR{GCm?bLqgj@vYNg^01bLooHX8dLepY0gTCHwq?@_i< zE*A1OyFC!>z%XQR*ObL(MNza`sZ7kwvP|1xF!=l-1*xc2tJAXwa2!*rlwN;`VcHM~ z&g{FtUM)ZVD_>GV^alt0=Nl@^lHOqG9T@os4Rv|_p{^cD;Pgh*;Mhzux+VShe?G8Wix8=*6K@#1ej<7ZPJ)$s47yTWP}B@DHzr(L>70HR25j& zZloF7h+}F(r8CbrAv2yZHwdE;{S>Ike8 z;3}XTH9`W0h=tGtZmpI6-LIVJ?r^nsZtho-9744H6SwaCq|f)P*izZfe}6;2hh-X0 zpEsxIf21z11@GHD@n*&!rk76bM}xwm!Z$hTT)4WU+$|+bgA2?~1aI?OSFhd}Ho7D= z?PkE+KS{ziUpDTo-1w@$3eTNsc275=?nivY_048gkz}*az+3;ZfT?hvhf1)cACyoX zs?*pzVy6&NAq;miip56Bt)lum?TOZP|A;M>=`{@njv!XPs{@|Ms}?0abtI5HpND;V zonKi(nYr}Y9`h#!q=c7ahU~CKp(sKZ=#N_gN!b z@t>F@JtITn=f8dJnCd^&uWvC@ouoQ7GdzQxMNw$u%vY78fICv(IE_T&=Zv_bN!qQr zl7x}8P~xUvz~qcjzLvL$#r$cnW*i|%!)=i7^enY%zY^$gny@6PvCyl7ZM+ebl~$2V zV64#AR<`_}mJGPTZ7#Z;+4anDy}XkZc?gCYh4b>euL~^0)M{M{BUS)uXQt0;Y@}9N zZZJN1Fu`2a5KEEczQsfliQS-wbv~Harehq`C)YLugPi%`#EtV?eHBoc*2i^>2UF&x z)^22Lr^&Ezdrx9%qhlza35HLd3_gO*EylpAiC_P^zOUCr8EL7hLr{fKURq!6rVOmY zv~%Y~N7n=h$X70W$3Ah8uA~$IqzgwtF7e$z|J?DW000QW&wlog z?wtPqPxEf~Q@@p%d+q2ie@y~NUEzFS%xC@(Qn}X7eD#q}{viM%iQ8{S zW}gK?^ao%0(ue-tUxE+`Rbrf*=4A*KE`P0GN9C zZR%&!le&X}E&bM~{C4b-CM!TpavM{114 zTvp&Yo@t1pIJ$d(t(f!n@1e^nlg$|zJwlh`?qH{V_&J&0=||N z{Kr0b*y`_TG+rS!`okal({^^w;0!nijtp0JYWY~TRD9}_zm?gT0~FrlzxV}75`xno zW=kuj*b)E$Pk!omcIM7Z9RCBcvEd2#^m}*7eCr>y7yy8$e(5)pt2chy;+e-klUuvk zbN_FEvS{J+U6LeA!p61N9{=>80x-UF?MH`S_+43K|J%(YvB}%70|4;AFZ}-2l^+oV z0Z44KUj3k<(ZBfo)WaVKAw>M)UyUAm3c*#fz%q>j>6#5pK6dxLzw4cSiaPVX@X+q1 ztEWbeeI~ZKs#I$OBZo{*KdAI@9P`Ad{}4o}g_B<+m8#iie>1;&1_a@QFMg?=x#{hn z0fcrYl>`7_=J;<^qF1|2UVwCKjn>CM_Bn#G|AR^)h2iLnzx9)^eDSB14nFiBxcrUI zsfRgiuO|P}gASk8H7K+TN=oD3{i)jKn~#5Nh|qZ?uHj6t>pCC3_?`bN)Dh`B@cjJA zZ!ioki!95q4yS8q_Q6Img)7wk(@IQb$gE%Q7#vpzpQfX)sy!1jQ@VTlrK3;3s5E%q z|K48_3Z-}O@aF2WLaCm9_Dfsm|5~B<_UCzLHX9-OH~uOb*0-QMza4xrddCY1sJpnvwsYI+Tj zy!%vdLP}=&x2o%I=m`GeFr`b#=Dht zFYcaLHILXZB+t&$?j1d=cB}Rv^-{eFPLc&TJeIB9N}Vng;^!HwZyb5siGue({p*~~ zBST%zLj$B4SK;Qi>Q(z=T20+%?VQj$e8xhW54KyVo5a0FTEW-_TqMe4{v&2zma#N# ziy+nznjt`uu3BSM)tQSvE?Kob<>o?3XFq6Oc5;rj-ErNuG}ShnXaRYrn7>}G(xx!g z$}&b($O+%9q6VT1dH4MSAR$!`m$@EqLEPrl2-^IfqkC_|9cEFn%(M9|plFzN;wxyG zuQlSWRVkytiK_Rg^{skBMc4=GTQ~wCJZ5(8a&=Z!m2GL{nU7QLvd}D3wj;*(G+3kB zICvP;DR6#EML4$G+kPeG4H`fO2nS3kEHtxc8v@61mBuQJs|W>{@I57a<`K(X$PO!w zm}0-#&5GjHsTud)Srs}6*nn92-IZn&=l3b1okp$cVlmy$%Pibr0jVYMDw-|D@_ATK z@r>FIV7y~%bBP9vtARbSxi)a~`kbf!x#3X)C0V7GZj{@VD%UInqNsDbWww;NaP^z< zZ3rhT?$gmsFAZcy*RPm~p+?D^dM$VH2OH{87%5dZT|cZelud7)4ks1W5~INDk`|+3 zk%h{!5XkbzM03qOSv%7<*u}g35t0@F1a5bfDTL!B4s{!dgU7Eg&Q*0?*w(p5r6vnZ zvDp9sfQ5*a*d_u(NIO-!al@uIDXsk=j6nznVCF|Y`Z1{n7p>-thyd&|g z?X67!03cj{{n7!hfwAA#`;h5PGkyaPP{HRHz00H zU|X^*0+M*?%t;7U0s?*g(ghFz0g=CX`5XuU0Ib}9^ie<(09oF9=mD3M9u3rHF zVEO&824_A(lBC4el8FQW0DvqxT`mBS0ZDN7?mO}7%OHfZr8Udo3qWfffU#UQD@%gL zJ#hKlslLOXdjA`rhakw-_kh?;m>h19FRd-y!u0{^zjF3oQF5HuweVNDyQ*_eGd(>$ zIcETa3=D`s63kJgWh+~fCCk2&>}&hVl5E+sWLa_$C7KG97({{~NDw5Eh%gD5oO91~ z_jJy=t1JHx(3O4fzt(+FJ$`R{?Y+*o&)IdVDyhlw5t5Wk0>d#y6qf-=OzkdiE=~am z$>nkyjZPAnaxwrx5X8m&OXFIz10{6;0363rnd-Ml5o0d$f3)4@=p3EgiEK_|P%INz z)Y@v3{$(~7Bo%5d7fc7&6h>EQYfdPI0RV}uu~;;E?VZ;JuF`+%V})$0lughy&6G{-WjR$1B-Td*7g3V}I+VAM88z zjKHw~MgaiP?PUM}rnF3re6+T*gvvB>g$fcfn8L)-`NY~47?mZXApig(H!aOh0wIsc zv{&DGU1anBMKS(cm;iz?rFCOv;dd}ap1ykVoK)NrOFJT46!|g)BNL;y0g!+sOpM+F zA_oAN92)^bMXaQ5UU?4yFm~>rYxh1<*VHO91f!*D@!6%EcZBlCkTz+zF1eO_r$jr}7 zrjiK&fFuF{fCQ1HY+_~X0{|h3cpLx#ASAG{1OR~e?6r$;;*|dXk5oboTq#*9m41g* zDsK6f$1;Is0*m-orb(@hD<#4k(>iN4#3ffIhh=Izn+s;cTL1ttzwF!D-r878Y>jo? z_lZ<8DO7UVY^G4iBPcR$;7@BuS;# zTH8;)^3Q+Pv-gnN>c01dWIE$#%W29|7v7p(oSRnZtpdwJLQbKxh-@LTb_IqJo-G3a zD4jhK*oOGDOrcF|&k3c7Or<9kY5)K(SI8;lJzS{5;otZ#LID7?H{X*=-b%&~RU#sj zLFL-J!`A^{1^{?hXCteBZ`Q`6f8v1$;o)p;p*2WqDKoWTr zMPXdEe&@Z%zw+bY@=ZD&AWaPb0Kn!%+~(a_Ucd9+*)RTN>Grw)lTSz2M0t4+bc7Fvj`!N*TY#c{$`Yu?(Bs;g2F4Xdus6|zlh zD_+FmjZC>}bt-~tu*i#6f+P%*Q-ifI5EWAzsq|LKa43%`TKzsjVbL+QwNl2+D9++$ zy(o-H*835iLQ0mGJ316vO$?U@ww4*0DeBSy)y`5D-&h@~Z$GtDf+xq{CUrW>*b=++ z%6eq2;|~U{>3XtV?O9qP_H~lfSrWxpr#^J;JyG<|9YY9zbGyNGBNpu<*CTR8==$B; zU9}CSjj82=P_L-P4BdITTH{P1!UC`BQYQ0)i-BI5zA*p*AOJ~3K~(5ESRGb*RFGD? zmHOA_s{S`Vd{OW00H{D$zpOXuJ(E7=9vf9mtYp&GG>I9A*z1L>nGc9p zH?DNF9=iF`KcFu2=J*9$XQ$rqs06B$p*sfn6sspHOa$$=>65h;MVb)Zg2L%vU)yVn z&93S8hO_b3s@+=^j5G>mpGmXCc0s>5hgMR77I<2%Ci}f|N z`%~?)orxNY(q(P(&92p)sDtnDeZ>__(|~9X@TH_SCzPDp5)n+kekU1XX8kKYRh@|| z!@_*Au5UlBcCcI9y0$iL{3dA}@+?j}G;KwKhq5H1XFXTu4w!0ui4T4B*y82+QZ}IP zZ=QVh=Q*1v!K}{achO{}0z zF16<^5Vf%}7Cm{k$s1#8iP}_PO$1Wdrqy14m+U_hs`!*|{W{ZH#<0`lzxmPAeV^VW zv$et9GDp*Hdv7}XUeM#Ltqp=?tEkG96N04+8jEfe7<Dwc$QW6}8nvD4W{cunay_UDw`FD5bPjW#UdY;vk!<{M8e=l$izf2a}%3bX41S zpXt_Bs!dMI_So@pxwSYsVHr>*p{!*|y{HlPC}c@cHWq3f1d0hHtLWI>xwI1qC@pJa zOH89-xw5OqI=KpiB5XRWX*kTuuxKfU6p|ekG0QQ!S|@L*M%j`~u5x$wz|kF4?__d; z;rHKY=-P*1GCIDZR_Gg>+jvr|P<0}VM_pZA<=)rW-hs+=a+UV=fBQz~{*$P>o=Yub zat(~iX0H9F_x{g_boAVd-vt14^zRh~4wLKGM$c8ZA4X6Zk|dS6hEA-d1M8i~K2}a{ zFOR-+@)O^-)D5iOdS&SOzb?mDaLNp17O5O6rbAWES~-E+>U%l|PeL%x7emXFx6K9> zNhy{lZUO+>kA8k>_|>l70aIPi)tA53ciQ?Po=!mK&Z4Ieq0hNi&uYUukX0<(svCSxwU-=qSNZSvpD06gaXH( z{!=EiBhY!3PHVT>lnRB`Y_IJ)ob=8@lEBkhSga@&)cVX#Yn258fXxMEh@?=famoA^y2WFa=F}QmdVvdN`|XU zHCm-C;P+P5)N?Ey-Q6}j-us)-6G#4ZDq{gzn zJk_-Sx%sONdG8+y7JS!YT)3`5G9Fba#Ah?k;B z7^8~8DZ8^aw!5WwADO=XO55>2wYuDNVq2?KDC`}{?I{eEdX7I0fRyo1?Rns{Y}#*W zeM+H3qnmeNE~#<$V4y-8TTE&Y@Oqj%dyLLTo+$!}TfBS2tXC^-?ZK51tIcNbdiEaD zhI*SMNg5@ouWB~wlsjAN?)o|eMx(nPb5%74agpsMowZiuXq~=(uB!8KXJgZqU;RTv z{|U<2Br;jdbf6TPGFxr#{!`_|7A$ZETaA*$2tsCYw-YK`YIjwkQs$!`3Z;@2C`#3W{=c z90z=Hb9vrTRh12`xZ3ui1VzelxeTimbG8~c&lH$a4n>hlAwGHKH>W@O_jKBWD-32= zJDu^bj9xtPhu;JU2@^(}ncQ5SzyF!f!Vr{>c~B4@4e7A^ks!!uOTHS7qfMoDTHR$7iWGCg9XDm z6Qnlk2qw!MC`7B|7G7r9Vj)-}GBuT@ys$uE6E5izTtNtp7fu_Bb6bK;34v<_70;US zBHIpUwJ;CiwiTf);IaZx6~e`0ZQWihZH`BAr6JdN>`99da~Ty*!x?2p zQ`QVYEKSPG%NKkGbrgkRqLk-ywWL@1%fR+_S;Bk9J$C}4oQ=m;r+mZ7@VE{)j-GqP zzOWq3h{*NZI5ci76VzHZ*A`H5xZ01Ji*Iv z$ej;1P@Pil9Zk_v5&19$m-z|c;* zOS<*gcA>j1Z;`7EJy?DvUiW}^@aru+1?*?PP)Kl0mb2F$ZM^(LC13Kq>xE1_Eq_GwN+IS$2)0+~pn_G38639Qz-Q|)}k2oU>zM|c`x1U%Z$fmjmA5h<&Q1q!3 zWkm3%1hE~d0o99?7cD$ya>sV;T47VCY9ad%B5BTW>NFGX-3WQN5}V-)m%&p#`U#0Z z^@bYOw&kchQ2%IM_p=`_sVc1$Rpi+sYE}}%G>m)vY0n`pvXiqZjK~13N{FGr1ONjV zgs{49(7A_1PovHUIv>2Bf+5Ej?EXbUr+>uW_Ekrp!O?&0%$NTO1v0b4ZD~_S2~L?3 z%6SGViFRFuk#1RR+sSQ}l^iOm8`;7i*z2G3+;!f*<(XB=MSbT^DQ8f~{gPrW9x*`H zV5!9OqT0|@TXP}{5p2b_TP~CZUZt|!mgs6y^-&_g5u=pC0XSI7T5n$W^L#0u;4=YZ@589cgmI>fRDW0SF<{$;D%teqI~K?T{lJC(i(%yN1f{qMbXiVRtJHY<$9+^z$MlukuB=a1LId z>W9K2Mw++5&OmRtrdle;l0HqnuaIgkOBfTp{>}^LmOc}Nl8-*OL7^p;%Z1^i@4YU- z=+v)Xka@O+a`erg{-Y=ed^x^0@+JYJID!?YM~wstRo0z{KUq%1MMN!d^v&14C9Yg&rtjge14IE}48SOYD**u4 zFTD*RH~_$GvA|OC*)M&on9p*#Kr9-)e(7z}(t#k@$OMrYH}Q)hv^n#%=7Kl%_th@EZE>f#(gh`ymm?X}II>;(Xz7)IImVwAzs*e|M2 zR(Blk9XvuBoEm$(N~48vwOng$9~@#!30S6A8*KnaKKjkS>>oPA7b6+Zm85^Q6rRsz zGYEo2Hm2lilf_w=^er{*f7n*roboS7cy(>h5Uz1q>bk4k%`xw)yZ_APUw&KSd9G4u z@9Bq_Q2!%eD}%BYw(K$y`Z+PVf1c?V9c$UrjHLinnE*74A;oOVg zJ8<@oymw!RRgGLJL8`TV4}QVm>IXmy&Yr(F`nrDUZLt)3^0Qx)lN1ap_ryf%YZYo8 zReb^?9j-l39DL#{#@haTHfeP4CCyE-okfka-`)Sf#>lUA4JRec5L*7|+I#1$Z72LQ z7cx5&P}#FII|%@QP~tZ)e5YyftkT*rb^F7PLl04g8i6U`q(awx7E{^*0EU{LWF*9M z^z?^6S5|c|O%B)f-v=?_NB{7Ph?w3Od3Dc&pP?*mOV@reclS1-sfn!IkOW%iK2nOV z^c;TzuB=`7>EB+z^fqN}Pi&28tJ(mB!Z7;iC;uE#H%J11_09i;5nPg_>+fFxLgmzR zU$#}dP$6;;smwYEB&l}bK?XmfGTI-0?sH0er^@8enJkjb!EsDgOFtsh3Us=C&tVZL z#?JqUq7*Q$4KG~sugyZVClU^2(n-FY&c=e(O&yXb)N~w_k@89|#uM%4>UzT1p>_6D z=(51G2Os(D)nEO6+`9~8q*kYwM8?$lly7|&;$o5{?Z59Ko=z`a`$e_8p^^*2Qof;c z0D@p#;}!&7N?v~b-@Y+$Xs8rjk_Zc1DZ&Wea`fZX4Q&uc=C`i`NkS0h#)lV+seq+n zkFBN-f{9ev2LMp&Ek8xC(ps;rBJ@cG@=7P+! zAI4O4X7~E}m%ENX6IuE&=e;EqJgZY9002T|{>=;Du{94G-Q8E-c(MD$^X9sKI_*Po z(%OCoAMo;5WLuHN{? z{Mhy1!(9OYU>C8XwPAX6i3Fjxke|E4 z(c~~qfvB`fVFFh5TFfSqsgmJKUWuse+5oh|F(pHkg}mIq zX;Kpe?yu_KiJwmEOZNv>Q>1AzwG6pO|Ev01mmce!a z6^RbDAsrD=gHGhOr+335Qjk*93a)$CFLpj!&2YR-UWL_2DmOf{qf@FteZLNOKolqK zzwdMNWgfAC4Cr5HLsz4_#fEC+cA3b7=ZrO!MJ2A4jPvCKmU>cag2dXjd^*L@n`?=1 z3*z4>iadwmM2o4O6A2->KJe6&a;nPek_0)L6DC)Eag9T7XfW|{GXg3b8*j;FO|1qK zz&KqQEiPQ&T{4PTRNGxc$+eEsjwbUkE4_o`Y{hYgWs=1zn+SSkY>?9$bO(LRqAO$y zL$U`|M0vAXOx^u0U@2hEQx{Hq7JC)$bGKwX=WoGqjvvd`Ha00-Ks3+>d{*? z>5g#D1d|MjiCy(^Eo8>Fi&+^HT2C)@m|cNbD!;Oe`!HI#lcwB=q8hTzhemE^X44V% z_QdUJMI554q`X0C{X!jX19K;UD@G_NBivEs1SAF@?YBH{F@ z@%B}{PKY}!-J&SfsB(@+&8?qvS?i3o-ReQT6}QFYRs2Zg;#6>!sld3dt;`ezj-gQO zh^Z=&@UHC})DjAeDHJ%iN^Rrz9LVjgl_VH*IDFf0A;tI8LRxLJ@Qk!x+2Z2n;W^*q zjs_S}6g_%iiDRZ@dFKda%?RESs}$D|mA#Ouc*`(?Wp`r`ua-dr!{fiRY%$4}9vA}=>R`RD)4FclRH*Y}-BC4*VaS!wCWaI^@cshlt5^@@d!b1!}`;P-D# zUJ;lQn_7jq7@Y}es(aXcbl>A&1E}oMFaPQBPyJa}?*N_l-T&O5@TG*v7KR>pRK#om zfYrGPAhIy7Q0q;etxXsqCdWpAP=Mr)WO!#|_%#@jr&B2a03^GY3|4?p{PjP6PAEs9 z-=#$W003gqs8k6dggTLk|L#z%ByV26C>1vl#=}+elE?!9rp8BLi~=GvIW__y7-HkI z6Qe+q#By+QY~=c-x92YX&^7Rg#cBl-j}XeuJ8w%ooy%qc06-GW77GL+LZ#^JI(7N& z*C9ncllH0WpO=ao048$TjL4Ss?tOQLZ?qqK^7=2o!LqD`nYi4x!RC|zGCMJXk$Q>E z%}k6RfBMgbN+#joKoFb*X117Enz$ti48t%=m5MDT=xm%&Xr$uC=FBan&IAdWB8`XV}a>azfXeM>`w_f@edqa0FxBvhQ07wTn1Uf0xR!@&!TU}nn zN!{GUC?urihWb)AwsYrIfn~~tJOBVDsJV%;dtUtJdvAzLR$vRIboj=H7ys+JBDA=| z5(@_)?ziMZ7&Ax{B}p22 z^ZQk;htjc-BvjI=?k)}e!8dPR_?aZ~5RBm38bF66R1*mWv*Fd=NB-xv zb3gAmcxLs+uL8Tfh}@Ljot3GrKrBy=jX*F8L~ed&G7*mhkz1O%0{{?Ub$oYo_M>x> z!2CAg6PWFlIhfFjCEwMHZ=!My;4lyUXw)bw@CT)*6c_zx`ttC z|JtlfZ32=M+MHLL91x#gm>9;DR-R5~!dn0UxHP%5?eTecg0mNGZO3OO#zn47({zQV zAp}?IOyyh}rSu3+PL7R`RmZrDvF}L?dU5%_^QKIC(ubq zVsM;b^Px;|O=)r`ybJR)lNy69>RFWNxYAT3u*IE;H}aV@$CLm7q}t$Ln}H+-KyYw* zn9J{qqQDp9qgUSf9ZVUef#jB4DqfB)5pog$K#&^W(wJEC@pKyI<06wLG|r8snR~%* zWP3&8@~B)pGd>K788#oh`R;4ET<(LHzo#)*qZlD_^u0nM@{C+AhY9uE^*0~-!jD2L z!-e=ZW$hBU3gF8Us*4787H+;d^y!~0-#*{I=WxgFLkwRAkdqWU>55VmYEf8OmKFSkDlz2d2~9v}EtU-srRNZ%y0|0Ih4iXQ zQ9P(X_poUVU%!hBMS!ekpc+LhmD6ITY9&IzqO&_3*b;PsKo9QD3wc!6y|F}~_G_Cv zy$8%rw@!jN?UR38aoV`7gz}K@!zj)B_txxHZ7OPA>Qp?WP{>pkF15tThf|GJ8u;?h z@VikF&WgAyS0J1+83J@baVHo5(7MMYWNa?lA30&h92s;KVb+s}+&)QG1 z0BLNnmp@R~5;9xDPr^`HIP8z2La4y$%$dpQxZW5ox|(ct`yAB@(v6~Ot-JxQs3Gei zAQf~@YS%Z4Fy8vp2*reRy9qhUXFO;seO*H`bRcI?A$-x zEPe*h;siZpv>(FyYIF|gfxq1^>8f;%XS0ElsY|00@w&a{vlNT5py|pbJBu1-V^aE< zpq#oBiQoZeHb$lp7hf@B^Y5jFLfdiFy-M`cCnEzA8lVmOXQjl!riBYpj`FHFPOEJ1 zZPS*l@i{rZq`&d*YXaJ^DR*k5y_f?B2F=!$Eh4dFWqe3$Zzr}1i+7mVI9iErC1}Hm z%q@M?ma0|tZs~O-CdZ0WM~2=}H2Xb=_9*vusv9Y@(&jUpuzf;qQQNH4P5BmBbbcrN zevVFA=PyYLmlDIXsZkgv)l#LnmUKR3=yF>c9~L05CTwv zz|^F|oK0coE^oqf>-;a_llLQ#6u9z^dGEuj*n%sXu-ETnb@fz5lo)k0qUkE=AZ7ET z&c@kd3W!L#kv2ljOuob|FjZ^HSh5J1WdtQlYJ(^j)~CL!vYG%4&%W|Ak>`Ej%?h%F z)MRYIO44{hTU>8Gu&+0=%qu)1CI$FX#s(0ot{7Xz1(q$AfRJArzdnB9KeCW*w^VRa zs?CvCN(#jtnZzUJ;`qC*aurfYA%$d;E|=LD&^p%cevtD|V`+cK{zJd3CM`psFQ$T+ z+5sf~!moZTNdm4g{rVq11q9~7Pyg+;w|?&RY)Fy_V8p+C=iCe5)|ji|iZ`@;`|#sm zE+@ADfQ>B=4jw+fG4|H;U;ig=%@;na!priATfAT9p;sA^T0O)i8 zpuc@}1I85xkDYW>RRKweZH(?eaW)-TJAUS248saB&*2ki65BIb|BT3Ug_x%hUU}xv ze>nC2ivU2+fBnb)xer9#_3&rEA#tTb%mV;uY3t}X@)(`iuvIw$BxB2I@76{kzH|23 zPf-*F%MAB@^7|4bMK-4k;g!C&4nd+M*>S1lEu^@KcmDmvlTU~|1HpvVW`kkk_|spJ z$z&3QqLgWOYZ>NaC!hM<==pyGWcBlZ^(us5h_c?%|1p%(LjWSwHic5153e6T^RRDc z8v>HTb%Icu^3hF8wY!jx3rKajSR@Dn!IcAp2MtCuB1TY|QlU_>g(v`kE|)6V;Lhr7 zA)A85Btw^yyK8c5k0c1u-5prfXlXvQyL8Liei~6VakMgp*uu<| z%GPxB)Y*W~W2)Z|0AMPN#M6P5@jb^LKtX)^#=Al}I{oesAP8>l=#<2YXKuK;|1eWb zJ@!XmD(8|4qmwV}(8aXcR0Skyd*b5I^WS*#Gyh}e>Z|vE`a66+z~)0**Py*=z`H)L zvpAYt+lSBn`=ej@M^?1&E|2vM9?3;EP|B<@x&QzW1nob5x}&=X!1(6f3*Cp#@Wt>w z(%F0f01#Xr1~4969;VX)An{Lq_Uqdd?*JHk;8TB9h^&ZQ`T4K@D*zz6ad+tcN91z( zo|8{Os4N+a?95zy=1;!a+}fUxY(D=NFT_@FZZ1wqVkMhS!>R_hl#Z_rbH&&@Km6pr zp|ioQ6~N^j&KjK3*YzE5>+F))ETPnv)4NP+kr2{TnS_g#MT7ZPe3dhV~*M$VxMyQ%2}0H6@_ z^zIp~ayo5o2l+|{03foZGmk$#6FG39~5gCD-}v*v?OR>b<)?v{*Fl(R9JLW^nJ3i%v@V&D@X5dF=D6&os}uIDGH^ty3lkLo^7;V!lY38R03ZNKL_t)9bC)#Q9)TQ0QHOxpP>nTL zs*@^sMcE1vjoCdU@njZiBsGI5(LtCXQlS!EbpUDEvi6XVKYrlzUn=oBr<_$;2)*$n zi&z-BW3jFcg-r(_OQZeKo(>yQm{rE;s<~c^(V5`DV@X6ui1gDd6KVxBxk_64%2eEp-)?L zC%7bT7a#blee{EEC#h6olbb8AUf#H(7P7^+ex04A=#`!t@j^#xE<2sCTI&T_Q-$bC zQw>Z->(fZL7cTwq^8ae-)>OSR^JM;Dv8JNUUSWkYglXUMr5Rvm@rKQf zaSgg$;Q8r_WLH}@OuRR{yKv`XAP|UiGFkW*VA2x2xqSO}KB5^|R3=_pw$PyoacQ4EPwAm`^X?{m){uA-~YLUNkOVxlz0_Aq4hTF|*C)6IRr1 zDn|*VrhZr6mX`%enSC}(7xjs1>Jhx{X^OX8J?-H7f3C}T6ZbUV;#F@mk| zHW^h(vUy)gKEsnH87wc$$9__O;wb15K>xggMTxt_^v{k6J^$Og$7u8ym(WZ1<6N5*pTLU!5OzUnSUtXb$x$LidjtmHPL z0jP$MItD2fYrE_rg)@$pl%Mz+v zz4_~j;TsUW`To!UA-Z`-X|4kRbf0(@M&;h631?G}R9HRt;`b8qxYAswwznUD=otZZ zy!C@m!-(A6{h+$4Ye1$(rPSKg6&Rs)275z)AJzaP1a)r(J+gKik{i1R1|cBq&VJB# z;H=2y-~8!6`n)?(CHnezKMo{G0&poXlJd>L^z^Gg_*%g4)wuQ)vMHmBevwTv-hT1IHhF1|V3&-UnPw9TG%92E`83PNdq=(*2wg}9^lsn*^> z0HF7N_IHQQJXX#G1KzE2KAqjV9NhJ1BOawjBU4*i_ns6=iROb(KoDHYCFJ&lx~g_q zrWM&TAy)=A=3ty!nw!e)PO{}Ff~%@p_ni`X9sqFoi7x>dLlC;E zb)VK&t8*Wr6C0kX%K!jG*;vYDIv)57k&fw1cDbnm!4>xug%Sz?!0l@vh;+H%zauF3$Jv83Zzu&E3*>;z+R@q2Kjd)M0(m{13O@FUFQKGC zSKZ#d?&}q5K#L)E7`yYek zRs^9f)pf?&ezogRI_xb4hdGYZxd+)wvHs|vm2)vnuEe!&1j8X11^^&13d88_YacNA zm`r8LC&N5bnz{1I<+oplab+dDiyFG*1~52SV`-+SeSlh1$6GyWz3Kx8vlU;CHIv5|W@tX%8pedvGe&YbT$@i7D^ zfh1b%dofiFuBl0dx8+*L_?5Q^rRnyiH$}D(4S0V~gEc(5;+slzArw=|mu0?{GGnCD z%4U_-z6MlC!A!)WWf__ZP@F(>*~KJPh7-PmXE{N6L5Bs&Br)Z!(AY;;vyqH(cC~Y{ zfb8ZgA1>AB#u}2iU74o131{;axop0xv}EUAZ)U7*>%4BU&+nqMXYpsi2wU2BE}Zt>pm{@6f;} zAx@)~?So2v2oB0tmDOp)$450#Q@zYkRv})77y6nsOS^xePzM6BMs7bQyhoj!PTPt=opG;jWry~`HYlC#wk_@h*6rw<$ zFLRQ}sEaU^Z|x!zT+-U6OLNyB+w;gqsZ`)xbto%9D1^$(k=WgIal4d7B=ML3`PWHa zS`ZSr))1F)s(hCKgY=vuyz|v+nZ17hMVoLH#xj3Ko&RmDK zmy>x-GT>ngq+oYH@3D`pa*`-$vF)Y0zUm*&>)L zlBPyAc#;VoM(_gGW#=GbBR7ZZfMfq)hU0BoK2){e((nwB_(C|z6zSD$DkCU08mEPe z5(+oR<^+XHfZ~>;1?VnqB*?8|R)OMHhg)ek@G*j8@)GYrwXLxr7bOh7WTv!J_EzaN zkk%6p#ENkX27606Upj55+%l1}thm*=o&o~RY*#l((`tFm+*)aCI0L`GDW{YRya#8_ z-A!-gv_9K@e%2QO>?6KC4K&#-vX*wxb6wV5NTxJxQ^~G|ZJGVZ(N7k{6FIB3_My|I zp+92!8tp?kk5;|3wIIs6Fs4tc?#Wkx`YR@^K90r;+NQ9|hQ$$&^_X>fDS-OpnYb#` zP_MThCgfF8PB52n1S5S-jSv8OT%LXZEw++od7c&o2!UY;h9F3d$q)$22R7l`FB@@r z$am-9YOoLRRfL1|$h1v^>K= z5UgVpnTbgWf(WIKr*n>$1At5X<{zFyWD14Rl?|`^*XALK!3|v!K&Ib+>A^4j*xvb| zP{};=#cvEAJ`SVA)c6P_W?{;i4tqC8el2j7d@c(BfM9%X@-6^~$kR7IyeM)d0HgPs zNU@T7?MHt-GcgVmI#jMp#H082ty0MZ%*AeB`#>sg!F*EWE0VxKxMp%}1VUv%WGBal zfh0;IKYeFJ5;?IPo|za208F3%UoA(Tt*Um4TsfP~T)*@-kVJ~2V3g#FiI!u3bmgsI z0tC5NE+NXz6=SN}ldzOM`Pjz+0CJ2%QK}ALBCN3PS3nwuqbRxg`8*kdmCe_G^$nV) zt?j4F;aQ!v8WPeocZLy}0!HLdefH~B)zy;B{@AC!N~gV`5|F7(l~Nv(AOL_ys}(Dm z$?*|Nq2!Yj>9un(iUXnIpTE8|Gj=aM+*z4sGG00p0x$yDcxZi6sWtxh;$G!+YIFt( z(Xez803cJ_>*^cwnRGcgLT9|$@Foi9bKX%(Z>O_yo=z%tCZUom#J3fux_mMuRU$IE zvKU{_<#HdMdzoh|`yTjsrBq<(GSBlYU6hduM5ej)%D5Klt&OckNyt7xpZPYz|YH=kDHKTUnAM@vR?y z1r>Z4WynT-TO%)v0$0do0RR#moS(i6i!@AVFJJhL#1{XrYpknp06;LRFeT%W|B^~+ z=ibIB#APJDB9*)lq5W-;2az*(M}f#en0jLLHV`V3#NHXc0RXsj{$H98K2g`$B68*5 zrH3erLb#$Fyj8pBshbymDT%zmRVZthR0&ClIv$IbVxGpMpT2Vb<>OC%Vdl~ciFn-E zdp6-2CpBhB%ukHoh7eqm*!h{sbSeo|e0SdbmL#$OLZdq?)7Q>P0z=dE?BpF#iG_Do z0RRx6y?yx|T=9SW^pm2f=GJx*R!RcP^E`yBy7~qH0B~`3cXcuySVht7&fHBPNkEbk zzGa=+0ReV%;jT>MkVLka*Z}}Qm0&CyU7VYZu8-_}`16HaPUIPyri;Zqg3IJ;eRO9{ zWYRE#kKVYda6imNF3KH;fh2O3-15S_!qgxNyuoOy=|1(^kN#%wk^2xFhr|K^fKL00 zaW83bMz-b_=B8x|&FYmOVcaUEvsUt9@10jF8hiEPb@l_Uh9 z|C>+%5Yn7UL;(b~?m32G7?TT4Ts`Yyj1QyrU00@$V zvWS|a0sqSAh2x+6kEzSA9)94-==%8L-1P5fu#l8UY6yj~%AH~KVZ_i08w{p3f-`W1 z(89YJVdO347kCsakBU7l8NuR4d3}bDH)J>D~AcqcqnKIDdQODn{k6{_fP;&aD+8`$CtI&ezbbGd^c~)EBQNNa1;MnTgx*h}SVXD}< zo0n^vs@}WyT3hozx<+SRliT%kXdVj{-}i?ml(^cK7CgSVO5-65ZajHAu=$?S(953x zo(8G)pt&LheRS#jwXJS*s0LLSO~E+ZV~$C*3|68W<9P32A)Kl!WP%2{W;a!%vieL& zewTCU>$0+yjq8j0ZuM4K=B}_@zF?wMyIF&Az`%yX~+iRFO*iqgD~wJCz$ z>-A9%Z>-+PNAHs~Wln$V?#+5-Q&?VcqzWZHvRl|yi0vHDq+?#HQK|PQmQo38FE1(1 zgaV^F+i8{7zd0Om?d#$28`N%H*+gyJdbOo?h|rj$5wuP(DK&)8Gw0A4m6S2Oc1x|b ztc=enOeQMO=uh1;y1G5*->5p!$-v5Tc)i-1DR4Dxv?e*YR!pe%t|Dv#u*|)+8L#U< zy>R=S*>$`(w6z`0nD;!&prU5-n!00XbnYsmkS||)9XoKWU#ZSdjW(P(3wvkZzwnx> zy{E?Rtj^|l0ax_*{fxVzEbf8dqxezv`D zz~0dJ-cP>Txc9+)X#V`qe;Dw4F|ly$`EQmZ3z&>l*;*7zMPO~Rwz*T{D#_iI6CeL3 z58I=Q=bGBPnS6q@_A{C7t<}ZO{ijSiN=D$eroq7cdkyUaD26Ug+yDSHx3;d#jOmoP z+R@>iz9b`XjMBFC?p?n5hPl44WAIdBYmC%d+x9;INkY;)UDwp+-`=?IV_$(#xo7UC zk|O$t9urDwjb7h*^y%Qz^@wlXP}8z{_iD?*=Vd}X6xi+De_uYbhGP>}oBN`6Rt@>pyPHOOI$0S|aq8`?T0NuYBH9EBVE4tr;>>s(uAaSq%`!{{tTkU&}E#3VH#qjFdx}Kq@7sftp-g6oyh)mc+;E2ZR zmLU?QHQOwvJHsD!A9)1VHD`BcRgNy0%lg(A)H=PzY|dqpwcSG&n+=GZREfxxIv_AA z*QteDuhMkcS>M7lv>?%uIImwI{p_q*5JP{D4&I z{aY)I`#-jF>*dztpF-pYJt>qjFns7wZM{KZ|E`Wm9C!q!mFcv zDOu%i!Hu0v*1NU3U^Qu7b&Zg~655(d##>1EA@2XY4}Kt*)f^uENyX+1rCibU+jq z$Ik))PJHI;FfI+P+_AWOdq#}azE!=m%{zBff(islahDV1XVw@?U{yH9$j-YMksp7wT;XKST`+Bt*^nZU|jovTkGm7aO!CtdrVHknnIUi+bY^fQE1 z%2qR^+P*mcQAbx#+uqZBEyGvymd^dIX8ZK`wZX%WqomwBcT;E3GqwEM{8aB?cVKB; zt&tT%^AHe2zSXY1r!!l(n|pSl>i#C1%(pz_?A|Ld`C2|nDKw|Hc9wNfOeF*`Iy ztF`-}@9ssID;b<^gu;kPb@SurWF#_l;hs7R>q{}MHPj**_r@V#mo6{xR|ZnnW?8~BqeMtq*SYwmQYGb z7nDIy(|ni98ylL8+rni}ZOn$f=cX?86y7mWes$^w+3Y2?Nxk|el=`_LIn9-#a)Fm3 z4UsV-1T9u2IGiW(9LAzj$p(c%QVgOtGq76Dmr(#aD-@G*G>WN#G+_fk7vFPA*niyQ zywBe9Y0j$9x~E&vWT6N|TD+U~YIzukjs+trt~?V%{pH$Lc`F5SVXI%iK{aDw;Tjsh zkqHl2@TJhgVXZDuEA241(`s{JBae)#)Y`dVPVM(frdNwXyqFw2YwI3KpgXo-{w`t6 z-idE2rEaCPQ7o?;44o2LIJDk^x2P3&&&gaNyTb0Nq(*k1G&r7sk_8!gFVE3e&Rk*) z-8HjuH6A3$$!K+T4K9@HrS;c0X8J1>f|WyDNFuxKOTmhUCR@&}75D0O%gb3zsqAWC zYE*|O;e&_ed^Mp~%+ES6q~3mIA+$(ig!$gxl|-KBdu#SeKBuTt1ZjC{-fXq+QQ$PeBCBnh zJDs1?Q!c`|xz%&Tlp%8?6M@bVma>x&Y(Qv7xLn?9t_?r>+g0V5d2?C4GqyQBHT&vo z)9?Hu^ua3%jFd~8)5F81S|cCXT@J2uQC1d%;FS>=Mk*2f#_O9a*is~Tvt~UWir!9C zd>m6RHI_oj0yR98kXFj;mr!&hmLe_HNNKA+O3zt&3RggmW4cDB4htf}AnC1Qt6?GK*3!bM`-kJod~3zxBIC(iFJ=32b=Kw=`4Cr=Qie z!Cd89gACuPX2Z$V{RDiu=7tochz^j>gs7_0AvV9PAmv;32OZn}LHS{h^>GD&DH`mJ z^I$?!S~@F1r82%w7s?0;8=Lx)bZxs@3|CcwMPEqNtzLiK(Yvovk@FC^%Eo$k*~);p z0e3{VXxGS|04~lJGVY!emGC64vq-egR+(xxxLp?TrSMABzmyXt(^sC42~aH;e*Aa7 zQAx}TqV(b4`McfwMj?p-fKUD){v-lOlp9(g2m%0P)2VW3k}`G(d_BH=o=`WthEF6z zTMec$aPOA@Pa{y(+O;1eDQ)XPp&pnSzpPX$fy5cuTp4=k8-TBif+)9i!3gn*mZ6jy z0C3~dIgw5`4)yb^&EW^WEVYizU3mW5`42nq`NHy*U(+-V8p(~-B>(^fAqu1G)gS&j z;2Tr#{V#~wt}^iP-JXUhwRenddjS9tLa?GO=v@^d35;OwzFm~o6$$u8?l}cSo>V)e3XRgalTg?gx(?Mh zE0uCfYdc0zN^1`Q0Pt0rsa>W}79#U+KmP+!6q&s5jh}pn<5(cDVr4rQ3)D*)007T% zB2UXLLk3qrhc;RJ?mP0(lf~d9OlW#{9smGXx(+?|?AJ4aS>wRdl}yOk+Y&unq&--t`eC@&+LsRGVcYcaWR5Fce@%ANzP`L&Ul@nW(p;c+`M`iX#DP?OP znmYF)jLUDHdk3c!daFaOQUh25Ac;^#*j$k}?HBoKCcL3-8b(RQt3Uk9soP@!fH!~ok5@nbP-F@SsVs*l z*>dzZpByMt;O?2>NB#$p_w!8c=%@c!=h?G*`Imb4j-GqJx_s@``#$#Ox0If{l3NBC3v1=c{^`gb$O8V|{^`b@bsOV+t7vmd=^)Udz)U7cHLN;!`*eE4XxCE<*{mZvO zZAGcG#=SG3=3VoTiB&(zPmp*>-FDKyvD|n6p9u9(Y5nQUH}k`k_v$rM80wH!#BsTT|y`=hLZ~SeT3~ngwO4J>}#abwshsCjss8p zH@YhT0IV@`oSv<&ms1;=KnmR`re*a;Rm`M)xjaLcL{!L=UXc#e#1CTIYSRvh%%LnJ zZjat6l`f`JmDN-sR=rK5UbEOdYLie5Yl3B2IJ#7LaclNv|J-;q^P*upCZT^=TD*}C zUd#LM-1K|WQcT29bFPWWm~N5MP=&-Y7Z#n$q=qWNP&a@Gp3W3-a1)%7TjKsl}qIjVXwrbJ{YF0Yx} zV^#$(Zx}RIwQfa;GjOfsM=1nW#_Lri8ZXtuG z7E0S?F2UoOXk|M^epcqak>EwKz%plI+o4+dRwm{-`6+0PZb(wouLNq!`vpiHBO-7Q zlx3tPY9y3iBp}i9P)8;PBJV_#6&7}E*YlZD zmNuP8<}&9HWq;RWUt=I1ZN*zui`mY{9o%jf?2`7YPdsRvT8RiMNYb?^praIlt*%Yr z&HWvFU4)R?acu9#c0!NB^43sf^^T7#dDMOGq2E83A5z#ofd{kRuD{f4}0cp#HbAh{X|DC>(s+eeD{<8YHuHuFr@Ur zA%F9U>8Lt(OB5L(Dwoi?WH1)8$tnU4g&UQ2nIur!l*t6dn3P9bLB22x9pN24g20o} zkwo+w9?ti`F1^IKD-&fb*?^zdRSFd!wthAG{3~zuAKTd!Sbf~yD#Mc_8WRAZz%oXX zGLRGs!`VioU7^X+^~SC9<#KFg{=CqL^5ukWV6-%UO+sfWts$LUP3;W@-`95RhEYzbIyd^Hte%_)0KD>pZ(V=$hsU4z!sdZeK~(+MK;R;v>$xxhpq`IZ zv(bM$tOx)o77Cc$R*zm$bv_H|n8?wELLNp5l+t8UslnsVy!oSVxIL{R&tlA+MsI}J zbZmQtRGR2Q*t@Y7-(IPtyp2)}mnuZ2=$|g_{NG_f(k)9KXK90E1CT8dH{LYs>sTaqX=bUDpd zk`ir8Iud~SEGbh(H)pEV>e7{0m|A}SgP(;_oaZVqn)^rdGOq_FZTHJ*$`h83^Xq&FG?f_*|22!b?P9fS~kqvYOw`ocReLlD#`#gy)opcaHgIG4?GwYFEOrO-fPWpQ>2#^r#kdNu=<-RtLSvFZJ%zXHK9jFK$N)~jVwro<@C(%mt= zd$+(dH_yMX>U@@tUdCiL0O5^N>e~4a%{|AsTF%+rqO!EU{rva)_nk6ozU(8Jc>9W9VAB_z4JstupmGQ?CM%2BPTd-ACsl zxZJQF3(zp>GPJ1cc_qZDtD7*4M?wKeYyd&H_~DxZQ~Hml=ih>e0R#|So=(O8}(>>(}>;dU)vNoQQ4w! zHaFWkw7kFM-AG7uawEmi34t&&iv`F-Gex$sPiF(9uHhjwIh9pbPo^sr&_JxRjOhe@ zAfMAHb;aajL2q@J30Yr{dGf~U1Fi0HF>kk zXSXX_%9tjla8hPv)5#*yQ3(eUe7n*BtWj-lt9iC^{ko6TLm;KJ!His;jb$dAHDMU` z2^d?-SsBQKn@bQ&z`D@YH(zizKgl?Mt<31Q8cPOJ6-$>bx=y7mi0RcdlA=f|d2w0h zK4h%7k!A*2xZI=E5p6B!U;FNmrI%Z|Y(9K|CUhL*TD^YF(z#o0=}x9s5s6^GZw~=n zg!-e+Ic=f5?IbO?FTLa2UeR^jt5^G^)*);YkXn|lb!{%pfA;>P1+9|D%h812U_GTU zC#p3QQMDp=7|S*q76)1ytmH9>M9>N%sddA~P-&@LpjI{Ev6{P)PZ@k~y{PNiUtBFX zo@nUa7OruOUUNDZTre09q{&2&(Ib|e+1xTMqulToZtwI?S9i9Q5pUN_Y`x1s%r348 ztY~X_q7BJRzWeiGM5^fOd;Y>(ol0F&;}$YyWfb%1q>D*6u9E2`_O;DGi&TF3;}6Wc z4l1q9@%1Tdmr@E*vbJa;szKT<$wlV&;;;36ZOi9h$OdQogsOOCXnUptCzs5F_tRDd z#8B|US>55^E(GQb+H#ha)+#q+QvuiLA7!c+&E#&uRY}cehNK(PJ`h&sn%Kq~T3Egu z*^|MpX#*aeYVC5Az&zWL$x*EZ4BHW@BUavYc`7r3W2j}et5HJ{YduQ_&=4irk;{FI z^2QQnt1p(^!*r(ZFioy!97d9FMBaN(0HV;@onM<%gVr$4SWFRNi!Lx2M8_Lh+l`qQ z9X*e5VrfTWE!+8sBp;}$n}G-v@=0Cw2;b@uH}0yN?%lv8TN4*M4n6AkE^sU%3uM=F zQI*Q3TJgo`YB{xOZ)iw7B(e6KhkXBhGT~iWARyRW}>LOQSw|!9#5;d6V5MiBeOv!M| z$UUT{Ra~0p)w?w&Sgo8#R)wo-bt+j?ndB!1_$Irum;j>t318GYR2cN8EeUa7M`yTy$y^@IgW)DC8 z?P_!eQ#n=EPJ}Nrwc`5XOh;FbNEe0=pF*UjQe>`_O{i5eTtY2R-RK(_Hnxr|-a6OS z+ov@cD`|gIYZu?By4t%U{>{$a4{9laspXkUnw0B{(e-*EHuAui0apV6>f3*6YvLW1 z>xf(_1w2!Xuj{m0nM~%|_hpDLZO&e8^0Zqm#;x_0Ca0Z{YvTS@+m6p6lmUWxl>0as z>NGl9q4n`}qu!&`iTZN$Kw}Bcn}t4i-^gK$wXRevRjSDPjKt&BUVZMb z!a+YppzS?_YqPh_O&*)WN#dB%;npgp!EJAQS6985Lf9}<%{D429DxiD4_hzR@(Fv_ z{;r+(MAoNF{ht?WUhmv3Yjdl{(y}r6u}Wv|-FOB^tGP%9fcJTA%;BCS%Xm9OGdB+o5^P?x8aCzD?!IfRd9^-47@X|GB z{}HJ|2?SwzdaS2!kgKFWp$eVbax^t@bcwB(TD$vW0bkpmXH{rM6gU!L0atgp+sm1# zqsi4Wd_281>*?w(r$bW9zFK@Lxi!z#^CJ&@IXwH3%zkKK_wL}_M-)YRx(5&hXG_tQ znOgvWkw?GHWS8rOw8=ee(aU`6%dMR~oqHb62c}U%f*_c0VceioBPiC$ZSYKm&WGhP ziO91ueG{lAO`aXDzJtM)TP+&F@`rvMWf1 zAst$`I-BjTc2YvYKm-t|6>|#ve&58)!Sw~#@VzK0%}0F_+x=?2^2VFrcMqR{Nku8< zWg9i`>cZZmC)KX~)x=7pTGqAhEk#xm@mTNS-x5WRgn6mPRE(~!%un|XcLx^7R9bCv z{f1O+TA3N|J@|Bd<+7>CBh!0Y+uIh#&$k_ThAH?Y3Ik=`NoTzaH$E6R{76UdP+)O< z;J_&$G&UwavUQBAOfG?~g?(#QnscYwxh4>wdekNZGN(6&%LB` z;N18BU|`RQ^Y8v^%iz&caNd#M*6%z7OYL-K)!FP4xjJ1+we<|9<6-x%XJjBIAxVU< z3rxAGt*;Q@Y<9P~29G8;CtG_4>cyngvWqLON7wEY621eU`c`u7>L;rq|EmSFqFS{k zZl?2s2?G$sn&6pq2CgJ{R*;z$qn@4RIf2RG%NKp4D)orb0mZ_3v)?VEe%~QXO zCrT`%rnsf4Xe{cR%*VadOf-3C?QU4ki5ycN%VzF+KUxo?Od`wqqB@w!X;*RyBe%+X zOX*Q7sVPL@e26SA@QEr-*NUO-602ESlGN2r7HUJ2zaf={DJtOHtx^<%T8Rdb+7gjK z5i^Cp2E^j}^1F@okmSm0hD$q#?uQ{?sGejHomOEeiYTxJEg(453NZ!(;KmIH~u!BGsRLAdOaV-p^jQ;RV z|3ZY)@y;R4GhY>KkX5KQ@Ez(t4G%(Wqgi7pG53!Lz4i{PT61uF;tnU@A`!$)N?lUr zkj5CKp|DtY4U4>?DHx$8e7;o5$vTF~+C*ig7@AJkQ{m!jnHR+@e5ITeGGZ9kO-lRd zoZJ&Ea@gvggiq<}IHgmLY!nJZis3gt490cl55~Ty#E6^e2te8OxsB~$`O@1furg)1 zvuP<9iZZsWti@)^>6|&owfL7JHN+zAlmy59jl#-o&#=FGR?G((O}`c=B?#tCL?sAf zDc)N1yDUdLtfdfQKbAoutCd0+!9|&~EDOkD+IC)ruzZ;;Xoh5kxQGO`+0;rgCIEzv zrz-n zP9~-r0#9!?@~t9av@zbfSb80+frO;!4KL?~o^?FlUe;~@Pn)7baLox2>KBNlaM$3wsKCx>=DYPKW>M&wNILEdy7uw>>;Lk10$W2E|C>MiCx8&Trh)LndCJ&nY#*KY;GZe$?xw-x zp}CK5UizqY^bz0Kudjaas#s5+|M{PM_}cSwqgxck!DFAc4LpERYQR09H;K(VD(6t8R2(|_MMNwuU3uZyr~eSabn!EbKVlm^ADxdc+vy;`a=hh4_GYqPD z`zL>2YTpe+;hkUo=+4+RfKm#hCmIR=`%~#W_BEx}wCB{bxczBdB5NDki%N7_tLwW{Eqnh;1nw#5D zTmmB)L{V_XKXv0@EgEa1n&*fPXUCw_HZpSZa}By7F%Cf@7{7Ej?wzMJcJKO1B@^yB z`BxH^0q}KO$H>UxQ@B(yb^eu>u6~Z8VajA}=~Ov~r1rg~T%wV)8`WlZ{q|-N+bY)YB~TQq){!ijoQqGm+SRZ||*tRzk@WPbI)O|vx zHk!H)L-f{__g}to>73TJbNa&{IffrbKz-@buN=MiV5IWRpZ!x}^Uf!(Gyni*BDhQ! zkA~QC?EHJL0{|qZfvw5+wXH`G{jq#_@xjmksn)YMzP&<7HI#Mt%H12Dk(2tqXOgQ| zyZ1i?aQ*ey|DjkYpo-?X^FOC-krIrJ~d;HPQz<_}f^pVg1q0G=a zcjYa)TtO;Lq{2YSRkEf-O8X#!p$NUOvM@)<6kIh8iK1L%K%p#GO||t7)A``q^;asz zEGbn0020A1AaD=_GYnnu-wF7)TRXc&rUJvH*4{2kd(@7Blb`xrIkDNg=ZQ>kMc>?q zlJZag!FR-Z&^GdEfn(Wf`urQe=-+=|(La9kgI|@BzWD4L@4oO{*UrPUSKc8MMq6v& z+QdZ|rQ8Dt3ek0l)W}VpBd5OJ(z_D?z)Q5R|Kz*%dbD1z|9gBfB(QKb_Q*G$gGp^y zSHA!NU#ZlZ`!Gri^Oei*{#s>n6;hGSg-HY_?*GEyK!E0XZr8(KGj|?Xo4qx4<$b+- zG_bJ@Nv!6cV=|4&&~`+uM?QY}xf_?xIr~rCe(Sr&p8NkB-4y@;jwg|DGfP<<4Ddq` zTtj&Xf~y4rf`DA-p@WsILB`3Fdb!BikP_})4+IT>B{)-;TZWKG3#Hhq6lbdI6tH*-ZpCJ(Q#*6KGi(L{WG zar&~qlzE{L6Zo#%A!G{}|7>ae7pvEyVg_QXYk`yzjfVNs3>e?c2Wh|0+Xzk+BOhXG zZ_KVsB}gK^K6R*r&NumI_l2afOxed_S>HmT1=*$w*) zrR7MKd0$ko!3m!Nx`oX0-62k_`}LBsp{}DER*pm-r7UM{L;Vm8H8j*f`>B;wW_9*v z&2X^OQZZBsffv?)y!~lMyUkoP6R)+CqD{{_4nZ76Q#%Z4LE0VNvpCM z4O>xfPG^=8+8A|vzGS*U**&-a`9mCaQW?VC*(Oz=bdBz9*PHZkb1#)}mAmpAI9H1{ zrB0L*cB0VX+v1f_vz#we_5mrrdsi#G^NBAUbhxw+Kdq+&GMkd9qz!!sTI#Zf`|KF11Mw`X1EY(m;G{Qo4>66veKFKked%mAKCRM314TRYK>S+MOkP*49TN z0FOmmCa`pDGSseK@1WYOQcacA2C5~)++{i-S5LlYcHhk0Ui2sC1)Th-HIJ{&CFU;K zf9op%OfWRZVUl#C4glaq0fpfCLb}S)#f^;`&l%)e#g&VEwT@#JRVo|DEnBr&jlsTL zDKAn@O$P|RTOG6TI=e2;iI*0xagND_>QK~DH@BxGn9Wn5NHzx(nI%fWofb>_97?0ER8mDyVy&9e1mEFO_l(r~oYSrzR%14C!i zm?T#?TTV_f@WTUpkKFUnH`&Vjw0Ni>K(&R~-Y1Q>sxe79{_2X4#HBS@`Q}f*t3)GG z4MWqd8x#9P`M~49`^`tc`ac@f$my^DBarBlYuBIny}ziYHUR+9z!u;cm^At}Hvm_G zFvX2a=UA4FE?sTzJFxrc0}!tKWLew44gP5SlW#$kW%cT>8|5USupop?;qtFVzELa|FQ0uE5`<(t0s)w>#pkD|{vW+W@Q0rM5?4(FT>tnNzgdbb?ce|K zqtE_PU$49C$uDS6KH7Wwvu~A=ySc=K9B+z?LUa?ofr1VN_M zbprqpI1*T&FQ>KaEp67LyqfT$&68A*rQr@I*Qjk~Q7ihJR^X^x#pM)(iuBYwj9Tj@R-DLar;s13vGjM5;nc!B4+! z_VgV%`Gm;U3%MKsK;RjIAYf9vGWPxhU-?mZ@oG8gqYRy*C;~u>u&j_t&tLczkh*8i z{`Byvry|QYXQuA--v8NXa9%_uY=!V|d4Dr~w!IYzheaUxHaCFC0tiWkHrB4aB5-h} z(tu$MSB>mb001BWNkl5F7&l2%;81$ZxDk z0ETzig<9U>@eauk_#=cH7*_U zqC{S3#H30?F;8#}TCS!9F3(ib5K2XsZUVL-QK*Y?Z>3UMoxF?^(nF8^9*R>CjEJJx zparGI3X|H4Z@jeN3VUn&C004AgX87r^;Dk;glldpkN~KZ& zz{}tNGlSOs!T0_E=4q8{m}^vs-V>pG3`m=|C*Rn2;^A^Sbp66d!}mTDTAKri1ZsqW zTVBAk5QO_SH^QM10Kn(n1Og2pG!x!jzxjeFFonWzUIYFu zg>P zR~p-`Lut`Rw5iji7q3;lYK@&{n{t@2F0qAG*TrnNEE5Y!Y{&BjS51M|l#sHxwVy4N zjHN~yfuf5W8Q#FVnQ}T#lpGM2(L_JKdaiHBNEus+7Zg}|ouy?ZKVgk6e>8EW^{E5G z&G(vGRGW*W4E77vBjwVK4r5=-E*D+vY-zeR@0Zi8&ukhoX98v#qpe!QREF*J(S@dN z)mBa)ntm_1`;iAlr4)k(Gm!vS3AWt7t0a?1*G;%NF1GKWw=0rDD~ZlW=W|d|Nj1sV z8>yY7f-23%vIN8lGEI^XBbod*)IL-mn@U@~i>r9ANu88WwHvDhKp4H`*b+0oJxjF} zd#y;K5&;RCy02$FzSvrl*IExpWVfXSt+#xqZaiI)UdAG(s-dYCyUXJRo2)f>`9j6z zv8S+@)0fqVegV<&j3Q6ANwfmIC?Oh zS9Xn-;FMmXyzGx1s$qV$x`Q8|(DV-j#nSfWSyH`&t)0;Q~^M%$*KQ=j|zZ1?GJiQzSo+@rMgiN0-CcSLWZ(Wz3ZtnN@jS-Pl@ zC`wzDytBQDEr&@&rZ?MT@yT35;Up>+PnKyEE7|hea*m;8&8}!X>~XrK#Z(D14U4=; zR`TiPG&azK)#q@Y0aQyVq3tUJdmpH&Wm5sK1vbkODv+J5 zOKH}UZI`Ia&_LE|sD-x)tF4sUvNv}%_wGOU()V^e{EfDbR@d-BAsJ|W@F_z}Yqn7u z9)5sVQ1{i?dh@{BKmShmt`pU;xaeEc)B^Axi=pCP@h$e)hMKyEti_6GN7{OK*Xq5n zSbyaQe=njQhYNr0hu<35e+m-|p+ZE5!4j3}_2>S2`0%5!%x>%4TZ%6d5_#{w2LVDf za^97haR9)c2Y;KRE0b5=clGS?w6>@eQjNX0YiL*2Kb1?xjZIxE6Cb;J_lN>ljI9Hq zQA@4KRqAp+qjT*IE?#Kr+@W>vvl(Q7r;Y80!}A}(e09hDU-nPEqij0TzvnPt3dyCC zt{wZBQlgsP)HU}i)oP9|VGsv^*wo(RZ0kcvWi8`do1gNux1$oJr>!lQ2;pKyrZ&Fy z^MC3&@MJZ9 zyQjQS5R{&_eWz-bRiwVvweyJB`!yP-Zbb#yVZLQU; z#@S( z>6=$OcOHUZDC56n-nCP&9k}x5&&-}@2X^=5!Z$RIQ4~eWxhMj2CQna2SJ7x$7|8iX zUgz9{YdW}cKw&7Oh!EMXX{|1bRH?O)+PzOh*5a{-MrBawmA?7g))r68fGfJWp)$4e zf*FI>m2UI)?X`{NEzi!+#;)T+z~|i>ywo3{+xcR;gF7%uMYV8qES=(KwCm z9Rpsk_Vn+rO5^z3`6o?3Tw?O|($i?992J$#%_#$Zin)_cy<+D7U|4H|7J9r5gY zBf>$Ar{inmbiHL@-vg~}NI9JzKKKA%&m?`5w(b#1V!$NTjrq-?9c_@P?AyH` zm6{gE-urJfSTGb!w<*-1J51&ax%eaiKoo@zo7CNJY%uYS(89#n?Ak^uvY3mQ8E>`F zr*||PdihFGwkEcT%5zEoS}EtR6h$EVDun{uXfv$Dag7`cE#6WDqVG~tX=~GPp<yY%&v#{%;vIBqQ_{{ehix;ckU}zp>ipRI&Z0}JACCr zBL#O<^g+0Dkl-3T5Qo)W(?m29&S!*uZH@_Zj^zSOqOa)Nl#ceZFjQRUR{Rq-m1sHv z(j}oBMaR<7=<4K5Wk!XxVhun`y27p;)=Fe~V3kP#05t)y!}6Uu`?|;x_mmZ2AS$HI zu9F&TssHLrD%1J9vvW;VnwE8BYH}W3RvUW->Fs=%B~!C#+_rFGyVQKob`K??+JPof z*|^@6lGapHk$!7p?Io~|RWmmld#RaNDLHY`unbY#dGp9#xpoV#$HlNcD94&iyHa#p zbjz_rZ9+u25>FvYxXigXgG2WbOO{A7iTz8ioC%bdH&>}HnHd>SS5&)-TD_9T^*vq9 zoJFdtfTSH#nRuFqWi^oFJ!rhn?y3~!Bn%f;&#( z)V9v5Xy1jUa}2yy)XYSvMS@on^+`tLvhlZywfJXxM^c+!_y*IUZ#AR^U^@}pK0}$v zA{(p+w2ekI8J^7q=I2yo%+vbxmq*}coLIiIekZm%e-?)2`nHBeC#V6QmW%}Q$pe^- z>NBCjHauu>(kRu~DWI*okA8aN#qV98dJVbydRzDK`#<>`00e{41RyL$*RZaAZ zH}x&M+K>K8Z2DIRKlP`mL^JWuKWN*JNlkqV7k+mA!bfu3(8i5l&Pgr41`NGQL zf>hu1=Fk3#R9O_3_QmV(Krk#(+jw(sPVK)D0f>|ea_3rgeMd*~=zuUvlhds0Ii zP167XiMr{5PyIF!8f&w+9{S?9(Q59oFZ?mY6j?!NdE_ZkWZi?c$!iw?02)HiW^QE& z6C_tEw34=dQ+laqc`;t9>lJ#hT#+9+>}DF)a#6Iq-9V(%$#^h~ivsf2&;A$7vN)Q> z#7i6Np+=rrp9%WcZmS$MvrFmemv9nQJzqL<@==!WASrnF;m2_qoArl>_V+@#N2a2C zMn6;Y*n>WVDwTL%9Sv@bz58)y1H1J8>n1ZG$!(Q7Rx1`7g$;tDVN_Z#q%f<*`_G#P0_D65h*9_MXK|u{AW%H1Lr`jcZsNwJa}8P} zlTC(}?}&6_bE!Ud>8!zyMHk*wxn>1O=NdKl9{Ee9f!vzOw(oz))Ojj6^ZbreU+>y? z^zM5rOCH`3lU58*qy!PSGlOcc*Y5+i^(Ev94|)Apq+2N`ta>#say$_a6j`{Y-h%i*ZCRq;a$}@ddR#s+t@4KtLx6gY6^WY6Z5Cpv>Qii))X*474 zjAlbiNh6UGDTxwEhz1l%kRSkp@Xz7-*RQ?z-PPs2uga?Qne&GfJ24v@8@u`p_eR`b zoEztyzg=C;u?O;7-~BU|iDB?UZ0UQhpdE%e3{4j@8~|Xb2l02nI={Q~=zr#cE<`^J zK+wIbABI;*h!|R(yUbVSho3rXbOa$arT2b$^r#slppBUWU)OO})smKq!{1{GXlNH! zDv_l%q0;Ke zJm3nDZ018-*And*A?y{;=;uycJf1ng1LGIjx~wJ2n4uTPk$YF(@%f(3zWc4z)cc8t zzPi3~6951Rh6_x(_t0s4{zE{mmg`lC5wvZGTGg$dhkg@49LdFhDmQxEJ)@E7U){U> zc6rbJ?)Sfa^P^vzo#i*a^PBEKN$)%V@vnXiX^f7J301z1(iBQLU;fWu#pq)O|4|t} zjVe?BJ_QSkrtZT8!mcxs^^~cXlvv3+OgTpZyIbet2^#`ofZWP)7=_vh0ym&%LNf*4>A=jTvZ%EGf@Xrkw<{O8tq>|Z12cib1hdpfR5s-2A3!` z$_W?;iFGojhL+?BHeb(HPA=$YS*@M1p{r}thUTgbSX-{?#*{-*C|z2Ya*~~YZ3|{fKM8xX18D8r7T{M9CDl}XN!%DYN8PP zOg`qOY$F}+_=8qb!F|rk#WLAD0w~C#!bWeRmaS&CcQy;S0CYmYu)+H5_{%Eq%Ud2E@Sf$8XHsx6{9rK~ z{YWH%uK~+GBP}Wlug6jCb(lG#sE740+%2!K$d<|3yMH1BX{k9*Ro2;EWIw*NlliFk zQRgqp=uUcp;3;DWQ93Z(%R-RcrB~b&C-L)_mI6;U%8^9oDB=U8cYf^CpKX9m3t6)v z+Y?3uCdmdL+i};V#cPz2mI0_ZF_Sj$N#h z_9te_8Md_1@^r>p^-^&of9pd8BVf<~;2?%urJ|F(^|ur?8azEooP61J=u3pwYc@Zj zu|CaeP1N8^2ToZH=}B;s6g3)23t`UY%NAFU(KGg(|E1t2(XVgQ$Dri0(~lVq9n}Y? zb=cPI``*w#fL0Vq6(zoxGK6Te&<4lTRkjbAgTZrO{PM$(J{|t>ZEs>!e6VQ&F@jsI zJ9{iNg+s(PVyy9dK=<*FKX_Z9CWOP2FaE|KPW;Ays*WBdOwLaQdT;&m?*@-v1o#44 z$<`P~QkA5Rv;dMKiQ9{}pZ>&`L`BIZst|^^8 ztwn&NEP=VT%nc2p0a5dNKl!I(>Yh|e^nBX?!LR?EPA5ru;&qB46hm;@9>kyrq= zg!lIV2!=s!`t~&dPypN%3Gai7q$tY2CImis`(HYbKHEDm{6D0ARUrrh!sur1VD!@O zU4QGxsv^oFN7zT8))t~>(y2I8*bf~2{6}y7^x~&~_wJkDs#U9=;b$s|WkPQSRX!5l z2O$Lc=9i)-(^HvOGHQ$&cB+E`A68mLxcRRH9Q@c!ljPNFE1RE4lF;06EyL3LWni)hL?{jcvQ9m9z0E6WNiCw42* z%?biG(veM)F2G2uRoT<&?FxX^N*Tgv1Obq5WC7S%OR)8Fc6Te8*`0gx%iY!D76xzn zdtOe*;;rJY!J*A0Gqlqr$%eTHvzGCJ!hF$lxL7GZgaTJNrJZ)7633dTx;1!Y_TI+H zixUbM)ahqnVw7vNB%a4e;9&m!h5Oeq!c<7@gIon8bcJX%z8cSk*A+gtzxxdW+D zOb=IzDG+RdxFZvbt1kGAm0vFbctNsaD*Ggk%3>=|MnbWl2&% z0FWhCRTZuz?5yVUyETYR2|>|HTCJJ3fvs?(l!Tl{AzvvMGxY|S zSf79VcR~VJHae$+{a@sH8GuYyr;cTsh(?Rjwq~PB2OarYx$Oykvp#AtU!!c70I{ev zG88GaAL^aC8J#>fptWD1h^x6oN#cwGTh_ZQilk)HaoQA=MP6n~7-?_jo8j3A%fg_N zj;#Lx!=*-*6B)VHVB!l)0>dB}tZ=)#>-QA(fAZqBnj(Zi5Cq8*3#iEMYN-)zHcA}K z?t)Sh(^M+O7zi?es;T4>iX>quY&req;rTa-;X{LER)Kvd{gi9OJMdVqi5{d)L(Rz- zld<4)pZ^_!mo#)f#avb)NtF@0GN@6dh1&<-)4`MH0|fG(!P@6-JFTk96P}R6-rE#M zKJoQWu?d`)bAsl-YAstLi_5Y_ku}N9P0~@l@%qhwA7H`lga!h^@_yr>S)+VpVWmp> zw0KgDigjHCkX5yz3Ph0LN*26KPmo!-|>hlnmoi_zPx#R%GllS5Y1p>3#m1H zU6=4qQ%>8qb@dk#Q|=fx+g!uhW&@6gv$lpg!@TqJ_fCy;Nw8yPVO3K^@Zk|?tyk}D zRu+K4Q>Otb+a@MNMcI7y`~4IGbX@@RCb_k1CFJSGRHS~dHwD}TT$FDTmh4VX$)3<^ zCfmGRqb-$^f&q1BWvQBPJ9*flx|;P_=tj$P>|qq1u39#3&%}fNN2OG|#}+LB@U%LA$9CA>k>nl2guQ)SqY(4AS9(UC z-Y6{vdd9dana?e&ENE3uI6f~{W_)cSebTnuoW5xq3YK#K9xC@`Y;d3r0G+4gTG2pf z@7x+4ao401i??PR-GMqGBqFa^-!%KE~ zZfq1go$Fgy?2p?@tM-Z^rrC2g=_b+EbMI%bSc7BA)=In1aJ#%8LOyxpt=G6(?QvfH zmwVS9MfGgEO(`CXFow)1K`dK#8E-0bJ!BpPtC98Wb~gtY_7*(+}G4c)=}Z+(Mr6(%Q+MF2FtIZswv9t$7e%D6iFk7VA-*YtY0kA=G{^*Z5`m#$m} z0ATR^g&MvVyPWNre0U|y(50Dr_wdoX*MD&N7mlGL)%_`-tKIG9wAwzY8ErM)y#o{i zLC(-nAm9s)nf4d<5l}X}&)NFI^^7CB7q__|_j+qeYuD%&nng`57nMbF@W|7f_ujIH z2HHY_#QGh3P#fwzjMJDRA!}0~P^PYvPyR=(A-+3vBQzH3op`d6KF}E^CNF(5xpcXb zT{nCB!Yem42&vWS#m1J**O>gCmh_2yk@k-4JowefC!TWHju#Re4&NtXSZbA~NWHsr z@Hcq&+G?quj7KMrov0qHyX-)Yv-XX!9eqA6#Av7cW*9_MYbv3~8jV z!sIyvh4_O)+c9r53mt^@fq`eWXlZlt+R(XYPy(I5G2?E3oU1GK+yke*Gqtw|H0qK7 zsN4=o0_HJg{mOyE7lO4Xe2$yd3T=** z+H~8gvj&5*zjW8t^_-UU;oxpy;xKL#Hf~gW-H*t!DZTwx+u*pXQ={@Rv!h?9pRff` zuB72>T#N6pSXsSJaJEULwv%r_BJWOaWh>dT%GKJsis88x|4EG&8bZ}&Q9aVrPof&B zo&$YtJ&J-HdJIH$*4Szm248Rv4fxv8@bayb0B}H$zn}d5rZ9Q?^>2lGAJg3W*}eHI z)o65k>lD+r+ZC|_a*HQJW5kv;U@_y2nA zbZF};>$UXFZY~W5VjHDX7!eMy@J5fVbFy13G%A^$BTxNKZu@PsQR+JJTYLAXWmeOE z_!(TCSNOcQ(8)?Rj$p&-_`1){y1L9O_a00hJpm}~_4FJ` zce;a0YCq-i>T%2)J6NY_3+c9)HNBitrZLPs?5@W&h5)0}A5m0{ldQDoDDFG}>XO~r z!8O5w(?KSu-Co}AKK5mUrn)wNw`byIqfb9~^@hcH2t-^eJC8wBs{yIyy3Vg2+}bGS zi;lJdv3iB3c*=j$=V!K;>(1cOVniR?x^DANqCj|aYTiH6A8a>g_V3yI&zF;?&AA8e z{zvV;0otc)OR4D6>H|h7^NmWevCTJpaIelbVt`O6aO@D%$t4z1>ujq^2e=5S_SD5&dg5%@zq+a*?}B+nMzkR zp?9b6K3I6;hna;iLnX%s8ye#*pQx>LnbLX_7rnecb6@BqJf|nL8)k**BC8c`w=pIe zna&HrBLN_&g*vuJsm<1r9I1|3}eQeQc*_CIPT)T3cO-6YXXFnuhWN0Fd0ijMJ-A>xmBB z;P6n_4%YS$ve{-Cvk?NplvJ%}>=KpahW7`-98@QA<9$h=zA4mLh&a!3F`9iuFD$av zJg%{d0=vHbE4%MJU;woS1CE=jxqa;IrhUSsY2KR;dJ+sxc**~16>uvu*t4x3DJ)!UuDON|wUhLtgCjKB4RW@Fr8gB_x6an} z?#>oMwkW}_|( zrD{=s?`LqrQUv%Xp6Zi2pF!Wgy1t&RZZm3W1P(T}W&?^F*wN$g361_Cv)ccu^pQZJ zTK@hkZ~Wq)e;8jYz4!CKng!)_HC?Xf=MPQLTB{;+&-RTPQ5;H@k|hPxX&BC3F8cJ& zi!2jCpvuvgCL7$!$)~?%Hst^UR23Bf09g=JRkro?FYmA1y}p#pUB=|(e|z_`{_d_$ z_^_xbb2G01y!`BM{jV>5;cK$ST3oB2x^ziZn8^AMnqyC@s+!@N6oL}F&4I6;#*zdj zWEB}RwO_Ef#qd^&v^)o-fln5HtT)i zrC%F-CkQ?M(a-;eRR&cBc;l6?-@9>@XGp!_PIm34$W(*V^{Byo(sSE;GOSX`qF>#3_i6p_W|h`COv~2^Gl_M&pGnC`ibM`1_1pD z1v`-{bRgO`NjAiHmL6QGi8Xd}ZLt*np)Dj1_NutET8;mt4W#aaBd?b*50J6jAx*kM6V@c~D_n z*{g+IMQqg8?#>r78H+FFZd;@bA_sPGTxjfYAI~~W9_{#vCt;*s$+*uxc|n#$v%l3h z`4mBmbv9Hh+aZYl_`Q!suEg$f%hT@ws?f;a*N_!lgOro&h?YiBt;ikVHj}%@Nm@Wb z3TO?3)iRCX^6p+ec7Lv%Qc{s6fWJNR2oFOIgp>>Wm)d&mJg>>8@`0iA$-RiNEkb(7 z2qG02>o2E0`-{yI`>40Q6kdJr$YWNAMUk1M;KOG03=JA z(KElRsM?XX$Ly3{6dK9$c?IBP$PIPn8;vGec(bSjO#X?LkG?&0`YEmV(Cn}OE-?NS z?K!k_>z`=%QA22QbM|MnxrgwcP+NO%d~dP5(;GY3zjyT&lHP08whuoADS-9jrGCo# zkj|p_AAi^%GNP8y0GWGMim~9diVoHb6_Sx7dzPed#QWh|}*bnmkVsG=W1O>CHNw z+hq$9(JiSKb|&*dv;IJ9Jg|7N}^^n{h4BGv3o|>H|mnbe;)< zVj$fUo{qs5gWh=mL3-c5J+qxWxJl{LOz~q!hZfhl>s6VuhnxXty;LBbAsO)NeO$Bd zcKMEgzSL4?6&oQV_wIshlxb+;f|BEE25+q`q%X#g8awt??K!0;gV87@M6r$gd`p3( zxm4=)QdTW3>!TlK&AkMP)qz+f53F)(Nu2$FQ;M2aT&8PAH?2yvWX3^*v3Klq8od!h z42=y0LjLbj!2e$Xt1j}XSWO31&2qIT=LP^kNPBi7yWGBOshW?q>T8t(7#9mLU#qYN z6-y;*HPo-+a%G;Y$bzxE4MuUd5x$#_QDSqaQDJ0}1=>}{Z7>~Cn@W3EPkVE`&((R{ z;qElLED!+zfKZpRb7fja(YP!md5l!)4n!9KHGtCLwHkC9SOcRF?1V%yBVc;8TG&bF zYEUhPAW)gf%2k<5>m){IWZuLji}h3%<9D0Yn}r04vl}hETFl&v#6HOHaXAg{Bx^UT za7hlbByp#7ua(-b&m4BFSPJ+2-RpGktj;gU0+xD*Z>;yprau-yaS;ycea%oW3)Qux5TB09$CeZ!|dk!`i!LFy{wAZ!{ zPZWU^LPE+utQ$O$Tj{d*e@YRZGh13fg1kbi>f^VTA}xUN9vL5mABWml^xq!oMaAqVfjonIb&-)3{q|sWml)}InIm%c?-5$ zdhz*DB-k^aj2lI3XY$r5#3E7bhPFD61)>5=SL&y%o?0@zzktr%j!6}%v0Nuc|E;B% zlVwR!u%Son`UwMGxS3x4;F=s4ONmT5Ge2x54K{Cw)_LO4p~m}CTV5RTI2E}$e){qKe16MZNBx2n&x)q{zBxd zR$X%K+I@%uc}H|^>bk0^&wc3+&Ry($;-%kz@poUaz!Oefe*cxf+PLy|xe}J6tF@C) zB-jRk%l6>8U@>Q;MN9Df+`WaTKL2=&b!*YN{oO8m*IqOk)QGbH0E|y~3+21v>pwiW zbL)xU`r7cZN1pxa|0ya8D@#?8tLEAe@9k}u9o9f4HLr*}w> zmTa(nPxN2>+zUd-vULA(ymP(QI-c13Sd}3VQIqi~E1;l|9vstxLIZ%&WZW5DPa!1H zsO&~IUIlS;DqT}WMOEpA*>y#dP%YM|>`GD#RHc6%maG^t9Ws088UTU_s#5_~V8qq6 zbalO^G;)d%N1zCbCo1JSj4Fz(#$yMHih=+ik404lkeWg~cA%=t{?zrO&*&U>N{7Ga z@BIvl(SWKr>=cB-mhx}rf_ZP*`1k*RP1h)4{ai6#jhj_aCCWf#RMSup|tAn=mPt0)dDiU5LKvBc-Hje3f$ zB%;S`otrJtd?@DbK;@My;-gT;*?}IPghGj5JEM1x5_mo7AnRQ$<>5L%R^u;y!u^) zvNRb*ZppCLzVKjE6c7H*Y;#!ZZyZ+kOo>G_b{K2q!ih|l2LP~`dB8D=@uBFDrZmBhgwh z3kvl@SPC!h2wZjg;}6B=+OuC85^C3B5b$I1-3KGjK~=SfqFiE*fVT5 zH6cBmDK^Gk&U?uunpd}D#Sl+xwdS?N30QtW zSu5=2(-y0UX0;KyH8-<#05QT!%c$Vp$2;y!DFMd>wj9{-i6k7FpbI6ZfG_NCJEfiVqC*(a}8qQX3654 z`S_>4ffKr$Q*FIx;xWkj5Y=`>zkgc+EM^WrFt+z_QcYv)jpx@K=ANzSFAZ`lpKrVU zvyX`a1a@)sf+`G-MhYv%#e&IslIE)v?XoZ2?7!swyC2@Ki-ukn+&(;uEpeCgP^c{* z-8MTib7bgLaq6{UgT+aZIk%nQ&#ffpJ!7YnOY2)}q{px8>0q>nmhb*_Ve;%t9BwRe z_asKwb@W)mn*8|gdZ6#D#ahTP6f~H}!S0z4zhP|~ci`suuYS-y{1o0&8=0SR=(y2m z8Mu3G$7@f0aDVdDu@RhUf+V7pwdn|?0d0emCwHgrS1dtGz;CJa2u>q}gb2rhNw>GP z)zhZ}SQj?CwlbY2v7XJuRG_LAJKHz&RWr-OK21Tai{7SxAFBZyXR+QWS@(&Y-jf*LfgjI8sv+1zb(F?6r0uc(57mm(fd)}zc_V%VX zUwuaZ@ER=4y#38?|KrM#J9)d{@9!&6`j#?jJX8s9u-*}S!J_}WtJizF54GQl-H%16 z-Vq|Kndbo7Ff`;uR^}5uP8(V-_9h9R-VhapyIV^|fi-pa%wGSng+6j3A57w570_*L3DqD}R)skg&Y;uH4)fsEDUvsRH+sX}$jpv17cEg7()l zMi^-3!iD#yN1k}D^Qcdi{Hi=K?m7v%yKlbtM(1F6`O2HSxm3K>2%LIp?(H4S+3M-J z7!(7T%OvZJN^!f*ai-b<^%*~rbpH~o*&Ifw!TE6gV74Vn=0S~IrMn+zp-hf>aQKnm zz$J|?Fa(bQk8nskHLgJSYEt&r@M=` z_KmOHc!xH1yZnz=qaOs?O-8?+0BZ>1MA5+DxIem)#1Iw6yGrp@p}`Gb=#0SDHWTm0?5VGJOh9Zw$v)89(V>!C|=6!WW1f{o$dPM_H?j!6r~Rn#2!;| z21dK~XS1G3Sc9KizWswh&kF{JF1dBb92#{5L)q;`y?Imt+mn&$zG0uey&PFdTH1z~ zvY}Djv;_ON=cX})3yqy{8n#KDfi@q9L7=4etYS|gu+-VbSbb1-uL+_9278Di@_ei5ALsQg$Uu^SD?$QA1Z$s=-6%pZO}WN{-pIne)Zm2+l4w}`=~8--iRqfgFG{lba#-`f75hc;clf4RFw4>QyU*QP#W zfHJjMQxd(FCLev^?{2G@UqK=$=I z(9>h>ob1?sPzIq61?*XyerM>Ei>-j!2UDckE4FYG)vy%SQLvcitFl^!#Ig6k`P;{y zDW}5|cRv0W0Qy{kj$i)m%Rb*Bza2fKi*nDR8Yiv6 zWRcTZy0fV|0)uKxU&*X$2o0q#%WR#bXbq*`Sx5;2M$u-Wz9tDx$ACv+tJQ4H*!c(y z)D~|p^qhDWGs-JhUh@yWtff2-^Spa_GP%jc;<}*=j|s(9cc^CR`+R1-)+ z69jm*$uY&Kjz;gi{c*4ZX%x1Mfq*PoGt-MjoiI51*>qtlVDT*8TVPVGcg%-k=Y%Z7 z;o}l~`=dKEJx5M!%~;@4QUDJbJT@zMsJNIhiUtJGH!wvj?_pJAv z5khrHGEv@$%?phs3yP`$0BBPr9W+3|^;~>KC>n;S`@3;Zomj6I6;(~P8p*=0tg51- zB%+npCaX2$WkhHr^)->F&3z@y**!kkCUnj%mE z`DBa+Wm7@u+pSgfD25_dt)XkNQqZRMyu2HrZ8{W{RK?cQrSxFtE;_tcfHYvT)lf@f zt5gkdFO^z#1cFc$PRajPgCM~+P;5k1?J299Mo_!TxSM%%H=SFqR0Qrv(TzAO0dTVc zSij;l;So2Q+~PBh_??CqChb1O7sguoeeAv=1H8x|p{$l#x zz>xF9wN-qJ2LOPiZJW2g=IwpLsSSasG@=``iu&5#QrY|Tr@1KR3Q!iQZTKhvwVFk9 zsP_-W>Xw8Atdsw-%w`VucbATSR;*!dUw90GI(E~#SR-%m01Z9V#!6NJ`ESllHz1Y9 zv{$2hHLm*V`(H==l%$}R6NTVB;*g8RN5?w`g0#7}+dQ(=lJWAEy_wx=aZ?XA;;0HT z4%mWP^xnjIXF}j)i7RJkBlTb{y%%`ck!APw^&0B~m73H=8yk{%E1v)%fJI~oF{)xs z0r*2kYpzx1DypsxpOXqsqtzXJ1a2l|FoP2=NrqHF2(am;zw=k>_eo-%^eXxnKC)bI&~==nO)8aj5~#@p^x> zR4xQOARzZh>bE_$@k-grdq5oAm1`+=Hh5W2kQywWBK>7zh^09`d~f+y9TzFs5MO^2 zMpYOrh4gbzZ!q`^N;ELqkDyzTup$r{M7u-0?%q-#P}q=_3PN$Vx*D2XB~F6DjQsGK?KH6 zKNR3vV3}!mUV5pN$x*(B0-ByAOS>|n%U-$g)ZmDX1j-CG$LhZPDkc8f#-pNJg%C-q_I>}=el5TyIV+))D zzWeuItg)<*JSNfa8@*Ka;OPCg-^iBw0=?{e-~MgqXs%wGOl^HVGSyw!oz zoiL0~-}p|eN`3jioUGg(oKYZ`!KlhBD6@aekH~)qM50h5M(!1Z-y1QK2_TIhxH^uZ63U9sj>Msso zYNPE)C3)EyI*%LLQA{+ue6(R=c;He+?6U@YAx$p^txw%BXid5Yce3&2A5ku^f!ZWP zx$Pu)j8xg^v!(E-ed!4K4X>)IHFOSm|N01H<9)a!VX4Bd| zJg&f#7B|>4bkgWEv#jsX`J=6d-{gg@{^OXInYjf!yaA~Oz5B|amx@#)8eV$uo1mPB zq$?iR1FoeqCBzasLTCk{m2)4RY#Rz_^iq?*h!DM)#^UbL?d=x#W=a~vp$}ibA~vS& zqi&j76pM9(@0`u&ucx-wR?LHk4~M5dpiE1>laIjCW!#KZN`d&j&1}g%ewQ1%a}_0N6sG8dq!)8B}4lsU7h1IS5}OniQtJZEG)ljb$=270HnSco_T|I z`K>rHUCM}xGPm}|Vb7v`>Oe-_=JCdjQf zzWaN@5rWXe>Fr^p`9L$WA4NzeJFJglL0sJ36Lt>6EM6I$rzdMUsE3QkF* zBO89GSg0HI~4?nO!k zmJZtNj%=-%<+)%iiDFn2f}7rtm0rnYa*zD=U)7SzdrqyZ^$x<-=sTKeL+NTZ9Zh5n{O(Oev;|7Y?(T?{N6-7c- z5JIJLfLFZwt|z*VeYW?=e;PjX&93o3^q#SWjy&TZd`d$){$E5ag6M#9u{vttP`Ro$ z6&tPv06>zeawDP>3ca*BFl4FhFhhE4QD8+y(ZH}*OG$j$r= zCtwhS39cflvcjP-VNe>G>T0D?pIYBbKG=C@ZU@ipPcPn}54s7RMu)&U z1cX&U0aX=9ZP&sqpJW@BASKu2JEd&V;ZzznW2Y{~HXpm#qXFT==iOBaNy?2xt)%^F zEBUKUWj%&Rvc8cJT}4PK3x#dk`)+{nSS6lU^CDk1leo{DiJ}{x9XrT8f`~{c|ahYp63eSlS@zBHi?vqT<$@=EQ zf(jOvtCgsJex8$6P!^n#dOqV8XBl3@HAD-&S`Nc@ArpJY<~s*hgpmQK)`9!96hZ?^ zP%kSS=gu@^$s7MTMIIlr8BC}QrrCyuIXCm|KQ|fL;HKfukN$VLo~t$rM6S&8^PRY2 z)Q{-IAHbFbQ8L%&-Zj#lq|Lx$L2223Nbhh?-#YVKXDlOHIPsd!*x71kd9jHwxg0Z9 z-pf~`%u>xPt+25Fi$w|bAV&k8&sE6o+5EP{b%<~|b>_C#d{-3isj)gndt#{Ob2KZ% z7e^f|;az_pHQ@1-c{b< zZenD7uC(?;j!D5xBna8sA9jfcbNI|UNBww{On14&g%vU_Q7Ry0IA+9XYspeWtTQ4z zPU{tkeXzW2;L}StKTyi;4Y`Y{$246vxe#5NXu+6qWa5t|HK%ejidli&ZEn!K2APKI z9KAnvuO_1XnkTEVRBZPyot^8WWz3H4@%7E+TxI{j2@>US6Dr0%7oRniQ9)P?J?R|V zkLugD#74x=?Wa~>i}ZuD`LGWt$UIxI(PTYE_V+FLZw_55cr75005Bvu-NmG|J1`>T$9rg^PuK1*C?uD3nh?h zDc@?=GzJ656cw%o0Q#%B*q~P9*jx6O0StSV!oJW#2ysw6`YCh}DX zk~X(;we5y1D4>#sffzCqozVQbR`IvdQ&`(8ybZ#QnQ_htB90 z?ph1!rJnP@S3CHr-h@^+29x1w6`@f$RmjCb7z1R!k}p9Jpi08l-1hE90n_n?ZX=IL$RPBpr}j^7?EV000DTBFF&%00;qq5OV)cRH###NG*Rb zgCf;pVo#^9!U!ug6I#lqLRhn2)KIj*sbZ_7g1Sm9!?D$km27p`? z&hVmBr=6?U2TS{DRchhddNsG&VyZAo=F$m;YazHcdk{;mq;y6D1f=(u|4C5|DuAgn z007YHLIOq<007v=7KGrkAlI_3g@q&t@Gw#pTM?W_As7Y#m9JA%_hYr428_0p<~F3p zP#sb(WB(~gyPKTgQtG8w? zWb+>kPmDhI#sBcx|L{jBf+cwt#Sp<~dH7QI>BGUl+@6az>$CAYq>L1H=l5rG+_wtX zfAsOfn>(<6o6_EHEH5M0i0s=0!FhlGpv!FlLBZeiBBn7(4c=@fQ7t013X`80Uc8rs zz*?;|*7eY`SXU9G>`W>ZlwLLSR6EIR+n$jl*?3wy!z1?-{laHpyU;0HJ_{P-sb=Q+0QBS5;Te zdFPzgUOC+dxM$qQIp@qx5EKr@sjspMIr~D z`3xjOy26Qkqw`>k?hv_Z4JAljWL75Dl1Wb2ai%;A)T|XDR9PpiCly(@51tbwKpVF9 zk7gt{T21lwB3n*2Gq0-No=;ow-iyXpA<-%$

{E;_bn?zcw_tf4o#`Q{^oPXoPGGX+K4yoWlMQnpFXErw#~+7)xGhZpLk zU^JVWsc=bvESj+&fmzYLK+d;dkx5z_E^Oqy25X90-ESB|17 z-JZ6+oyEGM1qM-0-N%SqqpEc`>apFLz&k?e+MW^cd_^SO^!CQBsBNeSrK-uQnv-2t zQ!O~FZNdDV72nwDx4-xQbew#it~RY~zDyCvO6!YxEMnk$i~MAdW2do#1s z6UR4gOc1Hvo#1n}=wnT}?fXO*=p0DR-QI6=BwM$BM|EDj8Z6ZY*W0?XzOfyjw6^twdo#6msEu-D zch&gjM`+)0E>W|^daMPW^-g=VPSs_RcUP=Uoj$Fg?)z*wliLwpsBO?+bM4enOUqG8 z_G3{aVxr*60Sb@j2+jq1a#5%k zL;Id-tEu)X6^q!YQ=e+Ib(vx(1jM~Qd0rBgrmmhES)|Rh$?s_HM~<9~Df-N%>s{?H!T12}wD979 zM6Nh}y)ab1cVTYe+>=f#uGTO42LC&kgKk`W5Z%{WkyqdYqnHaQ#j`Fh1fN}YzFn*Y z0?GMl8%}!n9dvGQ?69?-eM7tP1xr%^7_E(^83IO>X!~p5`TD`r%~fuHD!-~X+$O3H z9RB{zak;4%VGp#Ud!m)LiIJX@HnZd&Jlfz5hq2jl|L`9XW-K*-aq!SFNpiJ3o~f*d z;yZDF^B08DbhK4A`)HVNkcNoK5-8>vp~BGyYVo6Rf1B5PbZg~yxaHyC5l?Pm9zwjd>okcjb5$YO9Mx1P ze45;wgxLlk2z?gtmvKmpj08*&lu6Zsk+GePQa-iX)D)T>zt$*~qC){3TH0IPb9Nrb zRO$LVS7U=unF2B@UPp|_ES45ku6G{puBEi~gsBZ9xShpR zus!GxxsuD*MxJ@Jp7u;#zS@5L_l<@!flNTu({`I}eYt%2xlY7P%>4S@uCcG7M(6t7 z*V>1ULQo*~(5}k2Z7yXUo~L!W9*pJ<4peO@c2^6IJF|&`(!eRguySX-UaWYU3{8P7 zlioH)BQ|4OX>V0l+73P0M38Y5EqR+>gmuvB>@<0`#M)l8%U9d9JC7WgoxXnblYhGW z&g;G>K1P}iuYLRP`cJ;t7j7LK>rNJw@YvY-8*lGF9bLGS8YG-E>+=Ju{oUoe)vd+> z#dUWt6*%m`%F(8-J(wt?meze!cgsg?dd=oL;FW5O|ROJ(ExGnZu68)eq6w$IQN#!I7bQ#jBvlYRR&0Xp6LU+LIDhL;*5$c;NJZfqkV1iZGWUI+;!I1IcOkx zxTQr)TcOCRl!z?eXF5$8#WviaF?M&qqEJAZ$tDUYBt_eOK+8DnHiNaRk*QNAtFB_% z_@deBHX4C9#7P1f-x8dGE+$v0=T|+w{TjDh&!?@iM{%Nj>6dp$9(x|LBeTEy_vqkP z2}4`YzDX+9JMqh%3NsiRK7mW`8pxcp=Ov+7s}*#a8(E%tpo=+F<)$vbUP)Dq_5--R zZs-~iS8ncROI2*F!%)TCbSeQTQ#Q!cmCjW%Pa#d^Y6>?N8K}do8ZODXr|X(v2f3oy zd~)DQ9)Ac7PBuq+{At|_v9wnMqs8qw77a7zXo$-FisFOTv+ud*N;NdfE`5h+8Z^oR z{qQ@?+&PQX=?Vl9+@%!S2pdZ1-8f;9go-4T0RUr8|2A72wtJF%1A-BEYd7recG(al zC#gLIVm5kkGbUCfR#g~9vhb)_kkWIN2j$$IQd-q@000U>CKTUg>i_^ntYjyCZA6&t z-31LZsk$zSdn&QY7Alga#WOQ##a7s!1pp|5+DP)=Dx+2s>D3)Xs7FjK0Xb{X1*N)z zVkVA>TTYRS(lh{o>T&yfdrVeL(-Z)J$6z;zaPHa^LXav4j84+I-&WpX!Z!1Kt;q9Q z)a2;0cnE77gE?rFXgmBosA-^=ykE|8UIZf=osr(Qys;z+Gr62j*v-U2x6y4?aXiZ{ zb7f-?Z&HiEs9;%@SQEHf0o|ER*KLv}sD?z6-Ei9;sE|Q-r8Im93#{u_PeIw!!lYiU zY+3}}PdJ;0x{HqVV)he>kVZdY4l0Ka{~?rHuX@i`HI#5~@yj>nmOz~-(Kph(y4RSA z6OX;nKvMjt;I^s^6?CkGDbw6Y@+SVw5>W)&ZpT zS#?dziMex4ojW{7AQnj&on;Hb_NO4oe7jcYG}|G_F)%w9aYrohMt-|Kes!EBA^rZhjTM5pjbgh%rgmo_wc z%cC&qGdD5>r{|??pez8zW7{`hM%E#N9Vc;&%1%tca=qPb%b0yFp8hDR@Fq{s!iu=j zHfeWZ7WO*bgr#eS5Gueu2%iD9S|Ik^Z0d&9YYa3!>@dSn;wGFp)=Y+4t+sR>?h7Bu zRRlAn0;toCdugF$1fk7(=_Z?X=qI)62Lxtka?SaznE>G@T`CB>U$S-}5Px}VywB!y z;sjUUi(;_DwcCianpB(T!5n$$q=X=`Px;=A^^1XmRMMb^mFjv*XCw zXCLrov(rYkT32ZWpMIyGUV19L&z8ftETiq46sI2MRe9i3hnvh}hb>Vz;Ef1r7EV&S zEaZ1>T}MSCB;_Q2F999O$3<0Dv*y&ruFzosu>xGCkS>w;>(T#cq)1c^8*k1?eE318 zZT6KPq~u>uQOZ}_S;>3phyTu2lN$mKuXsOV$_Qz(J@@J0Qy)i76!z3}W^d%?`R~W) zKDu<{B3n*bKK5B?WC*7GU;JNRFQ~(qsp^AzD2+xls=f2B(QdAk_lU{8`r;=1jk$))4sEO zvHQ>|!T>d@+ZFx@VKU7xr0?FmrU*1;D$Gob>n#7^UU7Enw$)p{`O3E}os3HK5a7dT z?+}cKufMVR_~-x39t(c>lfOCl(w`gL2XDRhPo~hvBO}At-uQ;u(QR&iV)o+qKX_-Q zycE89;TMzRZ+W}puYc#qeMe!IKT_Fy8#4@GBxJN#nxajhoS8}8y?IR(t)wBbG<8R3`S}N> zJJ&DUz4ghrUbeI+WVNR$cF*71X&>pCULcRZ@a4(d*GG=_R!vs{007n@00CH)82)#@ zGy($+@(?_U@ikdTF#rJ_=v7&~mWX#CR^Ufl4}Zezf0p;3@{+X4XD|qBwOQ$G`K8>V*mgQH(O2A(pwvv zmYe_8>mWO-VSsWGoT|vGW@V?>@BI{lDgXdV+u2)e6KZ^{cYN(0_u;F5qszIO53h&? zk}CoEmA|#vaekM5xpD>W+sJOtUv$m|3sAH@Mr!4ZttR- zI>`Ie@td!?HFv9{m{ptU#AtXs1>>r>Nrz1p&B!;ngGN(|pc^%Xl%)EMdIn)Zb?0f9 zWoskI^>q56`^|c-VU5w$1u3^%b=|abS=Z#NuE6yI%4<~52~|;$=2^8Sqx5wXez|VH zCW?Hi@w$p6tA)9})mO~+&fmxc0QhXAYq3@Y05Ij%eC84?*C5=ZSH*@F)&xJS@M>+F z#bLPBWGhSJL5B|jpz6A&>kt4zgK4f-T&kCTvjNL<CrVGnF+}5vuZ9Bg1bAu*ux5mpTwHSx<6k0IzTG)?&D`Ys3VZ787X|GZVT{5*Sg= zFzH30>Hq+)P_HeluFhQ&Nv$dg`!V;DvbVYet(O|-@2%V}rOU~N$QB(qIhk1gALnoW z^MiYPEU{5u!xC`h?oJGVh&@K^{2PRPigVrrFzZi%B_Wt7co&F;a6ix0+6>36#~2QnFR?PEOP$rBq*O zxi@`l{a1n6ixyA2lBr?0rfcks`oVv#F61VEa!brK>GzZP>PM-LDB>(Ns6o`A@S08P zbCuZ=sjq1IRPVvI=&@sn=_4{)6u1zA$FOj}0CTFbOM>l+uJI;gS!US;s_PnLMZ3(_ zRi=WFAOPn#cVE6#F2Py${zto44Jlm`$D)&`0RR9X07*naROYT8r7+SUbgqBk=0pNQ zq#)e!3g|AIG#BE|cp5$aK>JAR+WP~?chfu@t}Z)Xc(IgNU}On4mSn;SW2T%8a+5pCg!gCRP(~x1KHNESPhg{?);qIH4H^Zq@E`;Pnbd;B8O+VYq>(B(gY8+ z#l#y@b_-Yd+D-+LA-bdln8g7krn?$~>(S{d;P4`l;nk^y?1m9q15>-{`OK~0=;!XN zzk{Pwy$3&?gN&7Ad|~b9$u~9|Yz;G-S8iVd0BDWWl}qQ#nyT3m*?-F2)M^wg>hRfV zLur)fVrQR$ntD5rS)jg$94+>>jxLL@?Z6S}S}KmK$?kp=W7yw>)|D8vP|3jgd)4gu z_0lUl%L~pdpI**6nhb`JL#XthQa5C%vgoXHd;!!OWZ0+_P`-gB=1gwVBo$@!kvy0AM^A?4GTsM2dpH|KufA))i()wg~Q=e?0YixBJ@NYl3Uc7rVi5fGZ{r@PbnMOL1 zjeNeh6UFiX07%nS zUftLzYO0134BtqqssMESw=_f75e!yUO=2V%#&liNg!IN{u`*TFxq_}{F=Q3Rvm!4- zum*IU;~D@Uh!N&E0RWhuFZ2Qk0%|EZ z{KVE~iL~pbM04lI1+n2oz)qm`MTC&dZm_bNJMj3vdshL^BqB%tO3wYl<~CLf2buCB zK+SSZeCy>Y0O1H6munXR02(JR+}fMI5!cmndi%X{>U{tUK-VDv3wg1aWk>^tQyH$l zhvG&6u-{?{O@|Rk5M)J=APCk~o+~8MOO@Tl5)LIArB#ZIt4di{vM@&LilitaWhF@( z(iI7Ut@&L|k)?&1OnPJbbN@6ZHD(Yf(Xsz8)4LVQO4?hE^V5@_j;PS^Cf07*_n$3q zq%5IErTCaG-seQ8r^CVKD~Apn%>HL5$M2kb>GPs!HP8zxdPWwC0H`_ucivmw+bu$< zp5AB?5)^8dCIy60*RAmK5;d*INksJE|Cn(SXgg~0A zOLYl?U|rWBJvTR(sZ3VoMgzzR6kbM*u*GhJVBv7&b9rktyxno~L^}uHXgP5zdhJ?z z`bWABu+l4q6j4vw?M4_vXH89pyQR$YzxOriIOTcb`LZOobafqkemCHb4cXj>#!Xl- zVYgF9oXs<@6_q!u^Y8EBa9x!Y#I%WsZE|>+sf_fGJ|lr%QT7fV`Xp?_1wF(FiqY9` zDxg}S;q)(TF5fTblW5Z+xwwm4mNZ_<%UP3gmdyx&lf@%`BT2M}+baB7nleEUJapjL z6Q6tbkPHpX`j>EnPz@&@w#2^*RQ_~ zcO2^Z^4I@L$_4fvA0n+~iloWs&cV8YKyS4Ud<6h7dHDfCcR(-=Re0QZTr=Ws_XA7Q z$DRH|Fjg8I^8#ptz&G82^?WL8@j6u1HU9o>>%N}+gHmv0rJ6s9X%_^o&E$qqT#N*` zK*#=t2c=_Yj=I_gP4-EY9+cIXrYSHEX|lxgJYh88l&+N+%Iso`T6%HQWDDSUZT-Q& zVYsf(S6s}B zU)*UI<9^a?=9sjutGcGBdcF7Y7j2#)1cD3*_FPlzZ-z8^Ef0$fqw2X*d2L54U%dK( zCTjoyS<~vWRFZf_*8u>uIYL{a2ZAF81g%KI|3Qp`s^|!nDR0PPO%|&F04B-jCabR4 zP*$f5Mt_qv7B*Ym2khps0XLzm;@WI+PZBEW>JAl2x`Hl+%q^ATKxUo2rhB`oHO*M- zcRPFSnx-kbhM*Jx0FykK0;A#6%`HIA6l69F=v8rPUa>-Sq>EMx) zBnjo>Y8{`Rn!5AjZ?P{=Q9%Puw??!FE@K;F*ku^Sgzia|Rhhu@coJ{~OTi-V&&i6n z^T`c)s9NqUPE>Od_)fFQ;p%RySLX3`lmWH;lvkGJ`8q^KkFPj1XA+Mb5>(Mw-GCv; zV|hY!d(Gr=RfXb5TA?WFJkv%0w;|gLpE8g@S6$elBmUmu+WG&mBb%{K+M+ZhDW|B_ z9q8)LN4tJMqH!y9JQKK<+9(-F>#x^hHmR5tdvCkSad*#bFnET_#}5vC5kU#vC~R~+ z9+YPU?DFFM;6UsUMO#?|%naHJ$%e~dm^#=q&((J6?GGgL)tx(cN@;3B&K!d-{(J?2 z)TY`jLFi~QYd=T-a$=cPrtCF<(YnsBUwfb3DeZo=C{?7piwObNYEU2E*peFw)%sxO&F`yiO5Gk>xiaCG zVsKZ)F<4F z*Q20VXQ@3?kKe`9yYht@PYDNRpJV)vB!akw^|H4kq=Plvl`;i%;0wDYugxD`wjnLW z&9X$(1wbppUadAPrmmH9za;Q9ZGfn#sYTrX>b1YsF;EGJS>acSsR#QX4M|MHY2Bwo zu-WTFgtp>{P@rRmZHQKcMQe$KWHocrGk2w=YKT<5Xm?O%YnV3cuIla`YPOOq<7#|O zroCuA*M9B8+v)9hHK?!ukU&{_#_`?wZZjd*zqk#6`B6e{OAaetPcI z%&qgE`12pE-}I&C-t9i~&mPxmar^2c&;IGi!4sve2QU8hpE7xWJv;mK=e}7?q|DLE zlfUyvh*+A4vz#I1@ebqzjNx@vqE_bm)`0bcoIdcc6VDjiLpg_ajL*ql8_pI z=1=YG_ZJXc{@B-k{NTbbfQ+5`-ESG`>y2{biO>8qWx)E!luCLm+#f1tM+c8sLa|Xp zw2nGnnz_m_wV+Tlx-9EBmBI;j`BjL`3DZ{!V)<>gvB+oMvN@V?OJ(?&($Nu86=Q=x zx3h_;ta|uk-ld!O2}}L?Klw&6c~g-c&d$G>yR#{l#op6rL}p$U3J*W=S0q8=1m_xg zq*4}C#pnv1;F&xT#M(N0jWnd_{n6H*?!M^G1XC^$1EZtG?bmv`X>ZdY(2|1Gfe@D5 zY=vi;YC#Tku9`erwGao^F^e~_cx#>T3?cUBQt}3FI^5nj>a_FSk94z@u6&WQM4yQ? zTP+qwb?)DtYyz;AtM_R9j5lD^iw#+*mN$^p^6gTlAoJT+^Lw{0-E~H+q)~kIIff~@ zeQnW&3w>NQ;p;w*DA#qlvj3^)1`n9$@9v&@=^s*aLmT&A@%I05sI{0{zt+6(i9-)R zw>LL?_N7m7OlyAU?%7X%ohkCRSpNAh{b{|p2;ois*mJ`pL9R;u=Rb_^KY5%hCD`20 z1`j@lqE&)&RQxgy2){J%&=M65ZMVR2}~**2J8-9qKO6Y0>p_r?cmLNQqlsQ#z!bmyN z`J!4Zn{7dwDcf5NxV@*&5**)KFOn9suGbWx?(K~Wa$^(0;7aC}(U*Y`$`i0)#=y|g z7=UfS(YkhVG?!rz2z)2$PCY8qeqT0 z1+{I278)&Fbtl$$T3{uT*c<-X=j?6PXh*4>*>UZEQW-rt%IARJE-8$gG(Y^}?@^X& z>Q}GYfdAs`yb&P=M;^&y!>NV<&mN&4n)i*`0aT4W^dv*C`CIm!3D^AcYgViRTJPC3 zWoPLPikLI@%Z*M`_$DG$8mhdw%?u`6wl&yRFJUB>Jp(mmM&-c3b+{O3_;;I?TuJ?r z3w1ga38zfEvv1T(OR`iiWo{YFEuJAq16AHmZDKG&zz6_<%ZsoGH@3HOnkK8Vrt6T+ zGvx3LGpf2$FIg}mCrSRE16KDwSKufIkR3?_0GREaW=EIB*=w?OSY7*Uo{``9Ef|H& z5rZX4Ym9N9f8Vex+-|lFSX^vIXru+yfF3l)MhBk?Hy!DB1$_{1l>!a8@o?neu-)UM z=<+Iq5f%gm#W_X=-lh2|ckrmW$t}Zrh4dKRCZ%MD5u&zSElPazK4+ONvbCLxB<`qn zI&7(eTF@44)VA%N$kF4y9<%Y_xmXYCFdA@C2&@)Oxc6Y1Z%pOas-&hbUot|<-ud9u#Q99e1dV4==(Mk<2 z?Z)eF7%r3O+K!9SWUW+5n#}6pi5E?FkEq18MiXQ1F`1ujxcei4|IOmIHT*b{?z!g@ zOj67EVhJX2wc4iij(OdZT)NXpPnpYcwcuO7^_q26w@|~2@4sd$bDO1G-TmiUP)qya zPbjb<05@R2pW`(YkbZsS5m#5b2#1Llzs;HA8Z9O(*s5v;(Uy^|Qn(y446{~AFUnA} zH}#Is=aML~&#O{j%6XB?k{%8;cs9M?=OYB-#F-Z*^ne|038da8*S_B$ z2^Cj&DJOm3izXVklqM6Qo_7>;ofczJ;i z{Frr!g^f1_&l?_c*lW}E2+yk z`6b9Or|>I1_9rE7bvAe`>J1 zzHWo2QOc|UDQjf&uihRZ7aE$IQEdH;TD2Wo$h#{uxx6GUc2Z31EPt; zS(w75hT>@k){DPJo5nnr&K?r6s&z}xDf-6TTk#QWSBGftR`y&!_9%{Npbs*P#4_Z5J1)7 z=x0#-1{JY(hMO_HMG-YKRRRF0aNEM26^-B4a%nEV1OV7~1m3CMC|IO+?^Zug)3GkU2DZ6%8NFE+3`EX1c@ z{}=Vr2a0A&{NS%i!v~-aH+7saCt)klF<(C(_;#p%IqvoT>f@> z$$#a&_i(U7Th?=Xmj)i`CM^c9*QCM&lr1!Ta-d_#2OC3A|G^hlmP44q-_-r*DmOiG zrBU04a@hj2@l##g?H$1>^YVksQ!3tN@f+WJ`41u3CWD^wH@=6FsTV6|UYq&V#P|ZUM$S!LY>5>RXeJmG47P5EANI9&XVa1^yf1umw7FfiM7l`# zXERwhN_91Lb=|mhW%i>|DIQ5|-qLb!nW7~{D#83zZ7!d>&xiCYA~(ChR(jxz{YeQxA>d;KbD&L4-NKp9X>X7 z<>&tXP*dMo61lr_tHaxJq*f^1zxwaxP4BgLuat9B2HRe8e(DdZoNaZh5b#_u8*dgf1x44E>ZPhAh72Yv zMhsZp>ymqG)AZfzYtm~w3%MVtrKG`OhNQ`*n-~3o4`FH5RR76zZp`Yqlw5r$Is2o? z=rLSF(fMm^PT0LQvy>{_{^>U_{rQhJ3gtWBTYK-n=2y1TtJmMyy*(in9<1F?bGwoH z_8q&Oy7222U4yKF?FSe38d;GrV%43?Y<81^t~Ahex2J1MQ~<q}jsk#Jy5J4Uodm{^cvK!7;O?>->NHTQJ(azEGka^CnY{ zZ?taT|4FU9j@s?7e*5nnE^YRMOkpRI+?f>%uLSnjbd}ZWn-Fyt#Sx$+?p#a_9Eh@s z8g0C8_ME`r4cv^^DtLW4wX;LS+CYBoXJ+>zLUak4k95fF37E>syUPnzZ@6V|;l`Uk z{0=Wzql0jMqz=!$yFpv5nxZ%L+#5fC3o+x#sTs{+vw0qNJ0q0E>L^KaQEqzU zY8ejhbFQenOW_whh@Ee1eVWbnsamS5^|b`*N!Q#NMyc(v^yUmk*-BF_?83I3n>2V~ zp;DI^B|TLl9(0iFDl>?rXG?(7_>%a;pT7-ZQyiG1QnQ8{B_5xzd@mQ<0nN4tQR+il+v?X|r|_Dyu_bP@ z@b-ew>%;WaW^F>?tP(z`N-P!}44DT6I&Q_?uu34BhGBc5BcGHhrv1rbu?S&6LiR1C zKyimwS~^YHXrBtl4`40=H>!dJD=xYwxAIycw@RFUi@CinzVV#~Wx3{9|7$%dQm zRx6CEk~V7h_GJqv$h#_C$3L80H<^gqyuXQCf3*7vj83AgS@pV87YmHXvzdDT*3O&L zKwaJ&(PCBvf?#poY#GpX%_lo*qK2FALNMeasP{8FCq1DXrPZU+BV(a(FHo9|LnC94 zhEv6L)YA3H(Wb%PD1NX>M`$l`$xO`Dep%4Zx8QnYgC86mzzc|CiDx?>`Y0lN_kU!qp3pLYDuf*bS_sS_YSS1|1K@>GdkFe8cjpj zFXt1G%!|_#w-Chb@KE5i? zZxNC3QYtu5HWcd{iFE`rFC=$3^&X_qb6$TzHr7%s5qq+>$F-6b%6XV2 zllu)Gz*g|pkK*w#h1MB_-d8veyd{J4v=MXgn#v~xYId@YB;i_myPzz;Ha&UySAF|K zG)*&^^AOg=6jXur%NlJUvGfk!8i<5)L>XSi?B|NON6u-M6SToi7DWEA#qUHYBZ{FA zqUyS?)nO%plNbO%QyVZs008zjD{O)j8Zr>#K+8gaVXKSbuFvd5R@dKpe}=27&vf@4 zc;eZw{Rz{#zq#=m*14a`@pCW#iQIr>J-=C4|H1a60#AHlxNnE4K{Cf){ZXS*s5Vl5 z!+*|??`d58!~gw-&7Z~jg0ub5kif=hM={p_m2Lw|~0z}XOq{s?@5CDLz$Uujb zhW6usyTh{5(!GU_{>g!Tw1Ilp6MRV2f?`E7(j@JcDyiLP{_4oqs-jElocy%6bw%Y^ zUDZtXu1YEq957%0aQno^z{b+i_{JsN{pHl$o3srUg+M8DPX{KT>9QmP2*XHd-$5UM zG?}Fr=Z%Z^(zr=1q;4kG-vGG#H}^w|WKJY&C=L@Qm}3$sW)!Qo-(D5zbqIzK1cm?) z!3Y45P!iMedSSbcL77@1L6SunF3VyS#b}`EiY&tj1_4c1RR~~GT9~-KTdN6)rSUVL zsR?YsKwfR>|NZM1H-HZNB4)09A2(nsaPRGK`=y_Eo{S}2%6d9F;IdeQ~>O#7UAC_Ss_muFaUt2FbGNl0Jhi5%pNN=B*5=M zS{jB~S*XB>005$@G5`<^LyDpR9q2mz+J8(Ii;bB(2?G53%#$WeJ#V)7e9h+?>6*=M zqy6Oe+{BCjd?LMt<<~xf?O(>BX`I*-YC#l3wwH^oN3HiRr2qizv`BXkYN#SF@4>oT zSNLsLb=YYI0BEwRh_c0<*O^n2iepq8T2B8)rV@94eD0@LzWe)kXW~ElS?$%=XYOJD z^|QT|4>CK^$bk=Pl{YJFfHHa_2Mz@XbM>qRBchlIHta%de(l{0rlzHP$%Vyt&R246 zsPx|UY7YS5-i_Dz%NLGYEWf&P0{|eDBmjUR)BpekTAq6DWbbb$#2sZhdwx4%x9ceX z<8ra3#d%29tT)f!xc=&9=iwuYplW6@aD=dUnc10?3)eXBMtt*UE4RL--*-%1o9{mP zsJW-^i#_?>pZtwfb4=g*1}K?CKFqBz!p;|ahPxHjIQG(4fJH+|=<{Fs8$pJex(9jc zpsv&S>IXf?zhZSn5x4U3mj>(>tbJf~`tIiO4lrb1XVHf}aAX08X z1c@k;DnQI`Qqj?#?ZtOx#5x%L6B(h7cRrC$be?=FuP(8G%YVb>Hq)_%qsK5!t4xp4 zOSg4d!%bH#9gpF~B@{fYIc&w9c_q)%o1VeYr%2P_AB!h;UefQ}^`~Rd;M=6F-Pyw#eVvQdcD|A9yhof zeJw|jsAOJ~3K~&FY_jDZdnw&->Y1IQ3xrSznD=i9L ztC5M);)t__Rw}y`hd5Bo05=7RoqUDbXe9XtMf=;Dalc4oF-KydVf2~nnLWya_rnfm z1lhY+AXuf_WbF*v@9)|*qihrH1yO`CEg-5!YY$&bSF1cZY?SMuwnEY7aA|J=$9zYu z7OS%>E$g(wE;t>|k|k@Z=(S)aJ1O(xQAaS+hCAwLOt-9*;;cg)zf<)F37+F%yIM?J zy?t=Lp{6E{xY>5L5--tYibX^FGpUb6MidvCjj< z2U(%<%~Y{7W9#V(3c*wtj}wn$lUoIYmDHXJ|m^v?w(&>wx=!@hB^aL>O)o`xJJ$2GyNz`}X!qXHNi7r|*ux z+Io1Tp#?OSV<}cyU21v3l%L`Yy?1UF zalGk3=j@dWQQC^ZZgIe^Sj+MCBgV~4UGm87Uc~YW2?Y`}A0ZtvNot@x$(r4^aH;Nxp|F~)Hm^6>*wMOHY*Af0 zTTZpPKT(kwrcgFp+O{(HG|uF)gtXdg0x3D$)rE!op)|sV9$hMe-Q3M!N3Un<=8rb+ zTSMJ#zC9{3yYT*2aQ_*RGUc+lgF|R%d?iCWn~@%2Y5Z3s2RaP)(b27f_xUfukpK3j=}_x{Dy#6F z^<2G~cCuHl|Jv&8$Du^1QrqL|o)K-a9ACQ7hzuCW#z0j^Gt|8IW@f{tx~%rjWX3}p zm}tve-}#?y{re@t*$#JB&Bba0KKW8_VRg&hob!jLj@dU*RjYqDXPwH6@GDzY`cau-!e(xfT%B}I?{Y;?qg z_*}W`coU9y!OR_l^_07FcACdOPljXqZk-CusSh;llD;TIaIyjvKd^R z5r>&77lF$=>JB!|jNfevhb@k#Te*E9INIa%^t}7SmsG=cdiL$!$sR=my$WFHr=NRvSosZP}=i1fGWUaZ3!H9ywcR=RsN(Kd31E4wEyyxcPUN!rWb{Ke~S2hVuI1LfVH+WQ|%J#gK> zF&-WKM5JSZ&EBG1k2i%zw^!DE(GJ39+`Ka`Da{;br^yArQ8rU~Z%0gKO8Elm@*hxz zg4t5Bg*>zgv6@`PqO-NXvy_w?rA?F^5Nmt)uP==~)5#YyR_7e$`68QNO>DsWnwX8)54-1AJaNu> z-)FFmpbgoB6+t@T4LWfsFL9O83&)EGlG&!Gx4IPJKm}dp!&zMeC>l`MO%MbOMwMY| zcGI!RjmHlnJ63zI0Bt7Mw|#W?_SOxHuT65DD#vo}kaP9ZpL7l|YRR^G`=1%-S=}26sR?6GvbufZ>C3*;uNEJFJiu6Xy&j)rTRFU2 zl(;tu=cuaYOD2yPFEk=b{RhWG?9pO9UH0Lf*!5j4^3XCJDsKcXG5oci-guT z=a+3(GeVrKh;(G-cI!DOve(!C?9osMM{38e-uTgQcW-W`X~;L{;tOME&uYf9QS_^p z>g`{Bzi)i_-p{`k3VqIIE5b%fg0Cr}u_X1wLK0T6mZGg}s}cm`96~9zBuMRoAtZ^A zvv*bQwpK4fcAMJ2*f6;fafm z6@}_xocks{oDUil?{?dRt}4+aM|b4g{si32SBtHZgRpv&cyxe1SZk)Bm;Z0j?XH|qcZ{13Y|g`g>}iReN~X*eOJiB^0j z<7_G&FlPwd&o?t7mj^9gkfM==PSe zELT?`7;-njDUuF1NyaS6t{O`cT>&EyjW-qaSVeSwdPK<4*O8TL}+kXhyh*+ z1puIru^HMMtu`kc-G?5|)e8}c6`3~L*hS|=F11&4cN`fE^u>u*000a=Kca@xI<3f! z}mCLFp_j%`7IgHP9OF-sD9(FWST`UD&L8)WABdJK@S)ZFwdR zH_9qsZSpKDI8cdKK_uicxwwT&>Ve4=ch)0bcC7_o2IV_O^c@OIxizND)g2jIs={}- zc`7{HMfr&VqG!wvgHYjaxnDcd9vfu9!;#$^jMx|*9~yVLm{?4zMh&SEG%10jFDSls z4M`SEfn0S~9vEn#fhGVv5((Obw^)4fT;`-dT&-+{9^Gki>2Bm08@#_Sd|+^Ob4VI; z)adqtUD9ooUtC%S{b>Dh<)s$~inCSCl)Loh|E1d-;p0)u$Wnd&It-xT{VBvKKq%-o zoLJu>^mAqa09YxJjV{s%se%Y4)H?vvNF_$V&6iL2t#>v`re@ck;%oqdC^(68N>Lwg z@rLu~xqhUYWnT+*f%&5M>{GC~_eGC2vM&SahlCZ=SMTW6yr>>n{lhH;LD-PON;S4r zxaeqsa<|ThxRb4jF3C1Zw3xVfK+go`T14NVuU`<3>Ix>GJ9)Gm9nGXj&^;?2U9PU$n+aNB+ zKTHl?KurW`3PB*J6KDM)v{VeVj`Ui66PmP!ST35R8O-~8l>Ug_+&=MJPZ23&?(u`l z^RMmfF686ju`>e%xj+BQA1t>9F*i#u-vt05bNFd<`u^QQ(igsLrWy-(>Mgx58=c^? z04%Nl)NU-LpyS~3&fdnf^2Ae*JqD0AcOCnkN_-=Ge}*5da62()F!1(Y{n*+u#R*3r zz5UG!H)!@a)<6B*)vI?ayDfJ<{;#>%H5@;9=lee#Jma@`O&c?B`g+frJlz@>xA+H* z!A|cGQEOT({xP%rNl-7{y8>YZy}y(5c&`W<_~P@RP<5}~do*(Cs|LIJ_TT+ZxpCCw z8@~5%e~e)%@9sHzzGdzHcP1~MqMfA1FD}e? zBXpl6)@JX&se{(Dmpf4~D;8mA%Q+aK7*9U7Q3@Y*Nk~^Qv3cT&r!ZqrC9^+p{58bX zwl=dqeEy^kc}m;&+lDUb8gl*3_idg50MzH-{nq^bqL39AAN*r3{t%Ei%Gs#d0aGR} z)KAvy7>L+l?{G^PHU~|#W3tM+jP}9dv!~wq*P9!2K%;TAlKdqi&A3MKQb7TlnSA>A z*{5wnY5V?1w~n0nQZ=?fC?5<=9>=L2!kE{<&e~Qj5&?$Ctfl?;2x>`(kAUJ`qk{?r z4F(&(dygiKZG^$UGV{Gg4G2%Q2+afpR9InHRRxOH0j=zxv~yLO31N=*W5EtMm-blO zPno?Zim?ZT{m8Lrj^2CoI_2qX@~101{}_$BTDq*U>8q^C%k*e#s<*32a-!cjVpxqJZgXjzP7W~GCvaU8VDVot9sCAdc zb?u;9q)X!N!PS~mizU?M*}d%ClB|w9*XL2Z9fnGmzurOG!R^)5XM4j=`gx`|=+sjhVg^gRw2{1;Cr2!ju=!8L9pGc0C4YJp)=PI%$VTV z-&(kt&)3_U>z#~68mSu(!h5-mlV|>9JMwd(sRl#qa?-pRx}1pRx=;P4s86-5f0`cK zwRWFW4&V3Vh~Paln_96leye9g>yHnMc2yePEyvGvK5c3Dmeb3f=RRk3R_F3Jvm-V{s?SK4hsT34tV0CAM z83E~hp(f3UW|@<;t)2PS^E8;)BB{qjTZ=($$Qx3BkDo2U;7ZL{pF*S4Mg=-IHYqcx zoVGH?%a~2)@rIM|HhdWVqW_Bx5(AT~f zAq~C)a(wN*cO`>0qsUD2S~2->IXscjOqO=3QFU+qa!G+H`{^T}{PU_4@(G4vai^~G zq)Ip)9VmoBWNr~-yKI>~*>FOaft-*(Y=~g}Sp7iL1e%R=LuSXj$vrzp{?C{6$o&Ua z_p#OYe*pl%!LRBU6ANSOpM3 z2i!-k*_A5p#Y#YRIlBG+!s1*Ed)UNkhtWN@vUO0XF4gDAQfPcoa;Vn1640b|dY^IY zt=Wj|=Zr(hn2v$}R+xTq8Z;p=}Zt*=}%qJntqO zkg{7S)~ad&gjf9K8l5q4VoAkGL)cm{DwdGEt>l~VsMJjF#hux&wd=Ws*auyNQ0DB4 z@K#4~Q!{rUy`(|z%COQGbT{{49Vu7jT24>S>};eFyUfp-ImzYqvF+yJ(~5kn20}=?DqD}X zBvP9&05udj&aoTSqOoX5k7~WU^oWe^duvo%$$Q+Il5W#p&uR&Z69S>jEiHw2(tD}k zep9|r(5?j2=?Hcv+D$6k*lls9$^Gz7(#|~gak~f8ADMfUBZFNHXU}1}DqBH|jdJ4m z>b%e!9<9`3*eU0drgA#acw(el-Y4r$yhFzvri{)D_Ch^PCaH$%4g#0VCp>UdW=5X3`^KPP0e$mq(Nq_5bh+z-cOV{{zhe&^$#1NIY9)QJ zrpZOr($s(w409j=1DXzKP$Bbl>%cT@Jl%A{^!%B0=x#T20-#Lf(vroey21$DBuppm zt)`=>a|h@Syz!5VQ5fE` zd&VFb0}X)5MA>~zsoH$?&(9jyJ$6DCdJL*?`xO`{>*tg4z0=&EW~H5JfxP1F`1#5ZTtAjFl@)3NQJ0T}r2 z2SKT(q|!AA1~fkN*7vSz01CtT)c$+ArT~ggJIIaotRl)dVQ*CTm3lQ9uN5OKs%Pt^ zBu*A!x}+)%7@;))1OZJ4P*B$Z9Doe4kmNL77X-OkT)ObbeUXDWhVHd=zh0}RU@O|) zqD>;eFwG-s;$B@BXeS+hE+d_>eW4JT~6x)<9kHxnFRmvue{Xj#M}s9Fg^1RX#? zUDtIO0svjtHB6Hl((-&t*R}M*o_V6sG2#ToZQ5WqTDuio@&_FD5ED(MKK~aN3Mp@u zy-j$27nB!KXSS9*h9F9_rnDbp7H{RwP10rd*H<3DedloiF&p=n2op*8&!4kToHUkR zYdtkSv-qa7a|!~QYT%YV7~Gt>hSCkT^jszPP}6ZpHv<5ms+y|U0001VO;@$0M~U6} zOb|bEEf;S!c_m$^;SDErb%~Y!+wS5=j~-rW+f}tX003t$hTmJ*xpM#3@TovCzF9SH zk`%%2ZTf*R-HnBWrxKU~L29);-2^`kYSlw^(nhJD; z$v_U67Or%^@{KAnpu6A~zxE$MNrSM4uIMlY%bMmPXrl=SF^NFCP|ApzP)*lrh{Ur* zL*|%#9u~^b5uP%5aGOmBAy_aKBbuZuXqnW5yP{Ay+*ZglQpYl0)9ye((PnzBvNjz& zF(8WZk34^gop-!mEfOl3JTSXX> zyPoq2n4qS->a+iWH)mqJ`n9cx)Xxser-?dP8xc~nk^6k*fp#XX^!pDkr9TGMPF&~+7OaC6vT?h}lTHk`DX3P5MrfnnOcPd?o;y@iWZzk5f~JUjA?{# zB>9ZE7%k(vX}+8@i4~Yna`Gs;8(Jjs)6f@Py79$K5GtC}{ zYohmzUrL@1s?Ya#w6zz~_mXUa)59p95G_pr)NrHErn!lXJ%3A1cN1C!&I?>JmB=Zp zd0trypCYm|HA~omJFrr^p_@roV7Hrmb&r)Bs)p)8vuWi~QWaDPVt5_d&n(_7=H5;1 zeVUElduOklXk-K=VPk8)TS|V9%44`wKvpmyD!L;9T5Fnj6WKb%4pKWyYo$<@0Y0LPkjG~=syhU2TEtNjI7i6=bRZe7t?nJU;N zRslgc=rVx}40{j;tvvqplWLA-bwn{?@?&FjGiUZrNsV^6|I0F@adJ!gW&u7ySNqRb z?1QDxB0{K_BKtJ}a+-`mn{)Qg2fC;o%5{UWONsYS5#~e8wE5X%q}1VJvt7*b5Z11b zlY{!u+(c`m5>d-;fgO($p@!({zw}3+6!R!}nhdo>tt9F-wj6sA?9@v1O@=xG-g#7l z3$j$iNZCDPw94Vkj`FMR*;+Q8PHY-aoo;*5w!73oA>4)&vHGsA^B$Puiz29juM8bm zt4u1s(`!Kr`8(WV)QS-ZFPKImTlF&7oG$+OO@2$qj0gY#5Dsd_b>G;xhSg+Q*m4X# zr7W$&1S+$fJO|(ntXZ>Kha!nX97t`^R)Uz%}K_%|HFo4WrV*BCk@; zWd_A_B9(Tsgg)xF*k-ReYO^nZE=XQ`V9u_u*Ua@&I`8~#ES85ed12#uf4hCyusr$F zTO$*F+NFCVBeTT{Xu!7ldjTxuT;BL!9VT9kUzNfosT6Id>%rqY0-H6!9NBvc&{GCA zBJRy?8-FBTv(>SU9#BOlC|%e-^0lW?1-rBT6OMOw^nHPTlANYA9oqSxl|GdoR z+me;aVfxYgiAK#=yLH3so;TXlW^q5@oZwZ9t=-srs<(kxT&GVgPP0UA?drVlAT`0w$`t@(dmK#(tdFJ*1#6X8!U48D2Z(HnP)s;Q_>hDQKoh!yqP5w!} zR27TyCk9`G%{iJ8UcUS_6HP!3*UtTp-ZLE{$J9&nQ^$_5a@;s+VWS?lxasR7cIIM) zV<~v9KXU&n0D*%qp4<9x76JfQ&jrM}BR7bn7hYrBr0W>N-S5Frs?mIU_=uHoQm{#Z zy)X081{a5gn9YtNrdVln`Ed1zyec-O#9h7iE@iDky9KMSo7bE}Px(s}1O=P>hi&EP zx~c=#;L7~9J;JI@ym(^u?g!Rzu-O<;_jX9j#NfDHkTj4SKJ)DVmTIOwlR+5mKa9;; z@RN$Z7@fkQ2A(l5jywAaoAc*tv)#R+@IN;=ALIY3;ks3HXMm{k6rqFYlog{ z+&J@vKNmM##p2!kgUfub*jj?*gUtNxgGw+|lOH$c}nY4!`sE;@1a91;^B@4R&^kz(V*#`L#&k?cA7 z+b+trb1==Pz}o--AOJ~3K~(#};t#bfoR#K;?uE}*zAd}AvZ3^??JEK=xK$6*(GIhR zr=Nc=B1tMMo;mepUSFnm;($1H@2}Qj-Sl{t+1%ZJ>d6;~j-zaPFjdtQ0*&U@-~qCd zUvxtU`z&{~?=&q_BMYmd^W*KXnR%MR?&_gI?is*AG)Aj?%)OfY4)r=nX z5Pn>dV>KwZQ`~K`H@o%EFxL|l>F<2uWdqT2D*K6znvJe4w!6!6dcgo=B}hg&pi$P> z2705GBWO0{UgaNz%Qph&!=BefpigxwUl@I)u=BBneZ6oNc8LMTh|r4o+O zj9S+<#h}*gB-7#^!AxX5#+5c%k!1jLK#adFx|m-si7Q-FkY!CPE|tZs)njxvs{7@2 z9)R@XYArdv?HwFG*k4ry&4=2VB7(zkwUXo)^96c5w9xD18hrV|<$gML}} z)EcH@e&NoJ<-iq0ln8Vcux5ntcBri{*@Bx9c?a>=y1NO#2|?b{maHA?muf z65ZRV+N_zXxBlwyj@DggaYORb6W>5#G&A=zH<4TYEJrdSxi&}|{Cp#sEw(w#6zx*d zv8`vipS@W~>{TYo zZV!~-D%5j$+pfm1+0ahhP~+MBB)bIFJ{&NqQy0IFWy)$C7f^J#S}(ncQ? z6~zNcJVqHwv*(0s$gP4yCw^Z_P!;@m`_Ky#At^oT$hix(7mrvus7BWKoDaWFXm`{B0Ljc>j<2IA=(o?IT8d2-01DfKCZebD}S>__0gQVyk0LUx+daL1bwvi_VrMMlFBDL zo(?zSnhHOuYdl-t1^{C(T1+0-HNZy=t&|TVpbfdd_M=$outqwnH#2;MgH!74VjL)I zBc}uW?OVnIit%kBu(jQB7OYDlwV&zkw;*PE*CA;=oY}{2+sLI_qsKb?R-DU;9h2_m z#19c44gkR3T@#9L@>y{(@EVGPfCvx-2_q;FuI+w1C|&4+4obZjzQkuSG`(KCe-w76 zDw&TSHKcx%173c6yz99eGk?3ew0W%kJT(7)Exr-Io-1$F5gxer(;Y!p8XiIZ>1?$^ zila+_nCd^9K@*2}-`yJP|6NZz`m2Bb6Z_=z7VZ2;|MG`WSU589T=Dwf44S=Lrf23> zZV2%61|*T4df2~KfT_;+{^h&Ft>+{pc;jb(;GTLFqoswJpUd4%(P=XO>_O#7MskAl z?-z*4xYegz`@!FJj~fJMcjRaP-9w$GY~HPfe>)exMCLndsRzLJS;BfEmzp-%oQ$J4 z?uq&R-6G#s>0S0-9Ij)CFtxXOd&gjl*hZ6WieTDvcDDzzRVSJbx!cYJj5Ub2f(s+$ z#UnCr6dz#8%4SwBD~CcRd!P+ocQ69u%u=!Vc0Byb@F)ru*K;5AO?*|UL5+=fv5?p4 zkd1|ijWQ;bHU%{$*8nuIi-JwFR09RMQdUifPu19DF+myK8dKib|AZR0Sen&xc?R>T zb-}W;Gt>2)TaRrJ#zn~MGJ>_{e6y>=At;2aTyberCOKDp;2&xmucJmQlOW(J%AO!P z2Q3CGYlh$_8Z6~2_2eS8b)1a@^xWX-h8QKS0!}OAI15r~pP{4I4BO0`ZW(K98r}5` z7qeOu+w19HE;kC4)E5P`_4cV`V`DFRHR1_;xqDcje&=6^{)r&?(w&e09QG7WjD59s z^RK&2_H5w!g{8Z=?Q;g9oE-UNa9@C_w%NCS*cm*n;r>UT{H3AyVsWJk>Z^wbH`vBJ z;xB884l2n+^b(oBZ$Dyc+^a(ZI~w|?$xuSh_T z@x(*D*mua)iM>7A9e-rl>eItk7Q=~M6w!ZqMe)fQ{9#~IC z@s`hFQoCYr+cmWhhhKtle(Lpa0y-(-($5}!JHJ!TWj^KW913Z_{P;JW0w@=%T)Nsn z_C-E^2qMd7tkY1cSS0~z@#J&H{6?o6)GPAicD|T@ZY}b+K-W8JqEgpnM9ud}hgK9flZ6h# zY6bW1Yq+o7@;kazU)lGlrlT-;Nosb8I%y_@N|jLdhQY6$7^6njxqKTw#sav_VRGb&)SgknEC)d5yJ#5J*T+y&+v1>8K={ zdTEtv?6#Q0{h<>ff*wX}qNZ*uO3{yckJ}%YvWu0xWCSjs>Alo8nU?ppN>Jhi1fgJy zEL9M$eptyb(118>^J@khOiH|%f*HF4c2zg(QUh0VEwJJ-ROpUQ4+7J$BMPeC3&9W* z1Bf}Tg=}pm5PP?KKZ|;3%hqSQ+~mr!138XUIxK5e#FzwX7No2f7c|<|XB0;U6s_P%5TLB z2E@>x@{gS0E7^Qz%}9Amp^r^GaEIDnEx&in<|!*p1n=zkon-mJ;k9109oyQw_Uy~n zSzZ$@DPs%OqLUpXUqtZMcyEVMQrYS{23$NqT!+~eujh?uT&Xn#3Oii8b4TVLP^8s= z{0&Lv+Rl3>Xiak_FMs27$MG*nN_2GzEH2j;?>&~qbu{Pz5eU((9GirMd_YQUtadcw zhHA9I02}Y!*wj%VD^wT7j+vui)5(50+F`WmHUHt28x@P3ubR<~H7*zPn9CcV zZjvBv&rT$ZZ`Nv|vRh5XZhFz_xR4?&9w8Lo0O{sIAG;|(&Tg@onPhRfMW@A9_gqrL zo_2K)8VrHHb3Q|%0~IJ}+HkUE*d%t*CRYqYg;IUY*?k6{qy*p^{i{1FKE>+29dQ`F@yRur` zW{w?e89!keq0k7{`bq%fK|D|aX9`0jxXn;+AAa`u=+o|irP|Lwd9qWnJ}TcjYHx4T z4BW)2&*@GS7AzXwC#C|?Y^|5I@Lk^7{5C(_0IVu6_uYw8|0(Xz{astyoNRn--Fx-^|I^gX%L|i#I)27FqseEi!4T5De4h}{ie4pi%1JnNSL1r z(vn2u?2<`;2@oqr2yCd5pVBreYPDF#QqMs5ejqIuc)3Na#{iH5U=1cg5QG3-Q%e#= z!n`KW6w^te2}8wv@f{tF;Ua`PFp*OVtc|B}6p+E@BF0rPkpwloME!LnAN*pws zW^xJey_%QjdyOY!2f5JIyApa%Y%FUK3aC0v!yu$DeEB4?v27u+s29Z%|SD zCA&FnfMAzcl~qB76sHF0C<5pD1K><{ooCxSD005dMC=v?*z;ZQr#B9%&_fLN@)R<=p><+~}7rNLARWxN+ zhXF{c=%HgrVu=cLL@mq(UTP>@0Kv-AZN>MNoz~V2*&LxoSP`jji4@ zb{h`1iw|$?>S#kKmMMO*#tq;6kN;fK;sJMS3zHYB_m1_v%myB~_2&dODyx(`^mJ3H zsDus?HeD;*ycj|N00`Ae-h(0s8W4&uZr=YkPJ)ctMZyS)Qc}ewVhD;sVQWz?~>U@jk?^m)NOOS0nwAd%yk`S46T%oU~=zc z-tmV=zy5zPz|$=+acz6)V6+FqxN7{BgMVOf*FzR!cIg+N_XFMiU#;tC}ffYPBaDhFrW3-mbYT4XLOKTX$B{J&hH_kaU(Fb)FvUH0EYZ z*CW~ksDjv+{v~S*)n33DOY!6vpUXSrL!F`J)PqK@203>T%t$do00473F=}8+S{vhVYa&b1(XqdwW7(=`sgCSGi&S#2ZQ&)8uFjH1rVWq%V zOAaL*5%+=+Wgzi#wuzfi!sduzyDq|UcX{4R(m}V)>>EI>k~^&wCI0M-ooq=+8puYf z8QES8+B=7O!*0U0u(+&nIX`9S8}}$~PtoGjMKmKdB$Ur<$oAnD(`~^JM>kDW%CKyJ z#Jx2rQz@q6w2EXA_oRW?HzK(;7Bgt+)jbRww)8Z(T^6Kl5EWlINIlzjylRx%XrI;A z$mN-AVZ$`ovbnnAADEC!5rX!6EJ;~XYcbAkXZAPqQ_qaEyV%^?qc*^JD--uwsal~# z3g%ijOD*#C0V`DQcGy#}!BVc&?G!qnX2WB{HV#nk$2z*(GW$D2xJzweOWSNw6GCdA z0W2;HD3@5)O=xm`&OFv_-%oJzQ5@}1Ok3@85n8QtRga^yvKKFnjI`wo-c)VDJ-A~9 zI%*p$aL62ZoZT|}C*+V|oFdEl>+fGBZ2dm_XO!+BXFie#p0c5w1KgFAag%dPHHTd; zL#Zj6oL;7pP1OB;;Y9Ayo%n$uc>9eu19&i-70q_V2R^;9{^r^;uS3`^4vzbo5AOH9HGi}-N+OemEQI>=mLU~LALaERWtvh`ux6aHD61K>Pd5?1sfD^5__h7MzqP*^nT*20H@joMh^qVti0PZ;|NG z>c;$l*-m)nl~?CLLu%#M8Dg~Z&OE$6?H-C1{>zu?*u7uS}36Gz_qr~f>7<|2V(KlyKO zjJd}7E>!)=HFW?}tH&iM>|`w%PF(xsZ@Q*lRiNDMt8WGAXUJgt^n<9s?>ExfM~rn0 zv(7bGfbtH@#s&9^s!n=@Vl12SLQYj{WHQS;!E+c3iD_`zXY6dg1rqkNW|N81|&dtdw}hn!w9Y;@N>AkK;V+Y#tkUE=ZRRN1sN$o#Rs)sGT|e^6PHV zeeBD0p#N(fAy@kpRwqy|ZPal*73~eDdrCrIG-HY&i5f9@LyU#fA-oShnbI z_3>k+N<~pudWJ7L)jVdGoLDED_O(FnMGI2;WY^sBtO38mKHysVY(ZC7&4B1)D4Nvs zg*9dzv)K;r&dd%^+P%F4+Yf$X3O;Wca2Ph1n~2X!N?L&&cj9%)zq66Uq&FB@i07um zJz)bmwz_fGdTz8ygeq&d?d_CQ6;{e|OrazvUpTxuV04vQ+00ha+x5B`*_E>i5^Qg@ zc~DH(4aQcFa$`QyF^1c`CvpqFFn1o&kZ^Hh-)?tzwwre&JN}`5kN`E)}D zLy^Nw5#ID4BMZsLjG=4%zPCNj@hMqvTyt>$djwn7EYlzQ!r(<;9g z+q>O9`Fdls-0Z1hrVCO%QP^KJgt`mKh{V=)UDv=JTLH2K)E&BL(~g3sAk+Au6mdIS zEE$hiD8-Gz9$iTb=|b@74gyoyMy10!Qf}C?J4;8;KTB$P&K3!UzF=%~m=DqxW&$^{ zNrTl39%$w9C-`fYa+ojLk6H_l_lXRfHG3{FdnFYl6f@%HJdN<-TT;liZN5BXww`cGz`%#@)lO8nx?G^8_WXZLJq9UJUUGN6etnMl~n8yfX=NpA=gTot>b$?8^RO zd$2YSSJ|AwaW;YG!;&wHz)N!nalDNjB0F!Q3x&e&v5OKb#8wgO7J)e;QI)K>gHglkLtPPfNj6!|pY08OHzNZf8# z2LK2J)3uZZ-W zcEQLWbc%}!a3nwLn+z5=uZyxKxW#D)gxlwRwX z_s8wJ8%P*)pz(^hyQ&2gpTQ5l8s$yFq7ncA_IC5)J3paq!J{;mv9<`^w9ECykmH-ugKWm885alZeser6ceIm)zu5DfcC&~|3+9Sf0@$_TZy`z%_*xCxTn^wggR zyCixukBgH!>rz?Y!QoVtv=+$3il;3NTNT~)@1AxPGU0WrTnFvCSreDCx9`IsWL4qk z|Mx$xW;WR>JotL6W&@-`0R3H?&VVxKPt5)kUE3D*k)FwC5sd`w@L_RJRd^BCpT^@F zlJ5(3Jbv`Cm0%qNE)`~4sVI1=%ek7vO-D%vte0?8yuEL-8Tt`-c4w`ZbtfwMmX4`bc!1#+@d ztx2Wu6J*ggw{$-v^7hsU@Ef%Byr6JFlD z)9Ji~F~-$vKR)Y!0||88efRAnuFoM+Z{!z$-_!Q20qdDt{J$Bw&!9{1>Ok;Mj`w+P z&iTGM^cy=TwYsJ5R!c%*B`_E;c#Ms)i>=*ZhOuXt@zi=;_AF*yV=!PCOa_5aL@lAv z>L7LZ+v&|Y-JHX7@00U>V2g3p?uR`e&WBUy|NU3zociDHu>-hkY^U}1%G!-49;`Y_ zk)$*L03ZNKL_t(GIFN?Vj2mVLvS{w_}m967uX?E7v#m zC+Up!*2=G*iw$b>xhi|zbMp+O8O`E#Cvk}g;dB3G9e>1W~P=P)mnd60Fw~?S^d(6^_>~PS^><>&M zQjA@GTstr)I^*Jx!j-~iiz=ZxE`(d)$Wp1w9iBad3%#Fw<10?@W0B!UCGIt3m~c1m zQ?ZY_7cBs=0RYfd{@Bc=1U(TS`{OOw@LKW-cO;=XCt!5YV^k`cCP($ z&`W`L{Zspgv-8*dgH`hT(cY3Da_C$7WrBV1$+x|n1Vto|JHJ>|u=@LskY#_5U%;ko66 zBt|gWfum{4c``h7Vf3j?>)|2U#IHdT=9`U9zz7ZbvbG7jnG}t{G=l0d>2#c7(g#@w zcFG^cVWeBg#XInQaq&VZW!pg7po>irE;&R)j}Y|gUVYy$x71Eq;%PQD=!$WK+N<9o z96kU5B+^<|S^$XDvTt|tg;w|>@tq`$rYSSU$Q?{^z|}S% zLb~n!e6POk04+Z@#J{r&yZcBgNXYrLca|e`fZuZtqs3a+%#bR8(1@`oRb4aQou=su z9!rx_vom7ULv2}HxK_B!;&Os8J$ocd35JG%P{&j#7}Y?swd`t?)xz~g-+s?rovW|R zH=L9Zt0!j9**4V!h&j`>+sUK7O=a|WUwO;}KUU4*#@@?ngyhxs$?)*K+;xD-J8x%8 zAB5g}Y0c|{CO!r;56{G-=UtN$={nR=q#y9G=Rgpy>F>=~n)-e#e97-;%~ASL;)Iat zC+zB(I?rZQQ2t}nq%i%a`nI>6IXJ32OIUoa2 z`NNlf8TN)<&N%koYhF9*L8;*F4;rQ3flRE@S&M>seRsXLKi(;?Bg-ciQ%{=V9FEO6 zZRbq?B=4Vi^Nnue+!q2wtP=}A;3OA&PCqv(7$ufGT{CihgIjIvU8C>K#Is4pmlF7~ zl)i+KqUTc|HE&2prWv?!5)}6taKEVq5sP%i5^4i~k?fr2?%zL+5u}4%_8lsyQ*!WpOH8;IcdAI|{$=Z|s#CRHj_IHq5x+s%C-R zTk-QJg?a;VdaVYILy%!vb%6fh2d|aAw-LINv>e{!R}E&XyWraUP8fmNM?U)r<_Ji5 z?|SxePot;v&~tzCWpv1IT3GLq&j>Kpi{NLYK@emB$kj7R$u<<-G>oc^c0o(fxDI3~ z-Hl$eD1l?R1ptH_2O-ERsiTKcTN$%tqs5vyO9*E1v1k5_Wr@xCs_WzGWQo<*Z-$RK z(e6bUERTQuizMD>LH9ecPei-(s}Jt-w3+*$uIizM(q@D=TlyXPThsg)6ffgT{N*ybFR{A_9%N!&yNZ9nS8j zKAYWm&ENf#?c%#QrgNo>x9|N1Sb<=WsO|q6Fg3vP(Lsl90ZNZvtv0Gk2ZmeS=5luZ zhmd4@G19gHRRsXlZS^de>=?RW0~R1zazhnsiq0D(g2Et(qcs#`tD>x!Sj$jUYsZEg zw$;I)4r;a`)3jiMx@+`*GznOyO(8IWfVL&t7MpMY08mnP9zK-DS;QHBOJ96y?6YYQ z(fux`X_=4-k@Ns=+SEzU&OGpu(Mb(Rd9179^zQ?h13)MUu=->E6~2S-V-)>q7`#rS z8L5@zHgjefCtyS3b^r??9SM*{>Z&O=nT-a=>01!c+F$vu(kWpI=s+;Q)Wao2gb2Z)2w4r@piBT0Owa;zlBOD3*+K=->KR-IG9_h6ROeOb z0BKPG6(B(fwiL6)Sh$mzzgI%e_YQdi$ih|Xv;`C|8MwiE(V)xm;Lh6FKRctBebw>X z4E0BRm7`ANft48$>h>@!?TS}qZER#;?)#J7+~r8`Q`_AfLALnzGmA^_0PCP>(=xwf z8M0-=fw&i?Xv9RAghRz#w(W&L#l){bSlEY?Fa%n9KvQT9h7<$UwVtl^V6&n1^zNQu zHw^#<5d#204TK=M4(hNi0Y+O@4X90k3W!xftpNg#2Zr&=Z+ zCSVN8HnvZGDx=&LX#5RYxs*JU0TGbw;Rp(=ZDZi!L;LwI>=oNf{bvtbW();ed9UXq z27>s*0H^2-AuI!~VN7$f{R00c4v%QvacnC>UquKWJ2M`I!UF-8=2Qd85bj!gk#|=fWppajj8Yu(VM7M|GEX zz_u$JH>wcmc<$I2W$6>A63cMt2#5Dv4?m+3ZMA7^HaLq!Q3+hR@(t9I+-QJCP!grJ zR!k)bv_|z*A}pw4md*R1Bd1~q`Pv^TehSYYfmeHeFYMt8 z2$XMcSKC$e!7AHsW7{r267+i>D@Y}RLTF=Gzz^%SwN<3E%imqbyU*+rG4Po&RC{C1 z#vaQ!dz~Z#cZ_mw;L(fmnd8~5yZ8ui`5~99(=dK7o?Q_7Hy(}r0ZEpjwr3LVZwGGL zHqaOowq-TqAFDR%1({dfi|4E*mxSu_WuU2BZ~VAI$e)iz`*Pbj<^P~r-+8C+2%HDhY*fLFk~G~e9awKO~EpzT3S@&H%}Tgx?TTivWg zBtgl6Q4eaH2&nDDVGrT#ST;gJhS35mBq|A()&sn=3c9VU?jfx3%EIQQNT%XcgC0kH zqw8eTH>;bWv~#VsZk45{LYbbS?ZZNAwU=~eSSbftx?68ao?fZbk{VqcMAAW*(gjs~ zOxsxU`VVx?EQEpz-}HGH2!I;Z?&!hD9xf!@hoE7-xRr*JW_EdX#F5xFAk&TV^?Vd_ zWYTHQG3ax~GaxJa1qU$(w02kx!a@gtFjLtD31%=nY!{10WB``ty} zLsSFE8<^!lvdi2?W6O(^5*{QEq~E#ofC`+3dOK^`edj0xfXBz=&fVh9Xs{}Zf<7cb z+$dhl(jk}~QgU=X5&wdvyLfA>R5iMIDHiK1Y;u}nx1A%AiD|M8G#pTCziKd!X+@ha zv%A+eu~5$`_61Zl$i~GW(Aj-(?7)~T9lv+)pNFQ{5B4j8OrXXiA)J2c#rc`Ygc9xP z8!6Sfy7xc~oNf%VfRGK`>U{smWarZVqlWi;;nlq?4F!S(O4jHJ!WN&aM__BJQr6Ze0gE#k=;@DYtMxZr@YyC| zQCF|5?FC}qMwxlwt#z^-=1ALzhGzO%gHysu(eoJ7-j6*@Mkf&_2hj%{+6<{92*i1( z`X+mzl}gLgpT!+Od?2JdAEtBfx&(z7iTC%KO2dw2_=NZpk$Y3oC3^S}y>eU`B7$9qwZUYt}6_G@fvj2V};w zchmRyeV50Pp2S=(L*g#B%$$T9w$NPje3{#^gP?=Zu9WlbsrA zS>xyIYWD&h%ChEDZ~y#zlP4lTcXD~rc~rS4k52vM@BYKg1x0HPLS^1lzA44iKmYoF znt13u269=ow*BtaxJTBR=^E(xyr{b?{i04l!}%f{TR zFAkqYge9!){1NQv?|0x!N|grsjZ}0m_X|=_r?Uh#vn7|)tpMh9x+HdoT~?GZA+Ene z9*KuHC$}ouN_&Ixf7aPsXeP=uk!o7Nl#yRFoXw@17;!Akd{DSqOeK5(GVY6r7Ch<< zk8WJupdcxEA+cGx797Bb1}Bix4cd{6o}DSybgPFQKRPNFZ^RHdGVy7Q)rrW&%-DpG zEy{k|2|nK8^Vp<5z#g)48+{2jXbrY8#A(gSWk3b@NAV#uZf?A}9~*xTPPB=&ss?+i zz`7@u(ahHPlyq~sGj^V`gz=?!zU!QP&OI6k7dET_7#fP#*2z(qU(llsa5HRujwYp* z8@~xgo@CYnck|bSQ`457M8#X^fdJxhY|a;g8GL=MRoielIw7z}IFdZNtY->zYqP9b_{FXgx-egT6%55C}F1QU^?E zUE8y(Oq+}|y}aN~lq?(ypfdV!zm=8RdcZf}bs#|X!QJ#zN3B)_DQ{(x$7>*>u44rA z6xh5e2MAwtw!YI|+j&1c@@I^=Tk&o?=@FU0`%8;uI#9fG7eq%gWU;=y81s=Da5z3B zOM1p1N^aij5>ml?a-^!fPX>^P=dnnNSh@baW54$mQTFEF`;{mBh}eZ|+h3nP_X)T6 z5jwIQ4|ReF*|Otp9X7!bY^gI-b*0xl>`sIa9#Og~Xg*=!n0l{<+IsYKuztDaz33hp zKF(b(gP2YBO?8-#QSBZ_2d-(a9X=8Pl_#%W`&(b;bFoA^3B6adO`Y|7;Jz5!2I*oY z7Y+v=1#zu=>j52}fjc&D!vsOXVY;|n_9endfZd?(d!!ieLE9T|u$gfhYc2n3GZo3W zhlj#QUWpFj-r2^6IDitmFY^A%yP@F2hY&|@_4|D%Cs6j0d}aI2Yx6TR&$Jgxx3}K} z0N^mh(ia{{t+wtL3%;?Q8Bp_EoBhsXA;gyz?of$yDv!6;UT2S=Fy(-wNu)l)Y%Vz5 zWXC_m1Iow?KmY5#{zDpF--*Nt&JE~Vd^;)nT!U&*jP7enKM0O=(R=X&wBIWf$vVPh zEGsB%FOn$-kLYN2+dVc$Lut=MQrL580BxXymDbnYj0A?bk1kM&Lr?U4CyWM*i}9`!nH>vhL9)0EY_o*SD@Yrj9Av zjmotJ1Vk+WwM-QNfc7TOH}ZUr7rVLNjjvpR$xiJ-pF3`DZ8t;#BfJoVO1&HiLaJ1U zlHvGbw~?26dt$dJ2><{Xx?mVO@VmbpYygAc(%iZVv)zS#5C$hce#v%2lBzZDa@>56 z-xsx}2FrDav#*D^4jw)R4vmu@)+9rk+^Q`W%Xjw0!nR9mDVQZ=BF;Jzo=ln>{?B8_ z>zqKYnc{)~S%8VTD1-orkZswPY0Pu=x2jo`MgRcNbusQAbGtLP!w>7YuYZDZkLV!2 zr*vBoOK6;A*>TqE>T|$2j60cNV8pHsFbS$HN`p=p5#e*UoG$AA{@q{qG@;vBwbs_e z>^;k{4JO&rovPQdy0}u~%Eir2du!J;lcB?h*S8BMOIsQk#0dj{83Eti5&8ntJCd3m zP_ZnBfiMh!OI#E0k2q{79t%ym{3Tf!cKS_;aAaZ-nsvDPDGw!<<=gjf6e@QEjzCbt z!wEOZ@U~{NkmV+Q>{!D);xix#7 zJtbR9#jRfo4!dhJU7ay{iQV+0TfFRc&!SDLwv=1{>6W8!SiAb+hu?j`iwlCZEi5K) z{`yDF>PqePpX9b~0L<`RX|C^)gZ1zuq-j(TDp%qRz1Dx^tc7(*d=HZP%eC@BU&up< z&DXbay`vIUWT|TItFohO-Kv9Csjf;*UPd^pZMlKMqQPf(N-dpOGuivwVBba=49WzA zx|J5h>BD`HNM!o=-|C^O8s>qF+zc_-zEZ7FUFE@pf80}glHI@@o5i=XxZtn6`F*9U z!Kr+&b)|f&$9Ns${W(kFQAg(5E1%{=;m3rz}vPt1}MjMi#(m%FjIUm5^11 zKo8)%percttkuUJ)e%2Vy5%UPc)^_JY`3yFTX@h`-BY9Xi?1J?w>tYW`taNlBVcsv zBw7e;yrWJ#1DXru$zi?sRn(gea|c-9|cgyH(qn z%ax073XQGOv!PKLb=U~x`NN+*b!~~Mn^5BE z_$W#;SP(TOK(ubgoSkAdS?k>;07>0#`c=Gp)aAJ=*j%E|spNX5*9Z>>E7wDtIcMOeIFFADE_Ys>`R4%{V941_ znqs<>{#G(g_D9IWBsqGHecEyAD2W79#9yV361hX6+Pkp8C7}K_@dJ4zhM^xpE1l-h z6MyRJU_bfcf86bk&OZH_*Z=8ru9KT#?g{b5|0@tnEW)Sne|S@{563;ZZ-3_-XC<}T zd1Md!TfcA?HTgGw_`h({AfAf9_*ef#9_d-O(<9z)9p{V~n%~gc@EuRm`tCQsI&#bs zJfrpZ{!9PNVPxfEZ9Le`KE_?kK2-2|wUEbKN z7a(8NxaB_BCYUuOw(HG8xGUPnIx8y>zU0u+@o}|jZaEQvGH1^qkYudlJ4ZKiFoj;# zvul@Y%u8sUh_Ns-_Mm2wCt4vnr(uISl5z zB)-wOe2XE2vO_Bu^8IK4RQB&(e+eNE0FZkB?qv|uQ6JE3zU_X<#p{7eZ5}2Kn9BC{ zKO~N^PSu1RmBFN2SH10`8XkWV22DA?-N!}RD{@d#>F8PA+)>FmYX$(UoAqy26lY#( zViU^*RX~Gt3?~T^h3Poj^QkK}tA;v}6wpCkdyo?Aw=Gl1`gLcebp+(z-V`^=((HWs z+GdnRuv3kWe8YL*$xsfwck?IrEAES*`_iqK{&#lvcE9*h>-N9+oZdyp>8<;VGW5`p zfA8|;@11N2CGPRMJz$sDfU{rMbu<`!Dtqyw}lXDe@4 zyXzY}yDzSM@E10iCOZPq_#4A=pV)T4HPlf3xK*Cv!#`xh+OL1H^60Z{*&Q|CeJhsu zH?&*3^Uhj|ev(NYdH-kMoDQCc*E28w?bm{yk5K-JU;f}5YA?-rMz1yhStbhmy}(NM zJH$boaxZnJehBWhC~t!0=0Hi+H=G*RKZ%DNg5{@a&3gzoJ@U?!GEr&wd7&4DT47Bf z-oSSx+)}LZTD}MlO{ZAS{_kJ?&xG%^O3kdl{lD3L25X__2d{@x%s!a8d2J2{`e|nQ z_Pu`?V*Rp%ZUXPR_cOnpm{61tg)smCvI7y|rN85%5=rd%IHnIi>_sEvY^OUmjRK<% z!y8RSXp#xAg0GJhlUZ3EjbsMUsEetbv$4#jvlobHOz>s^)#DU)mRG)~a`}#-bM6-l z_tsD?+o|1m2h)T?-NKta5vQ1ls=j7q1XZ45(z2=41jP0B_r7WI`#NXN|MW*F1Z3(b zK%}CC9wuf2ho1V&hT8NJx3U5>vJ)WLmwf1&d!rt4u zpQ$Vq`X=(b?-x`I54_sGRRJ^`biqnX1D8OHj-yc23L#`<&dHqT+K<639^`&x=@Nn! z<>X<;l3OdB@22p?p#z_oc$Rhc{nk>JZUHtx0m#2TW9RA%!SK-`*2@Vp0064oKrn`4 z;=0-e007!3?6)-~fKy(KoNHHp`(~c20{~FF-}zlugqmTgYOlb=NEq}r)9DS~u~lzv zmYdBypO^S`SzYdwAGAthRjdJ~Am1q~GT+&x*_3;joSKRDGNZ`sDIMN~No{}mbx`Wu zOmV5x!A+>E^uzWLCbQ6F=G+JO?m;MsM+wO=5QG3M41&-!z*jqa9?zJaYOCulCg?^m zhop9C81vyo+U}69LD14n)zo_WsKe2c(6F#$C?;Y-wh2C1Sg3Zo3v(-SQ^gph?J-g` z>j;s-u>oY%CPe}=QQI<<&SpGdHE2O@ZI%>~ofH6&*Hun24WQ)1!hGT0PCftLVr8}X zL8I#1lTE_`paYDn`{4(k&3wS}1mb5@!s$AgL1`ozcBxwroW0e~b{B<%1mnx54(tl; zt>yaiev569tad+FU+ub4)N4^83^15-C$ZVWf+xDcBcn3I7`njQJc_dn-ha31mpunb zFEK7%Y_~A5Lm`M8^J+kUhjRvEAx-w9109zzJ+@3Ax;F+g=(UYzDvMcq8>gtGR>)V(BbN635GJeW704ioXLQW`(Zbn7Rwo%k)v?32V zX&3|m0Py1^`k{*H^VaQKF10~HJl`zAraCeF{66<9Pk!lM5VTydk`k5A zs4@atO?v7NomQ^R>WOnfEJeT|1ZYKlJdP-*3_Z__)q3V+ySLO41=qwRi~$k4v zKY0B+m1PRwxgu<7{-Zjs$A}p3h^2kWP!fSt34;le(uF_Tvv4#evbRn@fVNsoc`j64 zNNkqM2G>w8x|7+ELhMOn%7+TSS|THd{X~G-hj?c!=?Wk9_BL1je-NtOZ6l5(oP1b! zu}YisQp=pI?!Q>I;mXp>_p1@z*;!jt=3DuD3D1pe>F_SGu0xptPm&)wWa~Zo_!q;~ zm%!#wpd$1gem>U-5655iD}$zJbyc-)o>DbRwRs!p*tTf&x}c>BTfA1az){RrdBO?n z0GQM=`{Of7tsjcQB8s&}7 znflySa0%8yfBHfkh7d?LQIsGt(!jv$`AStFP)0tW?Qh-ts!ZU)>%eNO5sHf~Am(?p7g-(-jkLlZXaGRYt8^ z9KkRLp(z~>`kiUH`Dn}9H^-RW?Y zO?n+W+w&cN=@=aB&foW6tnpXR8BPe{{DBC&w!Rgc8j#BVZG1i$J)2$KaE$F&rPGva zS;CPBqn9;2fM&7K<6HSRN2pU(8$=TY)Hn-lt-?#Dj`)MKQ53;!L5EBXrzwlE7P8F} zPoS(hg;Z8={wIln=;%2LMrgOtYIY3*2Z^vOluT1W?0{5Ly1T;Q$Skxs)C^?I`Mgu? zcm}yZ_~-{$-rn8W+}p1Sl!$p|td_o5tbv*hLcMN#$+i%~wiU>1=&}G=K&HQfaU^2G zWFEJ2kWJc_j&10%lR?`JKpI3l9UuTGCV>TL004Kgn@9e%51dnQ`wa$oI50K{8$8V6 z8f}Y;IrDo*cXuoBVXnJ&@R;3@k~Uax`a=)FXfH*;4H*c4%tmaG?`^sD&omn^$4FXk zPF8L|&{q>W0Uz|mLE8jqlZhS#0ni4a_x4IfLqtfZu<^6<-mftr?8OMcGR$&BsgkZj6Q>`^ppsbBa_0LJbfi^-{-i-*o_gz+;m>vGa)E56M+? z-RX`!9t()B3}~N!ltE{w9=TAF3&M#TZlGCHdQkT#Flj`I6QtP2j>RCp(h4l?hEM_2 zXwPT^k2Jddsi)5L%$Z&F(8)(KTjO&SB0o9y=)D`(Mix65sU!3IC%-uDKkf$m8P((b zz=`CBSVxjHd(<{J(0~~V{vV<`;PjpL$Nn|2bgh@)d%d~)a!KTVTd8K>s^;F7_yPa` zQ2l1>Tp%&ZdI13V-AVj!!#3^T=B6rd@tqbL=xB<=7u8A}%qT+O}oeCgH{JE=ztt2kITMqDovPn8GE@&v*|Db3MWIQ_Q5) zf;}wO73&z`>Fx+qPJc4sogRADZVowp2dc~{7I_%axsu9mm|cz66`=_L03OD3^=?IM zd&J%4z3XyYJ34mApBj)%1k6Ml^PIFMvb*+Bg9a>OEOGMiz~N~+Ff$q30K5GTHwLC$ zfpkeP*}&U!Ysm%M9HrORO6$G$8dr#~8fGKw14IM>DQwGy_2>`{d#6HFg7V|NtO%h@ zUx&(hAV+9cK-_|1aeVIhu!FXDYPUz#hj;O7v>OMi z4_Mzg0Lff-Hk^*EhNJfKK#To!X-zZ@85AavQBJL%s4jn_sk{~=d`>c!&0ifp`@}2j z+wHNq`@j>P;tek_)LYx0Fx*zq@Bjp48(tefI>PhKQG7%~Dff%3 zZl}dB8X6)T4qRKZ94)X@jhnSQ@mq!pG4Y*Eq9EEi$H-(}%$tL+De=0Uxa!9adp&Om zsqt>D&l_Ngp%Wu)9~rx&M4ZVa)e!*OJ7YKv;P&0ccis$;B&cNRi8UBPK>r(4&*R+| z1KRGp(jbw&ZwRrm$*)AsIavv^&IzSXCVg(5$D2sxR5&Bc2RPsupzUHicfqMyRm$0b zY~mlw&HcSnN0%;N4_4P|`CMrHLG?FVV74e{(eB%C_PRxoLU!_BPTU{thH9-4w`V}HdErp`XD9MM&m)x(a-Do%5JtZIQ2B{ z5nG8Rq%89He^bButKpe1*)1ZKGSjzawz@DKJ;2_3q{q!Gs*|{Td{gbl6Uz3I*VdOP z*8mrJL7k+)ExR;%*K{&m&5HYwjnHf9mTEAyZY~d-}8AAcR_qyKRm9nJ0XhSG*tb`Va`hf#u}>?+Y$V z(z*E1$9k<5R$3qWSiHL<>o|B1Z3XvWxYi0jd#Ck5Li zPnYXGyJJs3J$XaDZ4t_a!GFKE{4+>zB8e~Z2B$&5u|ubULe1Iix~Bh~?T=a-bJE2a zQUh(ljC!bo3WAEbg9qW>CIWAheu517R6~^d0OfucX15_)&?F4?+w@_Ex+X|Lk`6OD z!{wkrD-|}h+t9IDwg)VL9f#)t5gJm8mkGxytQQI=`+e}|3D4x(>9j(~e&*#YE7 za}{8G!jWsDd~0EJ_>mm(fI0-W_NIi5b)X(}xLIL)QjE6s--7_X=js;b9nqaGm+68Fsp7 z+SuwW9PT%sKDQtK0zMKg%`vGUQ`1A3tAbqno0JZtEiSku5cxer=Rbvj*R z$F|9H;m}Z7%pM_JS&z@-gktdB$5+1D@F8eA`o|tK>Ih({?)I%W5XwC14(s+X>t<48 z{Z>%F_dsT%+qD(0$d$TFj%Wi{`^zugedWN!#7IoLw#aVTkq}3I`-M9cs6q8pTQ^=v z^?gCJS0R*6!m=e*c|-dhiqbUO(^cUAcR<5IpB*M!Eb}%^LNz9y_970E?f~sY1@*M(3a9dL}X}5g0SEvfhn-6Kh<90bhIs|Ul z5heSNp3t!ikUh&J$@0ynvkw1k^IA4rDvp5tp(sogsffk%8`GeR8&!@zYU4YikN@f&c)47}V8Jtwij4Aqy-}E)LSf?j8UD6Oh~t znPJS4p;*~o;3ApTY7@g9`&>>8l)!aua4MMc_E!hdA#&0`Mn~c)unNxR{zv{(HH0Vau1IS~LYmL&ZRzc-JvRv+SW$=KQ*n8YPNLye(0N8wc-7HQr_8b1qmeX%_RvZ2nCrtX- zy^x6h6%R0=uu3Q|B`vEKdop{D7f{pz;fop3~cm zL;1zOy?x+PqU-A~{`dt_Kj!ct7z2{sW6~%hJ~@fOY`@ zSe*AK*$SNQ^osH101fYLH}^pzBs&;M+49ObrVC zdBoeETg}def$96=hjU?~U_7L7-Fd@tC?x~;ZvSFQQcpkk#f7b}GR_+V(6ids*Bwrv zOr71Y&AEfKA*xv@UXcugYaN#dH>j3I7;?9{%(w;wm%nz^*RxL&J%_2zg#%vJ5HI?AHMqS82M4MJo3Wd z{)4+P>5Uxy)|LOm(|=U7hL>;sW!KGjNo!62!B%>g_GF2Juf=!ft$3zkA&hsH-i0Wl zo9P6xUd+S9xXeM42}#$}u7`64JY)X~SlX*gfw#yFz)S7nhxoM>?Zji}p{D1j|Lrqa z_$ka4z4z*W)FVAN7#3c9B{fLyqthSmyzPoULxF;(ucpE(WdiWN%~$fEgw~7A&sIk;-1C^n zrz<7;GK~+SYWP9#7eBuF@_$$PhS&$+avh9<6hC?#64*_w#<#ZdxgGDQ1MJ*(E|gLw zpV(D@@ygwnu*XI>{dE?v`xO=%WxYd; zJ4!kR^b%}{l2l8QWX2T%FvyJePL7=RhGLYTY_!>xg+&(w>AY?k_Lf@kjHYW`_x`d0 zYt9?*ZguxX-w-jDadVal1dqK`(X1j6BRQ$65*c&*49 zHdkD^iRRl*lf_6MK250|jS3PF3aMVO1*yQ6R)^gOXHHhlZPJfxJTw^Z?+eYMUbLyo zTh&Dqn7FsMhy#*MC-$?uR4`y7-a~B2gAsSQTFK?x(^o-4Dcqi?>Y%oJOV_$Bp++m0vYT|u+X7Xn_|Eg)c$N87{ z%mzM5mRIh`O}%G(5Y-7w{V@cN)RboV!$ar@cfXxp_3g|3N z77SmSwYEnC^(z%YpkwIt6!sgk;2)US&%dy?(YH=C0!r_my-{-My0|MJjx?x_Eh*%s zSyl1M@_M%{9lhbWx>eIF?!gVQuSvOrwCFm=JPIqgJ{0;`Fm+ZjLZ?32AMFrCO4k?# z0DxY$$pzhZUysCG7MP^j6ozX8nu^+&DJEmX2&B-S5#>o<9 z=VYC;IlKG)|M~sfZq9wX@ z$!P7C&>o2r2x}n-%wZIUSWa1R7&fS_$vWC3Z5jefxZYqe#xiwm6%4;TWRVt3s2+Df zG&R`(_LSd3yL;8Gr(RC=mIaUPBGGy=c|KJl)pKwvncYci}Lbdz$RXirBU zRJ8xB2=kAwOGu!CdJxz^k+$jOaSZ!~BCO~T+ViNqCRg?}o=X@Ujie1|0nC%%)d)ZDpah`%y7Z#(E# z=FTI-7G*p|OuXP`G@AZZl@B4WjNpMmHEKm>_9XsU*0Itx-EPXN1KNemVUEN5jfW%T z$*ifOj+!Q)HaG5L%Z6cD1j-Q@4G6>Bw;+=;Ep>joo98tMC}RC_P5ma)46F-X3s^8J z>wyi!1^@t(P>8t_GG+ck5keRZ#8XZaCkFElC~RYRi*TB72L%Ze_bIg50Xza57_C55 zfzV09#9>P#H{GG3h~+~q3-$*>C=V-!g?XJAO{}i3PyTj_xTmoCn;d@F3??lYz;)cq zHtQL2`fKM4Wym}V^`w`kv^^zeSbJR?GbJmnAr>i#P}-?(I*$pRIhXO}Z2f0AjPkj` z%DtQ55riTFMK}=Cv=GD{v|9jHEcjZ!l~)7=ZWOkDy1)4r(zB2!3NnNlEkEY>U<8af zTDE>&Z9{5HTPpHiVHl9rn6g1qC;&i~I?uoSTip$3{_yLY!UT}3>9aoM(KSkU33_l#5IoC4EjpAUWZ@0ZM+uHv%-la;tcIVzZ-QIEy zDHa#%t~#wcujH7}!A}QGD)se$`OjHmjE>k7?%zCh`WTF(ul&wm;|DxsPXkZR#YfM- z@cDo1c>Lj)Z@+El%MGHp@%B=c5ct|4$316$>T|KNPggE{+nE!&=dHpCr=9sRqh8u$tSqJR#P?>!y6#*>l$I#cHIov-7cK z>RWM%P-_p9MZ)rby4A-Ulbw&?B_)Ve`%N<{WiPU@-A;S^V87a0Ety1Lski-2;sw5l6 z{~e?>)BJk@3rY4JZju??HNCaBrJ9Uos@?jsJC*iE`1TmweB^dSLpJ;jf>J2Xx{p^I zbAXDgq^f0^rVRr(_jh+|Z4`oJ(@>arfbmIky~Ym2k9eKBtLy9T&##Gw3X20`XU`eJ z2KFig<9;$}xs$~5(h?h)lJgsiyGywVzm3^mtH-@eHE(*8C|qpKWw$j=#0YybMWWm5 z?e_gahz#L=6-3L zBwZzOL%`Ug;~-&k#8EQ;W8f9hFAb?@?8sola7 zuKFr$Ax)zeVf0;lqq#1&Y(>Iu?-xBm4PESP6$BNxg6=pD=S!ro)7+Q%xXtc5kj!?C z#%jISY@|3JiaN@&NJiQ!;n}lew=do5c5-wGcxA#nLDcs5@NJ$O^aT;vCiN^(l4T0j zEGAmi+vD}hd}+22o&ktS5owl8mEvauA!G)|gB_FYuy^fO3U#PIUwSn7YMLIa$E=7} z85K>ZJ3XLEzS7+{=9ex%^&4^G9dWsd9X}4|XX^(hM;9J0jSVDrJ(-NI z=jth2N}2D@R|~2u{*vG1q8)*d4y{>D=KB7}BzCkl|MNgL%Z>b+)rwB-Y8WXg0-g`1EVEhJF<3Vc)kui33iS$&+3syT+RlmNCu584 z=u>)GnS5?zc5(PMS=#Eq^jH7(#4}%k2&DGj&z+xe7eqg%92%PWoQFv2c#P2Mt)*RV zZIl?$%>gm`91r{$eBYA_aRwD#THBka)EpzLyip;Dw|`G8 zX_4eJ%i3js1|f_w?WxP9OP;_$^w2rJ@=+~JCc(s%fR)5rY9`iIF9lPHDvM7t~bYQ4sidyuIrC4T?__a50jd$O^ymUKF6;CM^Rqz2BNu5T^YH$4N-TCKrM^`1R4*{Nw* zcQH2Vso~oc9&`p0Jibu5Cith~ZF9eu6~a?}OgN|iR3eT{ST=korv%+e1J;_258cmv znrQHkx*PHI8CoF=Tiaup76TE;8#s@pC0_AY4d^sd%_wd6h)Yg$ouzLu2 zOjVjQ$wIrMIt#A+-8Dxt=H?`;iID?JIX7Rp*I;O}da5KN6%t9g zy-!-a?g_i0I5+p<8?5u#$g$H*Z_~0;v14cC8XqvWDd_0Z{dq2Y-tS6O?mV;~Mf__| z@3oo*Vcpq(IvKk!kgyHkbnVr1G%1L1O}NM@w1Y!dx7VWB7s+t9QoI!&n3OHes5@n$ z=Z_m*!Z6X&}-5IIX2=64w9k@)z%gj)3e8MGq-``Js;#DVz3CeDqNh?06?Ju*bE=KZb- zaoX;l)%J5zAq_rrDf}~+>nV%%uWo#hxmr0B_9Oq?IUoaAr`i zq@mUZvsXj@naz4j=>%UQSi+@=VXx5_Ko45I4UOHrc8PP3bm~k01u!*KSuy_}!1}KR z-mm2zU0mB;>Xz#QLHp#+p4~G}2axt+SFS6rL9=T-9|-KmwVFc zlZWjUD0i)fSeB@Cn;-giikp}{jgzhhrj)mD0RRlu6m919y{#A$j(CPJVK;i1O;I)+ zMoO}Pl33E_8D_+(pucW2yu&G>nZ*_TAmu%R`63#}YhB1F^du!h+qhl<7J3{GjX1?b zY^G@`hHRw6(}dO`6t%wG5fLNi88C|M;-k7xEv|b6eE`L9xD7X@x+u3b0DyyJvXs++ zitd4Ex7wiaw5S09K<%--HdiZt8%vZY%6p`>$Z_7Dl`i0T&uMaQLa^o7{wJ>wvWD+4 zwfj(YjWwlqSC~s!rX^S=RM&M*6sm?eF7KE>9&bN3$Io|aq+d6d7v{GglDl}y9ULul zbwvvL0?uhQ>?qC(0hZg75|b20dHY6XY;bK~aMN)Nb4kv@d}Bifc3hf4p!)?PO0{5h z#t{}i>E{u4)P?h^hZ|CRIaHKFnyVWbSF_p;{yE3MSrcj^M?STxSU8LkhhL%%oZ=4i zPll|MQx2MNxNssEC|JD+B}>z*(e677o0!Ro%9Q*@2jGxGVyDdP#}#wWeYaO;Y{9*ntIT~m+AK8P;nwVw zP{sTld-L(0{Gg}Ch}8!XeoZRvR`>S7_SO5o@)HMA?7h1O)Z>4L`wjN-z)D%LH#sX` z;q~v=%xrn#F8*36<|~^5_WWm9_1JqG0uy~6Jj&_=kf@{{d@w`L$pFU3X`lGV`a9;C`diTI_~T ztbwh)>cTrTN@2AFYhu$BABvH?zVJDySst$}9G-HZ%yp6@`rC{lP)oP7h}uW0X8%*k z5}i<$_OJY}|1yDVJ&m_nGGfFe1HZcRw=JPq>(#OSo?j;#GcM2lI_Snz?%rNoc31(? z^E97*-E4&-I{xtT&vXm*41czCw3&4GPP1 zKeHte%C)DRTlB6$-oB&<$%#EXy*O;^r9!fTSK~h9P}3j6HLrT(sBwI^0LPSzR@N3fWn& z@4!?@=CGc$=8_0hZ}P28m#bgJZAx1+HJafJJ}W^JsMP51H5!Doi^^T?jsU;lWGa~2 zGU5y*n7CeO*rTUlX|A-|I1I-cyPHs9ogID+tKI5ZRR(ZPPA#P}eKCvc-UY?0bU8uF z+bhEHGyV*wRa$diqT;jgX1iF`Z4F=*GMNVuySxQ`34s9Yqt2n^?$RZx$3}BFz8e*{ZO#=-uYL5M4!jFknQci_($E;Va;QyHy?OIc4GMG z_rCeB&d&TpXRPm|kA82AeU;c5d-KhI;bWfjN7UxxQuW@3v+8^2jrTh(iLxKO@a`YW zzP!gbKD&Lf+uIe0#!B~_+(8@0Q2MboTVsIr#bpuW%Vj#_HyCTue-752gxtScyhrFk zX%?4qI>XS??OC1hV6&nzVruflE2tvCkYw>ySNYkDb{`;wS58{`vE_Cju`X} z`}?G{2f=+XCpcnuGaxfuKU@3r(pXSVUiQtbVR5(4$B}m$mQZ|h67Hn zhlaJ_RP_L-wVw@ys+w4eeED)$3Yp$c;0P%$RpoZ(+Mm8oI8NCZf~5WR?H~5k@zy(y zUU`4A@4RLebE=4j?FWHfM(#6tF`-dOI5tv1?7ENfgQn&he8llOgg*=hG%}S z!65`r+w2ETA|SUVVbAO)D5)#(i}Ov6vFt;YNo?Z}GuVM0RLDqI|3Dl(I5)x*)6ANy z3uk`@0I2SN{ND~z|5d=sFYk6Fx!m59guJY5pL#JFJ{D*d7j~11)-(9cInYiMIOj1s zkg3yqp8j)AJDgg4vOK#w3lEz9ux--e1pwS_6je=HZsyjy&5qRVZm`?*{))IMnPz84 zXjSK67!@Di*)w<&#qcz#wsgwJsX`k73u7_wgabezFY#fwjbcMhGIA__qUwoz%l=kP zZLA0Y02G2_$Hp89A4vnXYcL)*-x2QZTw8cdQk zkRc3_>z1jP@~h;cRFZm@1@Oo|3a>Ue+0@O`A$Q9}5dsdDkcY(*=o%Z1Dk%3XIjHG6 zZK?Tgv)!u|HU-^qtKxdH{1u~d!(oJiLvk}Q!{Q?+CF$F;QV5K)b1PmI(-Oq}l7+ z6>wX6)Z>X&v8wEM1&_I2NGAEBOjt-Qf897PKAm)w*Rn8-5uh;F?X<%$LL9QFfQHGl z?y%oG<>o@kSd6iT;0<`gAdP?_UHs{rfA|OO;0V35kliX`des)%_s!n>)Zx#T)KV<< zka6q-R5P%$8~Tff{Kvqmn$y>lw`Z*c-7Hz9fV_IW*by75>1jZ=j)g%z%a~m>J9`q8 zU0L3O2o-e>W9G+f{&73EMEi!PqZgE--8DKP;TV#CO|D+=Sf%dT*>%}Sy8JUQecFfy z!?9|8OilxPgT4*>Zuhxv<|R8MTd*ZAR>`>SGwGSbvt1s?0<#Ba9ERR&YeCoZ_gfO; zX?T1u(Uj;oyivZsgSZMB*&BFif{TaOiOh-5r^y%Xa<-v`Zi3j41=tgT^mgT8v$4^! zMijBSFDS#@;{GL-v`zFH3%P|b+_T#PIjxX3D_P3(DTss`m#^;jdgef(*16O7taRty zdz4NpJ+z@!Ee97YP4zn*U7?!(?3bN5-IwxguxD;A{4KBMGM(EvQ@xPc$?t7UBL>l| zX#^2Q$%QqyT_V>$_Y6gy3=N-Au13vqI6N~(xlIuxrbovq?@7X(a2O@Tb+R=)xwFo9 z)n@>E19F8`v%Z_XfJ<{8k>9z zK)}=mQQtK}2npLvQxi2wGtI!Xvy-b>avP!Ge)KrxP;drAET>`GXQs|~RaLilXg7qI zRSZS#xXrQ*sO}kmWy&N?1Y)D{gk&hH<#Uh3EwsybjgznT^_B&e{yEEkCV4J~D6mU( z0uoj-mUm>jQWcQHMs3;qSr0A7NvyZ+^S&a(f}MeSq7`-JR$v_Hyv_P$9lDG|q)|@E z>-+Me0RZW-g*2rHs|4P2Se7nzktda2S?|G)Mt1E7xyLtj!xRnOGGtTez+r<8FeFTA zN~f&oCJ7-p)U9o(iaLyqy0{SPDzUZ^2mlN2gPmSc)>L0x2Rw#aIE=BDYW4`Y6}KG= znhLPn13JNCGNgHvq>E_O3?*P4M}1oxH8`$818_%{9)0iIa_7mNA3BLvE7^K9z43kX z-bU&G(YSOS<&**czq8gY>S($;+p+8gQp7Me_0b1EicNpLv%8p!%u@K-R&E_hd!Txa zK>ZtyDJ3_8Hn?t7?Tl^wpMw1}JH@jat@*tzs4|dl)$p_FK5~^ee9cgwPDI zx^^R@{3#6Ae{qvpKpPHC!3bqqQm4@{I1NbuX=jUsbjheMv@J<7ke)-2YL-cP2wRLs zU<-1X3Y<5|CNbs$L=%=EFBQU>Fw%two*uRwFrXc0PkaeLaPEF%81Xtydj}+5O-@88 zo8f3P2^{CJmbKJ(@=Mk-iPJEl*g_{fs2pMHDTE^7Ch8e{;pVlA$Yfla&-&ue8LSMK zS`2H~sgf^ow54R@;Hx)x-Vlp2Bu$i!T?}Smpmy)gTN?rdFdrAl^?DYDbHM-rErPD! znR{bP{?M>2z+{r=zJfyu49D}@!wj5kED4gF?A+}r$`+T|KRi_PiqEhkbxkr?2^rjxmWNRKk2mB zTL$#b_kRb$cInovFXjf4t$F81v-nkAUF+u54dKC)kMBb25J$d{RS$*I-huS6TBVnZ zs~F|E{lVY3{R_!>R_r2H&+OJcM^}413Vq~QA?cp<k_F>B_d6ibNMS5_jiXI>G zwEK+3QnlC?QeJ0kM>iC*w!Y#;5jBl!J*cuM?{^w(k^vylD(%Mnqj#1sMGqco6NSb` z%{0`{#|B-aBkbJ%)Z`G%k0nA_He-xIaB9Mn&Jbw7v%0a4#Kfe)JZ@Dd4~6G%=Era@ z%m%`GqY>`z2P^G-0h81yZHte&w>s^8+$!dLQu#qiDd8XMgv#-e@R znO1jzwogoo*=*oI zhHsFq&7#*g5Z3Nm0~Rd4*j5~ZO)n@hfC#>$XZE%GW;o{2`pU-7y^+C6 zzKrNO5w(d;&NWb*dcenL+-M`rid)YV*?V=`93C)2Z*_~(MC8SEAkpMEX-IUs55lmg zrZ2l)3O=O?)#6lM=nkAj?M%CIAB2xq-ugfQY1@G3+B@G$4)%vOw;HLl`0~b;O2Mo8 z+O}IB{kb-e$(^Op0jJs>Kvpa00GRHk?p2?Vj(MkX)UN$xc?C^5S-uwO!s%?@S*&AkvorTao3R6&n4?z)M4xnthUw3Nn7}Otr%voWq^L#mA-C}lkAnP zMsPp*II`Cl>82tyzsc59I0*WPM`all+9tcEvanI?EG^rMd?xI{`>%vZX<4R}< z5|GX9xmI}O5UfuYm7>kX^38y%w1>tCZ>26O7&)E7=O5A02}_1Hfvv9vEFXwOQ^9FS z>DduD{NVPF%c~W4>V$zi*xu>H|{Jm&EXBBZ*m1QDb!h&Da$b`7yt zZ#-V2>@zOt2GGh03F=1V>SESkl@`w5kzK_)*P(`6$dUme<&- zopn#yL#sCZyf5LJe>6){2<32^jz*_h^z)1}4vF$k{OFmcVnBH^crZX!8>XiKY|-J^ zI36}eMvq#+EcIGm@+H~PWolOHc*1O!BBxDX?QngeN-&2+1aW9X9egD^7^&T@`~1)F z#_W@yK5?^N%$C$C0fRk5kZV!89XezwOT^_5|1vaq)G)Pl3Cw}Tn?Fp9Ca@6k(fkeWbf}x{YTL_h27!pm=H_+? zdCKSGBz!Myf2GH$vzM><)5A7TwXPUOFBc|bC|kk93KBTIdiRPqeAMsO`K1gor8?aQ zIE(O($6SfAhj%W9(l0<(vM62+*pEcgT(>qGKQd%rOKfarB9Uhd%q0|y+^Ca<@!oFJ z6FjxD_3rA&+wr~`(*&({#YZPiMz09h97BoH)!S>0vVS;*uzM1nL*oMw&mns|!KmZj z)?HNMI4UI90as*6!afn)3753a#+6dD@z&z{2|>NEJ=?`0ANTUDzxf{zq`zz$gd6j3 z>|aZP&-EG$C~kPCz2bUVAFDZ7pV1LCsUeZ2ZaIf2gpWK~YJCh=P3NI{jOMvt6!Lyvcv$Aee4q`Op!jk?AKxrB1?>VpR-&%cPLfi3T$ z63I?)PE#cmhe+9NjPH&!ryb$x7JWBvPFoEFc9>QPmy6W{FTW&o%bYcoJR0jRX2DRM zkb}Iu+Rg2ZANq<8wT&3;LZ^3@f9hpV!dBPdCE3d%;lb60$Bwko?d3Y(Y0*^7Gi)rO z{>UehveGhFZ6VOQRbRWm9uBw+Ma}l^xyD8$_6b?Wypeb*b!G47T}R9T7?aFV4)m<) zgNt+bz4mzO;PaXJ+v$-*n8&?&_p*DM3;RxPE&ZHxx`v!j=h@k~eVlYgcG~ZG;Nc+l z3@P_n%y2bpOs0#Hf!3?O*3y&s(F2B8LX52=4+`?oxqWc4NR@)gFJPNb_MBU}hgi?L zmU_~W$EB@JRSWzaFAL~+r?p;<1P31c`A-}J(?#qwuQarLog91#BTKUF5Ufx4I96AE zi0*4-I%D3E)$Pagi$9y{=Zx4H28+>YA?6-%)m^INIGVvt*1J6SN0Gs&TvxAlXB_cn zzv*zO*;;ZE&XxvuvQ5(7N}#b;QEu=bM#F$b$3*(7+x_%K+%k z9s2%$dq4a4)Y$*u1)dI$jSYNKSG$ZWh`=-eAd0ec^{QxS0Du4rVp2g@x;_jxQCn;C zBb(jjJVxu10RV8}WP-7`HRTr#FGH94*2XX9CK-Ez=3qOT{#3uGKS6Ve3af2z*4?R; zQgG>cF!yLb z-~h`u>c!;;+pLcI2-<^_Dzlxss={hLNVycT zgF^7V-5b@49g#PTjxg=-->hE*ZXD_5!oHyd33uV@Qj^%3(?a2wKkDR-ZPtKCgr#*K zpPBEh4!B)*9)(1fYBvfdTBGFgTqb?YFISj!7XIREw7;M0pLY^mz4g9m(S#6Z zDJER}*1b%-g%#iD)FUa{7CW+4d{hpuBQ!f;@N@uKGo)D?v-{#%r+Z(uwy)`f7~;5( zm|&_8|HHM%m+~14z?(eZROQv$R+zbftsMN?nTZ+a2glD!@@D001BWNkl<)5iAyjIDtdJl~b zc4L|SeanxKPQV%^#EX*ji-%9Y`pnt0M(;Tz_}scQ>tR>vL;qxDGeCzHgV-yBp*_fj zWVYNEy4Pr}SN3i!-!Dx~escE7J5Z6T^?jW}P@WJlzn%a`x z%AkOKsE#Z5zrXG|;|lagH|E~-MV?mOO>3V=+`~st{dadR{@##lCKx!fw{qDnO;e>8 z-v8tO%}z{)!m;-*y=8hcMCh6J)`c=xP`T{~^>6a_3dQtkr`D)a*y)V#ARBBr;%tpT zq=DRW;F6t%&sY1FFf*n-S@BG{+m370j_-Tduc!&#$O#;V7%6P2bYbAx=Zvkfw|?@C z&CMOVkG=G_Z>VmET{|zlpB*a-LHwjrrr!VQ zx7$jO_F5nO`M0x&1qe{yonY7h^PZRg=&x6Xz8t6g&X3>x*U^!)I>Ro{y&X+`#vVxD z{`Ma~KlCbrjbD5FkNU%3MRtR`AI~{~3uBXi_v637LyEyA0C+%$zjk_WW!5(}>Pg9e zfjz|Hw7qG|Q)QboHcTGy?yfK4jUd+Y_Cqh=A`86nmDU}q7mM;Pf;Yrhx?8-ggs;% z0WBaU_S#aFlmh%-@#@1%PB*S~^IOOrp{o#TN)_*zqe5w`Y(>!c$dH9Y96P#g+z$n3 z<}PJnt^HnpT{N`APJdqF4{vhNjXg|lAev&toP|3#>2TjT_uAvlKV>?Rz7t2=yGu?z zooamH+7G_zf+k=OT6nxt=H~ib=lR-o(OnY4wcO>o+RhqhN@`>4$s4!zWE<|*w6%+s z`aR27^K5?%L7cEZwX^o@}%kNH&6#B1{%buGb{6rb5Dpy(&^c9Om79Ri1J#m!DAN;{LfA`k=KlP)j=rZ}jSgxB4CD zOsYLcePfDy4Oe|n*6y{p1Ig~HMN*0HCT~Fl9y{gxCHRpw{{kRo>j%&HP*>+;%6?WrTlK%0p6;bW1}F(lw3<0tLO>beyE`lotpQoHqNZ{f%CR!u;@!&jcJ z>(?B;n!E9x06Ht>tRV{X*Rl`+mF_jjw{A2$9|yLGmUY9TmK)V)T~M~m@9XuY$xr-} zYWnAyDW8lf!LV3GZ72o>w>OF(`wlw`TUN1`zkd0BV^3+fL>cIWI*kSBQJafk+E9wf z-Cyb;U#YAHKKSkut?_N-kVzYaQr}#qj9$QF33hwZm-W>a+qIQ;|0)R)FgAAY$xpv$ z9WQE5s5ifdjkM70dwuEuse;?gp0_pnl)L}aWwDM2ec|YrICF2;_X4@K!<~IGU~>@_nWJ8fu zwF|T!=2Ws|E3>(<^!kR%>i~dFzLjJ+A4&DG_WxpTQ4)4~?a)~-V)*oDNx1 zl7+l}mk1ZP3?gdNsR1lllnotSRcpDf8|IxjWm#59>aiFm6^jVOtUp*ub3jFH0DzVz zXC0z1KxiuO8nTIX<@jJkF7u7Kx|opzH0O<+9_f3&W5B%Z-Vqs_hdoGo7ut0}RY@jT zV+V?5MCb8BwjFiZWK;QI_uk#EtkuJ_6)?y1tZ&c}4q-J5Lr9Ve>I7Ox-5Z5RFa)6x zY_d3F!*!9cWLu?^W4rK*+I-k6Ajnp;ur5{mVG2f}SQoS8RJfwn-~^-6C8e!B$QJI* zWgk?w8janZdv`W>7HG^}#u;=8azO^$ZMNNpR7~b30qt%2$&YmQ<8arT*qJxgColm{ z9i16VYChI3l3mRWET$`U_ga<7>B(QWQJ(Nj9JkTAYh~E81!2u7M(p7+UEl643+{na zys+mWxSRPoFA(LzuS_C#*wzQIJ;qssz(&{B*$hKr$=WDkUCMt99ksrsioVa!m@@xL5dUPMhT3dHsz8&Ilyp zXlww)%4n&_+ICkOuLDPCANLe`mA2HP2FGFail`W2NQ#DyQ@=V~ryg!Td^G*J)AQFl zP1Pqxtcy>!q|U=)9SYPEG9`u*h&fIZR*UxvAZqyFXY|5DE}ay8N9vmyYh8pIda&~& zE3Vh0wpfkL4n^g4jO^k&^R>PAN~gyv9%xFObf2B_K?VYk_niwSa0Cw@{p?Xh@L;~m z(cy^c&^bA4LK#MP)$G)o32nkcvjyrGv3|3)`J_ zwpr};yZ~Vf14pNWFo!`L*LpY@a2yy7w&n|p)R}v*I5;pmyB<3FBG;`d(M33-t1hXH zzxc_G%z~AhHS&tiV?gy<W78oIDmq5ge`dEU_y$R7AeNe*d3| z`i7zDSHAx}`Y2Rtr+@bC{~3LS+Wi2>^hscM{G?OmhMN zTDh#@HYLMQ3=;qV0bZ%|rF;jnAv&COB6gr!ga?BV2msJyDu%O;8Ge({EyA!AIntMe z0A%f{tmOy&35(HFqiGmr6ddiFJZ+0H+r{tOKWj_vJ&#$Q#P|pV0hslGeJ}0|3k$ia zPk!V6`+o~kB);XtEC$4)P$SQg!76g?#F^jEX_q~%&&=1ZD}?2R4;HF#Lns0y%vz(N z6-~uVKNq547)HeYi6ICemR5PP^-)ItE-L-UCutynj)V_EUCUIO05(m+_|NM?u-ef@ zqg3ozcmu&14C(?HqWz>U>L%INIK|*P0D?&`1px#Sk>tdnqIU6p>hRZQ2-*YL2wyM; z0FW7E`l*vJfLrdr=?nduSdn2{tbJD-`ce!638y&(5DV4)80jfCbBJ@YeE%)?(C1B- zgJgiw2%s#O#pR5FA87iRb9rmXd{ zk9YsFChZ^!0|4OVh7C_qmLI65QY}Lv-2m7xdb_6CGx<)VE9#bMQCSBFnz{yaC`u!i z0TjA!c(qzLk5Jgndf~gxHHaqX1?dLf5sums!c&E1Ln)4=USQ1}u$v}n=#UT@PD3cB zEs5y99X&8)5>jG(5XNjUjwh#%JCfY|<`0as^}+h*m5fXs@xZAu!!|)C=!38Qrc0bc z+z1>!7au=CcGeo2!a3twJLA#+rKJt@O--1(iJ%^M--FvD?OUtp!LzfMz5@;8WH*jN zgceIe^*lv7bI1>mpZ*a+ySb*^~sd!+cYMB-Q06?zkBmV>fUflvt8?*BzSgUD0RV~{ zJm-iinm+9e%+1e<9VOSK)*eif5vs0sEM?gV{nny+{Gn3wu)dD!&p1v2EuN411cW3y zpSMdDI!+Hx|F-+HULn(GCLupXc9f{ZJ|~hUH&^?`E(I0HS1^gvy+yGjw1IOFpAti5L^zPKs0 z6Fr8|=6AO564Y&{>N5zA7e>cVr5j-14V7LEr`I5-i5`leJy)E~>o6%9kX*ALdp=)# z*1;X|HP7upGv4qsvOe>rbALE8OgsIhUvu$P-^$h79}!`Gcyc&fx&2xz%F5bY=P5kUwNwWP$(yiVgjL0W2iypQtFkp04#8 zmB4XFsEW_$D>;#8QM@P%4OK!Rm|}wn&h725$6m0P7h1Kw?k^6Tz)IVk51Qp+&b8R7 z!x(H?7KU?fXL`Wq^t%Ton!~_pq12HLWB19tQbXm2uFB0J%#qbB1Ri0E%`P8jLn72Qc!(O7;a$1fO`hQ&}$NYq9fvmdsGp%CeNSP>bcPxsUGUC4rh? zT*y>bFSE?S+Q$9CJ`aZy?SWCqqtvPmU1_*^bDeJ38d+Mp@p^kTT+{YTKRm< z$xetpJ*m~-U9owBh`B7f^z3#fkPb_seYLlR+iigehBcO(A|l`h#omV_r_t7h5AJJ7VtuD4}Bjnbt`Lq^2x`4$iNmcHUxk7$<>FzNf5ADibAR2BoX5%DHtB#f!T09wfKak;&{JHvP6Us_TQvw1@JeRiOe9pH z0AQo<7{6DD1HQt!nPc-W%-MfdLJuzQ0?cfB4?&g}i zs}Qqc>>qj5Tsqj$%^7c|xVHMR)PMGLa0zdXt*N{t)QJbH*DK@4M(YeBw_86n_=bFxoW%+#%r3 zx{w3w4{k;#P9%^U_il7Y`B`(|@WPzs?xblC<1mJl!A<9+gX;J(*PyIz+<*7u_(-2A zX-Z#ZX6(~$a9WFRd4*93g}0^mJ<53ZNg?^d8Difqk(EU1j7ArcC#XK5n^>y|f1E?+QfSM@C!#M_yl<(w&Xn(~Eo0M#oeu^@&5Y7$Yz-}n5`#n%1OWmB(8%3rbWZ1VpPa)!`|Ot7>&mAuSNb zEY1@+MUZUElboJ>-YLY%h?`VdsDpNVO9;>M51Q_&39A&&=2p7~&+1%#`_f|1`L8;d zvA~h$;Pmg!_DrJAt}f57uDch+T+JW7u$}L?TOIm%k3opLjrStEpw#Fjs&{SF zdCJ)aLr(^ee5_Sw4AoSLZF$L=UavUZ9kdZi3GanY`X$c;GM8bQ>4N8KuBOwl4UE4E z?CIU@QPJHc<_-a2)-l$NHxyV&`A#v_IkgWigDSdZQ=ue8uxt zybjocUn*xeNynqDT6KCH4h4^2{PDN?yZ!xEr*nAb$SJA`cI=+xbbmdQUBF5%d(ZIt zVk-2=WM`p-FlR<)Jx<)z3{Qn~xFL(5(Ve;_3tF7g_2z!%1;Xc8ze{aNQ_x;ljWRBdU#895VhVr-5E$S>1?Db>u`G2zqc}33PYw z9|Re=hbMTC8Lrt03TEoOi0a*X%bnBjl;Abo9BG%bzX%-sg&aeid&KXud`Va3UwE?r z_X(Qc`Cun=zgbxmsx7Tex&+tfe9FK251FSmCV zL06lVE|TRUw0|Zr_|)@(?iVoJg0PX@PD?%jD!YkhK9OC&5{9@z+_Vu?^vDF$$2bX2 z6b~>KVOR(|s1ypFTk}g$BT-8N2I#qekSs|8OhPPxRY`a?ZL>!ofn39SV=_yH?WBXy z?rD+^000O8b_t{6yi#;x)qSVs7|)FEN9^!mPOOM%MfFuM+c?+dv*ZoYHpuc=s#RS# z4Dn&3#Gn}8$tC!vG>oM8_HDfs2qDeoDr!-sMr*rJ3y{owt+3l}7>2snDx0QZng&6l zR*q;6gSD*|1fvoef?+8d41ItU|=FwhByf5_9_uR%=Q?8GB6 zdlUvWgXre@&8fi29*fPYSUlzZiBQj|#o{UzXY6@f0D#hgXpci^ zD}}@SLNZg9#nrNKkgh#QtxJc})%|TDy(U(02Gq4fuV-bNsl3psj(JEIvqGB#Onal@ zjR`KMp%cWcd$G6o8)$17!rayNyX{+i$mzjEu_4>-IH`tiG`0w{{Jlxi`zpEZ-Ed0SZErY1Uh}kN+ zyLlDRR+Z#sG9x#8EX33ow9v4BYJ6hiKOq}0o{60g^qe8#p1A4Vx_Z@zp62;|W4Ga_ zcYtO)dGq4%GtX>Y{!v5x>e!T%WI;*MX*+KmbZa-|$qX zs7CCQE~&)I zq3u@i5jRqeg3m}wu0Yu%XPV-F)`=&RuAf79 z^~2Y2 zqMKH2W9gHSXUwoR_VkMbtqZ8+xVLsCnL0qB(8kqe(uEmf$Xviu@%y^kIe3sD`alx~ z%C{b}C+((ABmTe27N@r z_Vb+w4_f3c+mog<>PHZ(h_4iP_WEZpI75@$cjw);X^U}=gk6Z@V+XsEg(XXRf>MLE zBb&{wo!q50&DoKb^LSxOGeH!?SQqb;%=%{cHC~auC)R`Nm$WpAn=z z7$=6rmzQpT>%9kmPey~+fA}XlT_3T$WbTzz%37y4H|O7K>~FM4;Q~-x|JDhd zAoB4a|JiT5p=qo8^!GpbEjBpLc_)g}w>IxArQq;7{BFaxN3z@fzff1E<+wE>vGZpuPDS>_5dU%K!ktAQ&uWSWj3-4*&p&P^HYt+eXGW)V$LWsS(G& zFyMPr_)|=X$$QH`OU@a5OaWcrO|AKHzLI4saLZ?{8V$E46liWymgtK;r+(8lN%O4D zizaEJRAZijtX7mNR-&V312^R4!hy;m<5*`F^?u0BK7M$ZPrh< zI>!0-N4LD#VQaPRc73pwDSwuqGZ@_8IcT)c5suQZrL*CD%;i%s9_nx!OS}0sp?##n zRsA4wuO2p$yK>&AEPZsSl=zx)p0aGU?|qcDKCft0r+Y&-0zmC7LAmu)uZU?&=HY^h zoi`fs0zC@|IrHtdmbVo%A3;*cmn~_8bRPYHlh&KfTQ=hZ7ib!VyJAH`U`r|WS>bSY z?bY?f-21{E#c!`>FO>w+%b?c?cVPNI-qlb>oq%? zdf~}lDFE_@(5$Qjm{8oE1HAxU*op{fEJK+%V>h{mH@1U~GO2^$Ob5aosH&iri$3?}L@!Pp@fBrtq4$Rk!3wiwsvKB}j0 zA9&YYCUyUc5eHc{C&N)2(L>_2bv8Oo*y-WWFigNZnPqstJ?2AEgjhGMhYu-Dqm)Lx zP?ruicDhYZB)cjaa{4^BxBvhk07*naRQ~;odb;mH4sE5M9QKLL^&q!!MA`9!_OY=GQJdcF9j##gTu>k04;5(9G?d)l&0^&snQJO7V5vTYGjTg^ zS!;SEG%lQ1!} z;>u%l;5DYGq38Y25es-scGmL)y_sw?=C-}~C$nk!!O5Uk6!%u=e&kRZqlmdwyh9PO ziboM^58Rum-t#&eXucFVs=R8SfN!9l27I0ENCU z3=nR-Yrs2p?vGL2vIF&-%MrkfgPI6{fQ8@(s9+}1mX01hOgFOkFS(pw*JxQN$(?En zKYX}Pc87=_1NzCP-)Fbsb^ggNd8f)7&GbfeBz!I#hTFgZV?Pdf7zqh-35jhrBqVj? zHqb7M$b@fyXBa@ov7oDKcB|dj8+jI#TCD-_bk`7ovo7Pf<;olTAEW-62Pe;rw55IT z@R{ksZmkJxrjg#hRoUG|JA2trzo!rpT&M+o3;VEl{OSL7?aFp9|5Ykpy!FAmlTlA( z>`PIaJ9hG`o?{PmrShlCpByHTN1y%`k?RrbI)Z}^?;JP~P70>wRn+Kcv zgh~*Pm(vf7pcAMTNGNWYay0r%9i1BlU%_k?k2Sr*O9#R-fRF%hpodm;4$=+5&qm#x zSJ!I26a6N_YGiY3>)L_(m;ZDbnSeGLoP|*ihP2{t&afM%Y5m0(*fNBY+)fFmEX!cZ z4GsV%KzRs5H#J95WLp}NH^4e(V@yN?B-77^bRS^JBax9_(}n7gZ~DtK5QG?NjW3Du zfFs4f6FC2fv-$)|W5Z03CC2D5BxG%{l|_LA|HM~6`{-@pL`>bOGL9kLMH}sco%Ne2 z6dHW8qU=P0f4iQ4pJphs^H>MY!XN>)Nck2HtaLyV_i%m!B~3*0^~4Oo1mVK<`S0z@ zul=GHRaYRu(&ZX74Fl;k;Gm8Wgl=;Gt{Ry1K#hirB>+OdrzNj(^g10DzfpzgkYGk_VI*WMpNDJqjn24D1&cN9{&W+TQ2 zBQJpzjHWHt5M4*jIb|YLm&4T*@JL+VCOz#;hJ=1sHt(Pys#J!A^_2Ed z2hEV%60A3~5ES+IhfM>JTE07FDWmeOI8N$~j(ZsZ0NpfKBhg&u$E@28063Vx6mr*oOQcK`+ygk=CoT%dzXsS_y;HTw^H2PWYH8vZ9ypcAu^wAHVDuty)6k=a zRn~p)aI{^lDD=74h9lYH{#!z4Q3y|y%KB1ITX8eq!Ew$1R{7XrrfM|HgDpoZ9{ATg z5>)Q+wUY+Mp_<0miu0MBpZ$N6kzrzlx2Amuf{A|?VExkyMo81p$)1K|Umgj2kUjM< zS2SFGBfG(01ZNNsq5FQxNNMB>E73ibVxs*lD8iw-W@~hXY zw+rfesq{J?$|Dw;@Zo?5=?YsZF9BhY2ZaFu=p^N2BXHamG))uC$retl=C0)Un*fHs zpFh-8Bso{snv$-|T(?5yi}{SsKuaIt7($XZy2e2WhO$^ zHJS1fwJJE)KgoN@O5E@}hqVfA_xW^DPiOAky3r~=sHttORMoTV99$B;@hZ{g&Yn9` z%-z}pu5afn2yWycwyNMpET9RvhtJhBJJx6g&e=yFfMhk+bj~muiqc{>;bqV>d43R+ zM@&#E=asit-;NKy9LOf^OC~RG!B9~Qc+@J-L0O|ywlhp;;X6pOhQ(^tO$7+&84cDY z8OAUJbBLfWm*M?Xornk6Af>fw%Cfn?muUCk786=e@uk2Fv*@Z9HNltsjc$1Glk?Jq@^Bme_=Qe!e||Y z0Ql~_l&Dxi$QmBl2S>O1KnCu&KKqqwu^$nK*VEw}@6GSNljy!+D`KrdwN){PwsdAD zfRISHMttn*`66sV9HvwQdn>7m`RR|h(g)aBP0b;${*w;Z5Nlmdz*Bq88UTfk4V?-y z76@^km<+U~v`pEW(rh_%4Z!JE@gbN0NYb^sEbE487&1l9ksR4R?EU1OcT}ZibGda` zx13wH@M-L_tGz#%yrXd$8?pS4U41^lC}5OB(dbP1=AJG#4lgHqU)^8%z}d@c?gB0* zj2%H4DMe2`Q%kQ;KXpPbd^eD&`zBAx@m#u1jvoK*Bhz0guD?5W{&zI|Rt4LbeEg;G z-U+$9c5?Woi6_4zxHCt`zM)y0_SRu<=Zo9Ybp>^LqURrdY5?QI000EqNBBmv415R| zT}-Aq`^`t}52LDy4Zai;6G?G%kGZfaXqifK^O3Lpan^QAvms&oucZ=ii*#|2`xV{L zs>!*>zw|rKgwMmCfLj>u^#;>>o!ztB-xoTEbZ`l-CVqlg6@)*SI`dS!-8@i{n=9XG z^H+9!-<2B@PPdh@J@YdjX%qu5j$8eMrd06G2*Sd3TPtz&^MANUEVTsY@vr_ROSw$> zz%_IxUA!dQbLSubBWex>>xIwFexv)zQ#vUH;uln3)mBpQ^7KOanyA}*W+tCHeFU!A zS=BmVJKJd9G<)X2jR6wL_4j_!m9eUrj!kg<-3AJM5*@MaHTFTBMEiQn(4OG4vF(wY zRw(MW(}y9f8~wGDi8MWJ}+y z?|JD+G=0Q26e8KfL9kHWyGvrRrXNU%a}oIbiN~ITTg#!)%e;MUuf7>Ob1oeGrFzK+ zn#Xk46>|16Bt%Fw2ia>(#5+!f! zV-d=uP9x^~t!(C6EiWB^>i3brJ-C!R_rf2TDIqXZGT%O~z@Aht?8Dql)v5@sXs2&Z zKDwVznozyp|Gs+d9lbHBSGjf#k7@`>!#1T0q{~`cbO0hy}xzWAVpel_%WKCl-`;^R_=)czf+_QT=%4 z%cm9YJ=2~e$3B-TLAp>MJVqQ`dk+@~4X{DR3jGG9p*J=>Xg@#`!ET1UMvXIhm6LHX>6AYQrDY!poeYp<2_ zR{*})N^igJ2|bFDP5=N<2=Wnhmx~?y%{a!P001a0jTbxTNVf|;< z8u@x%tlzj=+!Ty<5{3x?09@l%rK#HbII$#iZCEz-wN&Z)Pqq!sSj#u+u*H<@Hs2YW zcc2{Cg}g+MImp_WY@gMZ%`)t}(04B15x4vudGifbZb<5WW4~jdRe5ko;B$Sft6xZjkGPenA5bnCwR^co1NzU)?uU7ST?YNfDc9PP#_7zBe93qhzMk)k5) zHgb8XlMy<8mVpSDm<#~`fI+bT5C!*X7=?r9+|2|}h6x72G}9QgIJ_{W@EQ{!J4mpO zSRmYP!Z@G54k~TYoUd0z(=-48fH8=r@Oa#TcHwr6Y;;5mfEQ)Kh7vYY(lr6In`AYy zv%e66`jR4IMRCSy0n$pBM!kD)f!wQ5r_kg|#jq(f6`$pdvMi2sECE3P0CY1}i+eEC zhxnp|A0AV@1zt|^m>a5(w)SNklBLypZ|^S04(YpZcv;!7B(iH35}+SM-4(Rroc;iy z4}J8TmRo58+Taq2Xe7-I-wQfVTS$9XSFjx!yvOns5ooWbt(=ppO$H_r@LM09-?{u2zX`6%4i;|FD=vx9pPkl{rm^~7GMmt-NW~zp6_Jjl0Le^hq#to)?bUP>aDhrwRhu2X<#=-N z&1)OZhUp1#fG!_YnjpM`SgRla6!!0^+xaG?asDoY!InQ z+1Mw8rSS0*Ue~z8k8k|oV^`vbatX;KMb*>o$E1a7`er%X6Mi~bON(jRXR}`X+ZCY- ziJ7cLUDw|GX+Mb~G@(-G8KEAdHns|X+v7ql<++nzdAUjw=vKDp?DKbiyqiC0)GEi7 z=7wArhP?pk#0hjYvG9SyEBe6sWGid;pXo zaaD$Tc_16Lu?q!A)CZ)@jgaV_v-^;_4}KmBo4Fx}!*6q;BY36TFxJ-4@0LkV(N`8N2@1=P{;OtpmC=w!|EPzv zj4=DQE+S4ANlkH%Hcy(9V^9aASO0+M+pEMZ(5vX$rGn9WPufiN1=~PmY5QQY>)f+U z3;)4)eq*CmcXpq9>(BoKHP~ixU-i}hy?Z#e!yaASzvr+$XS1gN@y4GI3WfxaF1CNz zkDnzZ@Zm>)snJ8ECI0X~Z==JaA;ged9~!4fkww?v>DbTINN4AbKYlIxC?j&7_4ofg z7CeeG)U|j1^xW7>usyV}@^^iu({Rpn_q{)GIG)68!MXgLqiY0F{1xjvSMPn0XWUwM z0-vnYY{Gv|v6X1k-ahlpL~>7McKfWt%qX7+YY_%Lt@WKliWb{aZ~N3is%ZW=k5R{vuvffTrpVzM%89ATGbbvA-tJcWShn2Ij=V_ z!Ir*3kJ1n*uk7gR?}hqyVR>L28r@phbrW7k?+eYH*IFRjh4r`K+bQq$CV93@>m9xl z9Y1}T00qgZle<7u4tbvk_MAEh;_fwBA;HMS%I2gEvYB0PW1kriY7k~006>iYEynf1 z=GE_O2#$dOeP&LBS5!3eKl*-TKrFF35A+qIpD*GYhMK;*D96+{EAi-5>21*WJC{ zZ~X1=0#187mu@Ay+jX8`S*Vn+gxkLa_wW;kx{f^_(zC6i3{zv#uMG!-pq4%C47yPY zx3+rYbum2vAx#rT>&VlJZIx&}uG~&XrcRrdy`R4Gt|}`a+kNldzxFxD0lKl+_^UqX zDO}|)zIw4$uHbh6&FinTy`--B)y-UqN*P@1&clb~C>rfYz)DE1>l{e{0I>CNE9M#O z?hg5b$L)i$5G|nNPaSvo>*_{mU{p2Cnj(p9`zHEmA$MD8KwkChhpA{|(c_-r8ph>G z$&CP(Ghdi+wr`k1Z<};Z1-$3K{L2k?e<=98R&uw-woC*-YGYP!F1vljGAi-IcUz4e z2_vF0cvZSX#6%s4>!wjpY#SC+fbSMI7wu0+s?`d}5Mq$uTwV*G8rBGCrCra3hY{=h z{M}ZkR5wjsmE`sB773@EYp|YcrayelC^}s48!p|~Le8=Xu7gF4^$X;*W|@K5w&eZ1 z-F*zuZq9!GCA2eqZ{t#+72SqLcc{ThV~bF1UMZPV9oD=lNGqO9rm+DQ^KY-xanNEx zwOYrSt>o4*x5Rm4p3ntZEd3&S7y>{iPCh;SYr15315X10kiJ?bqqBZ+QA>Tm79z#cYbbBnqzXj(>W zm)0BAwPsUt^R2@=9ovU06P&{xj=2J`y#n{?dBToW^AGb9-v{P*?i8s8h+#y=ZrXL;8z(^~CrQoau7MVu)*q2OQm}9_1`)tp){;KS_AogPgsH?`Ce5 zyPTG+EqM34H${0p2goGUv#@oqtcjI;PcfhGKWMMSCVS{ofP1Q~$E8}ArhSVpYs$V@of~}BNJ~IxCwylj8*=T>F zHZX|@NBV70XjsGD^}`I9`P^7wxVDY?hMwhw#QNn|MQ1;m^ne|a^tT&X;XK_1L$-pT z4ED42M5A;&w}*{g=spEo1QXZ?7#LN?v?~u+`%>UuOE_uoIrp+i9aD)lOYcsAAQb~i zZdX>9cFWQ`2SSf5mO+yyl#Ef>-`Fl4wu)M6Hg7-&&Z%d{UJ|H~#+N-!-QKE7{u{F| zoE&n5+wD1D>@3Bi%JSM{FaEkoxines$emQHzE!Bwoz|7h{|D4v2vrB(d&*YlhH_x5z>H9(-V0L;>{W2E{2%Q?BmG_puCFnwc zU_1n6immbkyXJNR0H7-s-B2JB(gj^8N~+qZbh2TTF;&yR_Gowtg>0agXcL;Dn3Agw zu~i+=Nm0f?!#ohN6)zBEb=epipF(lQq)eaN_A2D{9kWCOYJzcH=QRzUYe{^cl02y6yZ)!|Y5J9kAFFs6d{R9NTKGp^Spk4-1 zAga?42((PoFboX<08P}zvaD$Zf<##eg~>AK_n3lJgKbC{7er0Rn`FR*!6v4+BeYcl zAZm?_4o#?P2Lvs#*chOR5<~kY26aJCH&&w2vQ$y5o{xc@#|Qt12rNhZxVtH(RT2gq zLxQf6x*{gXk{M@Ia|j^T5D> z9+vX(je^BB#RR%^U6EV8+jXR7G$EjMxbee!`+!9-KS>)xqqA%WLS6)dL9?N2JVX$H z4ye4&*Bfo6(2a10YC^=8g*lFc3}EAA7sS^T)+c9kB{q`T~wBuHYab`u)lguw}Scd$k|VYx19> z+{Msm-^M%r-BRu0-7Vze;gOx2X!BAd*X_IXy|=%;u$8DBsqa-j$Z+mF$9FnXmX0RQ zyLdcMq?r(XbT`aw9~6F9N~LZqUUJiM5=wC zvQtiYDyiNxKonG9Hq(Xf2><|iIKPwe030?pI}3oYoLW#qeh<)TWt*M$rp~*rXyiZq ztA7tQ%m4Y^Z%BnVXfak0R|DHQ-i!3O#eT>Q4j?9Vj)~%H34SYVH)Ff)-p2tO;|8) zT-M0o3Oo|~+8>>@pm<_$gRz(DDrzTe7+GRR5gZsyn9Sbl4T*eABkiWmRgzQWNJ*@% z7~FdCFfCcey^?^dyV=wR>IU`payp%ho_E1&`oZ@fm>fjNYjWaQjNZdN;l}+gIJANL zoTdhJ^*><%M(x#NmBJbOZYwyB) z;?x)7%ATegnqBX4#zCWggoKgPP~}%=U!e%>rQ^p9bDsjT9!toDXKlzZioM{^zO&ZZ zjlu3?p}e9mjtHxLp5dDMiG|J2l-|w>yIlfNV-5+NZ3!j!=Qgb~1KY_et3l1?x^r$#5K#BL^1w*R4@UIe)F3x$%qBRt$aG=DC#5$xRh7 zZ~y?B2mC)1t$rc+)agfB>bsja^8o~L1%q`w;dQc^y?UnEc8*vucU6}`u~7#AKq$#F z-=vVC9@1i{9T~!4+-45cyzR0(fAjNK_D`HtD zA*k2Z?^CiHmBh^O6IP5OyDIJCfYTcGcAaR*qRyuWPX)6?wNotPHZ&fxM|%VJS3AdC z!GkL8?H@XfZ5bZism@yOXc8TJEq} zuP5`EIMeZ&0KCICKoGG_I9uu95YeP8@s8DOR66}9kQ^u!cNzmR_xyvU3BO}`E>BV3 z$a;|R7XSbt07*naQ~*zsXbp;xP~E;E>G^uip*N9NV?*1ZdI>w820&w_~LCKZ+gqYRW)!{k=fXarRi7&qu&1 z(iv*F)Bf!a+3z~C;hJx5#cW~Dks@igiS5WD3;pcXe`v~TY;=&W@3N8b@{ON`<7X`O z?TzhqEM#%uhs8p^nbHEMr?AL`s1>C8xc!I=)=7zyrFz#*n=BF@AeGHwb8RuTfcqf zwc%su4y!@{;Xk^(aANS0qEAv1;Xa*8q3P7kTbx?y44?B*i)|)wx)6K;isM2Uc_>0VdeXP%ET@>l~_}5v+m)UbiT2< zvlty8oyhEhl&|3CJj)-}xdEE?gf=icf}|YLfLdtL(YDla2Onx3s+!M4#?M+~@tSYn z5gA*%dN~w0#<(fh=Js|MZzslo_Q{)?X-rH^@9{r(joDCS@a3auhMutw`*VBSMC^;P zK(xGTmWT<;}jGmHWZ)*R8a+wQ{w~I1ifMt@1S;(<&FRczFjD>Q+3{#9{k_e=Xmop# zUeiBHnuB7v#7}>8?PljdW{r+&>KpO>P+{yRD{sFN8FWwBe(>Rffim$iWqD_9<+UpY zXZk|j`Bn}tI#8V%IYrTU>~cA!+tVZexQ(%~^ZfIrBDPMGkvoJKNhBgVTqoP)ItIzL)PyT4U@=kC$Dg=x5^necU43rsxM>Q_ zt%NT=?Wku=06D#0_$2X=z+l*3(R}Wnt~2h*Dw#hDab1z#1#h9<33r#WytcCti#DJW zUhcsqnhz&BlKbhE`5)|cQ&ILbC*S|58$}c<7y-2F4Ip&XiFYP)8f~*uf#8d+j@TC0 zIq0ktx?Cj(>#3r|NLI?av-@6m;44;0FW)&38V6EcppTs7S3d!xF0mvBJTtgOuqM{I zS*~9eSjQ8MP|7`&H8V5KB9Zsb zgN0zwHuvE^=$y(M#3O}tfttxF=^%VGlP3f52w&4?>t$8Qp?ENw*i(;@*n_l$aKnL; zYs0O@?fdJQNcT`ff{lDD#{jvlT?^y3x)>DnIwf})mc<6TsqKyglJ9RdL0 zBWN!{qX?ndCqRIxrWgKyp(_9YAYO@5(8w8E5CK6DHTa^mnkiXP{FJY2_GDOUcAU{} zXW%3RV*mhjN;xezKY<&9uGUKr%h{XtYR#m=jH?S`LV004k-$al;EfPhev0RSju z+aZdJ(%b-RKj#i2Aaum;-EEi0IJ>Ti>io63b}d9jBJopUi$G6U9g_ewMQ#^Cse&LF z1^_@~rKM<{(_Q09%d{zr9Uw(eUaNH$#Rz>Z9*P7`4FzJoN{FavwKd8^fH3GBwtx_b zAw<;C8?|-iWgtphf~+T}Xja0)n}~yU=7=!qq)g2WOb$_QTvvHJiuBK(5UXOtH6TDF zjM8GO0wc6Ug2&Gt?HvsDTD<@O^f0zZJs}K28l^=TC7B=+pZ4rF8+=O0?ALixC)p5! z(Jo7^|tkO$rC0{qR_pEk3=G^jj}m2HBj6?`dif-ZL&HRi zNb&7YKHG60zE&+A2D&z=odV@ML&NF)pDckaC;>wIqaE79Pd)qM$t#RCTD0^$Pq_1N%{+fjg)f{fXG+@Mpf_FN)K)BfKO*?`B zAOII02uZeQnn%n_}P{Hlzt!0 zZC`IXDnx~R-EOUE5*@T{TW4tqtji>cZ3wMofb`G5_a35FaBzKnJ}%7zHmgmoW@^Tv zlRsus@{>=$utTh-@_XyEGi1uq#=|y_gb+-%_#qU63CPU1^I?*lg|FPzVjQdkr~)fTk|XJ@KMG&eEY+1#}OB1@B8fTf1Qjx zr5rl0U3x8OJ4rM8yLbN1@WZ&HudJ<CHo>D`CQ zk_FJ<3xlsdlE%%jqQC4}4*g@;0M;}obVleBPUS z_3D-PC;$ZyG=O$!OVhNXL?e+hD~&X>GaBtkBWYKo<;2LWq!>|RlS9vDv&rseH@X{W z1MjK;l=tqrdfsQgm)`7$mPpNR#O_YS-VYg(_r$q3@jwm z%%>{hBZgYYT7MZ+Wzqngw}~qr2sBvx4xB9l-7A|VxZOc~4{V*+9p*OI&O(K}nqC&q zoD0}{4PZ7D>FBsA2Ocry=D^7>JoQyC6vp}(#{f%vxW(R{XEX?)24E4mQ(0)vbw?MD z;|%UYD|`Mok*k+=!`LZgQg>5o?pyxs<(hX7RGP@;i)@;8*Iu^5H_dzu^;L2Ya)!Wr zq3w1t2bnN(>KZOSg*ndax)VaDD0bQuV=Vb7u(Bxf%Z)?ZkeX0SK20XPCknPySG4Q! zvCsa!(NCb_NkGVl`k!eoO8|g(i|NsGQL`bf1m~Xly-&e4bHeu7R@)^GAerHv&DnR_ z2H5Db;gD2|VvfMQ&E?B{6V<$HqPW`@nnX*|fP^dSgvX?z+kD2D_q3P*R95JaN5Jy*9-uCYDt^NLbqd}-^xSTFtS@$iz zlkMDbzjiHv(41ofRvLDOOPmlqb7d>Xocv78?rTI^m-bs6>Nd=IU1;JPR!pQXno$=0syK~A+YLrGSj z6Y4Q8i5RY-p-%o%1@uYOD&!xgAO~G;E{~kgx@BAmUB|T-0)+qGHx^>-r5>83LeCiH zKI|yUnEhz|Jsig&D8;}rN4^y}L>lfb429ga9yYM2?jEKFR@&_~ z#J!*0{qB^Oc{&gW02HLoEBjm5wk|Kd@!vM@y!ihYT>$`Kqj#?k8!nvYRHeOgo3LY) zmjDpdIEsLd0Swv{g1|H_Y&QUa2~tMTl}DXzP5sb6u!)q!3PK|WFd+y40KAh9obbBr z@h2mr7!1pX{y{nOK`FDw)iMGfrWq3eMA=7B7y!_erE0z1m~n;zu($tFpwPKn+2Ak* z>?q-D8HTP)#&Spgpu*hmNHdw)`B=iY`kg^q?bIRFp>14Y@QBK3Ky24x@dwlJi@fD1p{Dc|IcuWm({}j7<-D zwEjRI#!SJS!Evm%ecv_REFF&cyN_)J9C4a~0N5A#O};^idAs)j6EkQZ0W&7uZO+S8 z-fk>z7sPhf9XR9Hs+*FDK}d-8QvPF0>t%$ja_v0XU;09l$R@#;~$4{R0+kKR;{9N2qe{e_d zAZBf)Ufuvm49Diq96n)DGH_>Kn0acU5V2TsLo==9bo9M_*l)3`48b0(Gj$<*VS?i1i8x^YyZtPCj8tbYjtuLlZ``gX^@=gts z%#@;;8!!Fv{=E+(SntN%%GpTQt_l#5F1{b|>fAc-Tp5bXLi4PTRbB zcu!j;dQLoA-6}fbKaAeJcXja_DxKc*ijZhnF<5NwjCm&*6U zG-HDjc6hkCx2fpveQ#{_{fmys)SYW@g~opu2h?LjH^uFo~c-q!Ic1kGAFlnbZMlrhQ@=w3rbMoJB-+3$5^?(#c zHHk;!7Nfd~Aw5ay(&&*tsgSP^(4VehTZ9t{niq=LhKVvj1}?rA-2$*g^sy5@HVAa> z*kg|Xgf=yPzqGn9|5!E*LDv8P2*e$UpMp@zw1`4kGHkyPlz}7@0Dw{m%v(WAaTq;- zMS5Qd8>(sGZMK(&G+L!wbvJ528jP~X!jpz3A{;gK#3=<+bTTqJb{N(r!%75>xDWyn z8(ZOlk7_9h6Qgv~8-B!#C~;5Y5Kv5|TB3d98=K4WIL$4uu#t0yPXY?36O7JQm}rdW zk|FwYtNc3zMp%dm-6Eg{35yQvPE6h{A)J4}KQ4D2nW5Fl4A4nlN#K`o$MrG;tQA2nKu344ccj!EQ$o@^`0H&b>825ieQ5jY!H1`&xC`^H)Vf5p?wY{QET_n^y^i&+hSl? z$Rk#*>YJCpi#l@KbxvH5;A*|R*F+4%u5J?MJ=|=mO10NHYwLQ$GxcrMJEJ?~u8q!5 zZoDcNXDY4R;_{*mSUN`WZ@1?qLtkzcQHQ?vq5_o3eB}!V}94{qb$M=Olzpn3;jKIv- zR_Cv0KG;ZFoDcekAtL-i16Xa*7)-$U_Qx=XwUpWlANsclAU1NR8vaMf$0m~!{l`xF17S6|< z7J`U25Y(~}<-6>v*QceTX6OW*Zsa4s2H3cGgc>|(3jXjwV@gW*s1zQn?eEi}}lv^91Ac30O~MVWjz`+?1JK-iX% z69rvF3Bt}b+X;i`g%yUrDE4A?@i>9HEXRKb;G+wnNhftuM<$~K{cWmJOSOZOBW*!# zQDoq$M6H;SdXB2to0>kJ2=(mv^~p!O!+ZP9VSFgS@6Xi~DASw|J|yA#O1mxhMIM2V zw~MZ1J-k%sw;jv3{v9_TF3&ZVU)Q|{yBw`#MkC>bqW9g(nduRp8$sXFP4MLyRGfr zYO2GfIvfB%t{YIZr{57JtX&@-p<|e)0f21inqj~IdeA8KPJ%fcW1WNBGTkTzxNx1b zrkmnb*>)#-y3gLgYsFa{j_91Vve>kGrh4lZ61V7@q?w>oky^DSSPZ}{+0koEAI&0U zy)=Ks>BmPX?*WG{L6~?ThLKhTo@D4l3}Z{R!C^{wLs>y+s%omd^i&|m2{j1QnJ|Uh zFaQ9?plrXT*``nnLPqvrxHvXc`}nU+_(n8)*F;BJ)DUNIz{&(^KWXW=I@6Ukt33hX zVsotxObI6W!!1{M2Rk|%ZPyAqwY}3Sj`WOoJ8j{<9*TsA+)%qku5>!H`E@bVfrMxs zq9DbrrnTa19U?+|l3UOnS{D*`j&OB92N4M26gtJ7)k<{O`QY9*@a-;(H;UDEu2EHe+7)oN{Zxi}kcs@NLk1DF5OqXR!cbwgEMB~1#}7Ht z(849bPbVy!N;x&d7Nv=!F@|4aI1Szr9&EJfa*Z8h5zJy}a-)XFOAul}`Tac?K%#aR zZ%|w7$))?L%Zm?!PKic}u@Om->&{4ak~NC8HZwgQ@opacwW&zfju80t=RS5M5v_Fe zfNjJ;L)Vg}0IKSa(J{Ll?Ne9lYnC82XdmQOKJXblZb1qqKWtgI!u|6&5-{fmrnKu2 zpJ0J1=lPbGm&m6Su6StPb$|&a zTfzRSJAlMCh*L+f-Xm%*S=8lpDQRYr5C#XVUQDhuGZ|b;;!tg2Nl*X^#lr4)HEz2- z@Z`t(;-KfTuV~f*#;Xm23$S~Z70mWMC@(L$y;H!zb~om{uHctuezZl?VT26Ahs9jxt;SmOdhhrP>htq`q4+n)*uNFONR)C`2!N zW3e9S1&t}1LuMiMwi0c$uUCWRV+PYi=Y1lUbqtOl>-$tIvz+L@u(R@ywdDP1@JyO~ z2kBtr2R~vPVmjz18+6OeY`yrvZt*(XBSLxS%;z3IcJ3@-@Zh--lSXAZqw<k*0Oig zKY&803AnSri~B`M0vXp(=HGO(*vIj1bCS*L5a8a_A#No+qAOTXI9iv$8*}f=+q+gQ#;X439Tj_dovIziSOxOqN9Y6R?SNkYz=X zR7^BAesRylb(klXDlgJ!NS#j|7=CW;>t$5%w7&jY z-=`z3REvf4zJOheT0^n#c!P%6YVvn?bS9`UnZhya5e3cIiT*25EBVK`22mtD_~4>`II>{J^VAU;ZT5C29_V~ZdE zOn2%=$*mIHMvwg6H>^BvalYH&B@)}GaF6Jdupz`Y{A$~rl+i82mR0>(!gEzO5$Iy9 zEnS7^c7b0p(UuZYWUb5Nd(v!nYo$6w_X#xIslX2Ud58A^1c|}EvykD25INq{qo8qM z>Q+W}JKBuI;6}VYR?%2>-^Fe+9exP*8mD@>j%Kp=GZ(?6WQIV#`c5sNC9* zUgX3g=l)OmB>^>(!_uvK?~171FFd?eU_B34Z#E&j3&Cw}>!GRNPTac#O9t77%0-^J zzYL)pmD0#TH({su%hw7+jLZMDCu9lv*gd=Bd`riePO~XGs60TAj_iid?IJ+nR zlLQaD5GRC2YFOeVLvNVwA{T(9d9U?2*SWg0cp`oKZ??1ZDGp)kMJV~o-O4SLtKxoH zVS{97@!+vz4yvMq+AtGJJ{}7C@iVoR+S1PsJv#iX-;nQIJN)I*CbUx#UoV=KOk*~= z`Qrf*PK~I+9FBj#ePw&gxp(*aH~*q*6u7SapoN@qgFDh@AI0jnZ#i1Y;pNv0#)gX4 zy^?-J^L7=Si(uHGsJBTBD4EQLPksHZmpyH@%8h<=eHp-ubZ$lz3XHo8=C^OX{&qo; z$_m@!GMKp1{Sn*hn{TAozyBeEJk000ESXFUGH&Yy#gD{vIUS=!p4dZ*|+==lE* zSi`IfgMT5;03((pi4H0VRgl^^jF@v``C+3_;_y1yYSaxG0>IQY>BIll4O126{k#8M zp$t>ZT%#0c>?^I>zudzBdPQiagjETq z3m$P(&h8eHA8hDpS*_YNRp<^w005XJg-8Gi_(eWLStI?d{cs}WbZoZ8&5kY$^(X)U zAOJ~3K~%Dt6Wg71y;9?gQipYndOVh6ilZNxJ|Oloj+eKulo~tV-kZ;EHRZ_B^=6uH zY`Ji%;R!~@J)RLi1Q1Q*0RRMv5*=7=mOW%QUa0w13R+$xI<$j#DB`AE-nY(glD*WB z#ZfU}5h7$=)iklNeZ^)c7gh>t6B88Q4&tW)3L}sX3Xca86;4S)(PDAC9KOGy3Txus zv3_psNC*yey!|z7SaL>6%)y9v+-`b31ifD=lbxJ|h=B0zH;S`^?L}N|02R0in&>4E z#81=i5u}?!{ryTQ&uk9)Cf!|QxZU5_DjAYe*t|!vxLQ$NIJtN0y>Kq&s?8FfJ=et* z2+hC@YCvzj^A|7Xa84tH|MI=}KPcb0b>sdVw3?^XY?tCQsbIi%+!r2ldLi64%9tNz z<495)bPYEXr`Sk2oXGYa{XNdRpeD*7b{cirgqfwr;o~8!)j-wpshHMVRx86+Vc(#4 zEyZ~WC+BRfEP!F5j-J*(py;i3MnkZW?z0f~^1Q;qpS<_tsklXB?6b&!YfiMoQ zB!UzVJ55mrx)wn^@j!t?>(#-7csgNR#p8ta6Y z1+(q`?3bn<+8Tx#oO|OU5Gn{%g}jSs+%jza;?m;P7w`UKfA>>!ufJjvtwGlXeVaqe zgKfODS9&E=-=&$*&3k`^BX$5lz5jhs$y-pLv|+S!q9y9xxPHq$Z7~|EO?{+dTL2;C z){oyXdpKX;frX!a&lx=>`>V*3NIANE(UTXy_18Xl-03;Io&TGFe%R6)`~F}4o{i|W zM@C-%@t+Ew0vm|7idz+AOJ<7qiLXI1iGma4#|qeOm(AJ7ISMdNF!`|Ge=uZ@BRPnI zp5F@o0}gzSwKx(&i+#7rUDxK~a?^ENU2g@zQ(6}`xBaqnaGJ`Fzx-dnx|Lg|r2e=5 z{zcP`Tcp#i_qJH=sLX8tK9+Xt8b zm;xxChBX_bsZ$Db1v8)rO;SO~FVd|!jO_b}G)HX+;jNH2{mggzNj@9g3 zszca`cBKe;WworL;_t-#Pb!F-e^IWFKNjb7GrM3Ddhf1zi%&S%EZfL+bv{RV8|H`CSqt-7fhpdYu#nWUO#{g?4)pMV}jC<|a260)b2$`wLuptRDN zBMFQ`KvDA>_M6{@%rs5zSrYfrRt$3H{WX)q_SWZqs@VUaBW%FbLyRivw4$2b?xBN- zZdK%F;qEQkTW%HC78V~iQe#G~Dw#DpYU%7X`^uLQ)ArsQ8$AhY#$pZkeLGl?Xf~s1*ESiSH==aTnr`Rb-qWt`SVZEhU^a0Kznu;H-{?#@-|JxQ2AMVnVa4)A;3mG`Rgl%-S7Wim~z zs% zy;-n01O2j;lba_r4%^&zYiJtMKv=;s7O9i+sjf(a(csiRhr1Qr-qBQVgz?8&%17Xs z2V__XbN9GQ3pFq>DEz~G8(xw|Lr>7td4f{(x>=JsltDOStRaNUwhcemstAL!@YZ$Dm7jlb)zD=`CxTvtx#ECuHS!gZTBHDOGPT{QhuYnNvR>ZlUwh_ z944cwOU=pTr3T|L$}=CaF>$8|0UleBrJODp1lpy%WKq zZRw-YR{Ox=ugJU=7u{ICpICMAt+d}V*6SM`!d#Aj?dOkUlInENqrfzDp#|fRj5L03LM59f z>Pk~Jpe#vwZKxL@z%|SYWywI=XcW?(m2zjHz&{Uy~07J3Sh|E zMH}p#TB>3f-~G-{|G3z^%}al{znAh%w^0$(rBbJM&!&EG>eA0VGGcWcesHO1Q-5}S z?d^{Bn*{i?9NVg0TRrrz`$enV-A>7J4eho&>8*~j4IxQU-+VOS16qo4HqOL#pL@W{ z&6%{+?nIr>E-b%U!G)~!leZ$lDQtCr=NsGG*WR8u=m94qq9ySBqjjsN;XN}oJ^rKx zowB+|aM$V6-v1@?!3`Id(~>o_S}#bQG zWQn!W2%&(Dw(Us?_s+lfK*wCL*~xA2GG;fOM6=jxM;$~+lk%(9F3dH=DtFuJO3RQ< z?k6?EY6So|xQf3$w1~-Q$b}3tPbbAy;HK4^xx*Y3rP%+B3ZyIs4oT|je zovF8r{UK0rp5LTGURPvp6v&&%moDSS|2zKJt z0`5YbLG58Fy(d^DwV}baT3TwgGP&|T8t`=$TSyRvsydo$q*xn)C#c+N!!U>_9MDum zl^Sf=Z?~okB3aAsclBVqyIYE?<2DSV(L{r(DPos}4f+q;T|+Q|m*o_^Pxw$Ii<0m^EgqQJJLq;neC+4Inv=aZT*S$`DSZ)I@(pI_>H8aqZECLa~W<` z*B;(wL&JeX=j-`ZJfErR{mhY8WY?4j#>Ebf>lo(SYi8rF!sX@khVNu|1=4dd^+0w++NaSzQXje5b1dGH$Cb$+0{gil2RKLT`Y2*s&&4a z;ts0TnZ336Kof&tjeA^eZus0iez>I(qXGZq&6#&2tS>LeVp|K?^s(H{l#@-*m(|$G zr-98;U79sQLy=_C>9+`t{=hEWX3hxGg73hSE^id>%34nZ0N(~H-U?r0X|}`5YGce6 z45ZY}z5BVbgO5wQ4>@J6H$GBt-B{0M2L{Jp``VvOJ@Zi*g9?{^icU>LJ3;frMqp>e z;_cNn7qE)DZrQy1gTCv_;)y{=^Jq`P-j>?Ey-gdCt9#c{~Th-i5 zPxt7hul+^jj3>rSXBE4%U##9-A-aqral4$#hT^CFJ#n&PBYTe+{@wYTKkgm5Kvf*A z>b`GaB;gy;P9>fA1w{1MIyb$I;W9BVDUB}mkYj@KSw9)TJz4X<+tqdJ-5+)NC)8Fa zRiEo8&cl9ydL^=MCo0Zz-&GRWMIn#dQH_+W^bis8w==8zd$YZVKB-$ZDANcX>p|8T z$1y*-+n=1h$wRrI;}Oc}sw21D&GS{^M!^2O4&R))`cAYvf^imwYY;wKZe)#)fxx(4 zEPn9A*ZSgdZKS56oIg4U!VO`gM9C;T(VCrq+3WOo4_)xOSPMC1jrVlud!0(QXXv@y zttGqLH+1MQAwaHY{BGkIEI|rdqvzcz?^Ubr9D5`n|>O(f;?Z{M`_H zL2cKI)vY1hBUl0s_l_+8f;;-fp#vwH9Czw@>(tq&7j8coJ@@o-n(>7Pl_GxV z$$H6hw2|5%Y@f7HcEB!csK?RWCx}7X2WFdxEf#78nzUP^_IM>hM>boQzSv;2!`Edt z=DpO@eok_EyNR1bDjW$;m()RK!AT8F#cZYjcJZM#PKR;4St4__4QnAy4@qs=E?+51 zJqfPm*8N-3`&+ZAt${)Jd*8XAd6+zMD7vt;I<~`$gdyMIwLKK>_1AXpF^7>-ZpPiM z8*S4wsM>pEW3~oQ)kn?XQvNV*38OWfj;>+|>o_dT@L1QxCrHSCJzp6Z_^gQtkQ(Gf zmA>D|MB9jfS#D7_YhPL7`OE`Oi!KzF)49UHBZnXoYa2zJIE~sTk)gWt;uTwW94GoB z?j84*MIA|HQv8KFEOoH~Wt1~5+1wq+-~}sh%8fOAXt2r(b#32EoXk~~jwXsy>Hs}z z)te3PTu*bH_ry16KS)R%v@nM}wf^{S-_qKT^r8J}=?Gy;u4wjLA^U)KR}F4l^02nX z#)8TmKb~-|unpAl5x4S=S;BXxo+k^nXsJqsT-BsncZx?8+KH5ZN_T&%4pNrxxRD)R zYrPp}zoa^iYWZTqJtc~~)9K;DUVV1;-S);{=vSKKb8I}T!l%9ck!vr#-1DTbUKm!z zQPNG~sVX*l7+)WLWoy2ax$2Le49?C9{^O!lrE6FkI2cD*X&4qoE<2l*YnP*@*&28h zVb>MmSP~Hiy7Q&&M2)NnRSv;%sxMiYArfQ%S{6z$j4IMU#Y={v#HdH@J^cc*P<&AS za8hdLTh(Pl(+ooaCTw-|Dbhcc=@@$tZH+RHUV+d2oNYoB!)povz=C1|Zb+Pp;IP`! zVYesCGLleTKX`UD23wD~1Bb?*n)07MFz}IMt{?!Q^Doj@k2u2Ph>Ak6X__>G)fH)t z`$cik!p3mY0RZ6Y>y7dp0Omh)6~fqi9sV)9chWUt)Aq;U#t{oMg5oTMX#Oc+?_mHh zSwc3@fW1>*f}sL~M^uS#WKrnTZb#Y{e4+6fAkjsPRjhd~mJpk_Onphy5f`v}_2qmKQ-#_9%YLI(yz^=_li z4kuU_WN2HN>+4y$u&V(>#bCJJspqQ?83%m1m|mI7-xa}*tf~mzZY9Ir(?f?(idnn= zuoGc~hnc&Y()RifIw;p#u)VFfFv4j{EP_%(Sq?k8Og5$jU7N*SAP34qlhdMmLc4Uo z&gF!>&|*E^I1&%p2Zi<`6bNJ-a)vJh0H_JZ+C+3IXh`J!Y<`1pE!DFaT_oe$0!_0Pk=_uEQ7vdkC6vjbCZY6bxN^?Hi3WKrbgZ7neqGCwyHx6bblAx(jz6 zP{Vde8^?Is?Sw2KE%FF!>o}TQZS$BrxYKS{4nxVhU{_a-${Ur3 zSNVE*^Y+q}!n=D8-(()6g^DaUrA|kUC-K>sqQkomxZl27*bS|nZ_pDkaIci`w%njyI+Q?eR@44Y63iN5-{RE?pUoQ zqmwzb-~F@9j*(k|0`-(hcZmM3-g`IbO`Y@FqHxB2TCpSTT_2t|CvhxUy4O4a%c9ms zbw%Ea81-IUl$y~Pzx3J<=IU!c`tnk}!vTq>Jh)Y}=l4^<09Nu0gqUzA-P}J56jJl9BcXXNd-P z+%KYYoty9egqlYATT2i?^?qn4d&${I2(NP{x?)dlX7$kp%P!@0eL&mJPe(1W2(3Bmx5%;L3z6l4t+eizKq^s(VA~O z@DvavxBA3d`aQfIp*MZR)W&4wd9Jg;?d-*ZV>;HUWp@UfpOJQ! z)!aRju}V-SWz51A8tb+x-L+EYR@waykkzqkALi?1LL9>BW8fbquSsiFPZN-l0aNpI(O z!V@EaJf`B0KOdjw+vmCmx((CTJMd}i+kF9WrMX`fwTmTw&*D5r!W~J?fZ+D3wLf%3 z0mo-ukZgnu#dC7aW}oVpd6gI4grUo851i%Jen7X)&EXkIbvNdl^-NFWj?Ak}4L!*Db{N;YiAr5gmK`A%VJ`do!fIQBeLN9$RlBgnJDJ zB*bm>n)kTcbMNj2xS+wZ;Qpd)emeBI|@=vjvtEO*+7FB(|Waf z6LHNm4b+0>b%h&Fq>J)PyZp`TmkL`8nr-gl+iM5`^NX6YbMiGc+h7&^RCjfwRk_

vS>(rf_VpVn|=8aTI>&6h)#QZ|NVU`>mlB*(24R`8J_o)uzavW1j#fAtyNRcJj zj227tp+>0tmRDm<7-@s14)BU;>4T{X5JP%%6T%d0t%rw1Y<0^P&dVKFH){@nmtvO*QEb@#>_NzsZ$6X_Thw6 z5gMdh4LXo^=CW=!8S0?6!$G^_)x{qcwjb=&@_tl|wSAT1yXEc0qKn>_HC^SitM3lR zse_4A_85a#gA<~kU-#NDe1EBGMe*6$42(kV19n3yHpTj8egQ(E@_bWns@0X2+*APo zCp}?W7huu@06@K1_)tZ{N}^ab79+* z?FB`fCt)9bY|Ig)+1S$FyO7dM*gf%{2Ay{nXX}~wO8|gwcc0!`^~9Nem={J9>y2W*kj#r6I$2B3FYDz@RT1|Iz7Tp) z-B}Nimf;@JR-tts>k9ty;m7{-uMV7a;-rOkuXFY8o_NC9-F5US-m)?Ms8vjFo%BZz z*JPNh*LShx&YM6q9IGZ6(8-8j`k)`m>*>8FsUMyF@lFTo5mw%^(WR(TYPQm1=Vk8J zf~_O$Z;`AjsiTsH`~BiR6zbEgByCCpylXA|G;?p>8a|`eJ2+SBv${N8V>lAsbY|M| z5uK2%T}SKAegbVnoo+euxR-H7rfH``>qO?Aqy0Q|$;?poVE=wEb0nwNrq3^3drKAF zfW!>nzO}L*8GTZQE!$erY~GdF*CsI~WU`C@hK}G8 zysZd6!h!^bvF*2!hV1Ua`tM$fV8F|wY+TX28Tv2{T!A4{Hl^cd?+9NUL? znD@W&)ubS5^*34(tEws`E$2ZShHF!D9l6PMfB;iKtiNt`c^o7k+;uvFcr;q+BDmjk$ZsNBN%G^R@Nu$jH%H=d2NF zkShaNuz$BW6CC@~t=n&NN7o2>M3m}aXi~1s*v(1PBlI8qp9}bvnEq=VnPL5GSpQO$ z+%Yj2>G+)0eq;+WfHWGOjyPhbsULgn5r8s=QBCLObIOl^WPBJq0TLYVdjiHRhT3T* z+lI$904HlQ005C~005yZnMzZJi(X_HK)~5=)jFDqcO3mz9d4K=k0TZX(hU+F2_01A zCRUq<=C%fY}g z96TVlC4_N#dxi}|f{e=2_D@pn+ooUu02-YtLB)dJ2>?t`Y~sBD#!&+_0RS+BU^1&o zy25KHyA)wgLoy0E5o;H%wiL}K0-q@qYbLCkl%nGut0iHzhC9s$nfC`yO*PZIsE0x# zE*f%TL5J_4vy@K>6U#B^g{_4-rgwz7HtrgeMW#pYK09i2w^6;1T-?2JBRcW1ZMN~a zVP2T{9E0{`uDwn_`h3ux5XKN+h+S+}JBarBdW|aVzL)-HCU>ts*awYMQt?bM{t<7& zr64Z|onF`Er!jaDNY&Z5{|cc{E_tZO|57?W#>x zcbP1c-un#i?TZ)BoB03*iCDw^dG5U*_v`L;_TBsFMKk$24ttcwBmt$<>{_|RA+?g= z^ub4;f-^rULsc~rv_XcmwHm)P8~L2l>VD(mBk_I$mX&riE#L2oR2KF;cMQ!iR9+MQ zp&DL7q;;MMVhcaq?`<-e3I}(vsw`xGl;3XG|Hb%;b{)DDhyw$(t~S(f)$de_>Z{GK z{=-iNS;22fbcpnQW>jxABI~%sYtGlD8*F~qkb3;h>)gDei^LHrXlG z4?Lm12XS|k7a!yYzs@I2I;v{946;EQU4urUtwH8V_q0a+LGA1iV)D*>=^OG%xMdk) z`%dh-zPR^(G1mKFega+Jg!R$BX3R;r``hRH@DsyMm&ab(V~=Kn%9zES81lMxH%$9T zxvmJ^k-lk4YK#OOC!=GRT+XMe%0*4oyB_d`rhZ9wF8YSe`ie-TbZ@U!wF0M<#}G`J z>bYPxyTe4ea^!cJNZ)?5;13yj8)-Le=iGzyj-5(uc(f(m1<(;}4oIyb`{0BneMFi( zL>tbs?N)88z1leOdxL0LGpQ+y`THHHHv3C)_q_wb^W>us{V$I_JbK@kLxwN!^^7&< zt#V%>5DK-;Cg7YG+&=!Uk3=u6BpyxI_gv+#S$jSE=GrRNEC#vsVbSA##B58LkTXhS z3om>Ukn<=6{{l;C=dL#P|Jk|DxF(S1yxTKQdk8ur#-^X8nJ!KJAKINACjkH!=b(=w zkl~>OZd=|j^ta3~3ZHMUn2oxNHiXG@&N!~7z^|~2@`r?HtI5c z)$eyvWrGfmGF_%lttP>UA4Ls7>zt`;$fP$N%FZ6`gWW@sRxW3C4Wk`=1Ru9REeB~9 zX}!6+&T0crQmA0^`Tpn}SKOCup6W>?=@GY^Bw?Wlv)67udp@pm+RyK==-OfGDukJ= zu3;n_U%sAUtrpA@+my&uy_IgWY;`H>>TN?JBAqUz zGhbNcT8AC>h$c*$h$U~@Dvf;r0EwVec2CIOjRzlIt@?R4in&moZf!Knijg%8Bd77H z5G-3{nH6ER<0MGDt4d%|UDhEOI_NY7rFA=b9T)OS2lH;0i7wy0T1L_}4FR2w2`4;2 zCor4=0F0WPLtUQP_@i<6tiq`Vok19QD^ra#VZX`gA!&v%!I*__XI3_T2mz?xe5*pu zA^ttFSMW^OQhsp{Vo?UZx&PrO2iM-ntYBloCaH~{m}d8MFc)`qjcbOnC1mJ2ZSjR^ zlNvV3sqxsX)7RDg2u9c#-vE5>b~gZLCtPKv6`Zk=LRZ7)g+x=Snd0P5VD#aPFd^vS zTBhw7l|aO#sS0dX1oRz9a7T&g9gJ_ikj!SUhpM>eNwJx1O<4W=9nMUsMxny@`hXQH zRB7!(}tm)BCAN%6J6b2l!1FEe zjqdguuDCMy?7m!_M40{kC3kk3bX(+LQCDRmV{5o?=`btRSvAD90=qVIlg^>`SM;_qp(;>HNyle(5fD6tvk+r4DXdwc~C1)5+K`q0qH^^Pe@= zn@Vm2hs=<8puwDaC>mu{tu5XD+c~auj~&{z&XSrv=e`*1Wbdg*yZ97XE~gT7OUBb;ulx>7x;Se znUlXa{^$e{#~yt2+0uMNLbI3O`fsLMP$*_FGuFkPQ%uG4UwS5e=VQ2L@Y6@UwkIju z{)?d|mC>yxkN$*!As{aeg6Ej-v~YZ1Z;qd zU-+|;2cC^}ACGyTv5j47*=7wwOYgo$m~1GO*Uh)lr*CX0cNpjGw&GklZUyGi%md>WbUkvv?*K$4aLUK1innRQs000bd`Teb9>lQ`Rk6z4a6{Y@S zd1I&i)qLzuy%;HzhaVQePTX-(wvjpWhc5Sew{zudyF0C_G2#ptXx*shZgBORud_Xa z_E1ewPDqcm4W!-JF`!Vr&SlCuS=3vOr$;aSuDW_lChi)h6fa%FJ8vQO53@TtBE8=U z6Br0y{p7_;KyrHyZ!{zA;x)cFqO^D1l-964Fo?GN}F+>nG8YN)6m2wJr#BB-N=EPj1l&yB!DO)(g?y0&pe4i_f znjpRPs`dOMhj$yLx|P>GF7qj&8?vIv{lVeu3%jzHxwF_4XlFXj{sV}1R!WfM*(=wc zz$=1W%0N7I<7S9+-Pz4LC~469LE*r6>FI$uWlmd$-ivR?`+YWLs71N+~A%> z_R%^Kf9>{*)X_~xKs(@PEZ~1%t|lQ{3RgBoXwfLv zkA$m~>y*1}Wn0U!##}Xj>tN-tn;Td&`Svrx*zWers-geS{HZDnEk*tXQswoUr!IBT z9s+@&0arZg81SRIqu-Lbv!u2Wk^dj2LUx}Hb z27-AUWYaq7?(V8272xi^cldFW&6z@&cgpVXKh7|d4&Sk#<_|tBrRVD<@XsLebPyq7 zT}Dx}5g85Fk@n;WOVF8RTA@z z%$2-iveHah9YeNY7&)xK{$$0)`oZTSRH28o#+Z=`-|qK~IZz}rb1H6fU|QCKr_50i zrI9n|V_SL)ww3pG-yj`s%IbEOfM=3%pXfNlx(}rdq~q(@-AV?9VA@7R2*k>3mav(x zNLqw4g(9s=)9M;ABUrT#QC-oFP%*<$o75_sO+k+E;x=PTNJ157$e6RV3OAKZhiIiW zRe;41(o$@8S}cl~6|2BvzP!emya+<|lh}y4eRA^T>_mSgN0_|i`fe$qTCS`dw0LQ! zUH{_XrI`N&f)SzV`%I|@g9^UgpHYx+op2uV-K!Mi=GtCu5~` z_Ne`0lnS|zVL@A1>wmOfYJvv>9vzX;%toiNaV=l2(udcMZvS*GK$6SGk34U#j<*m^ zU-f_X+9z+lYMz+lI@cWPvbk&t1b`*RBiIgIHgGbz{_v=W*+aPNSuAs1ZyxI~+|t;AnU_>^T)4 znR)6PmD>%Ou($_C6+%Gt2GRX=h0EfqR5XMX#C0s0GpGKGnOSP4Mkh;E+uFX*NKid?eM-)|)@1OcsW zeQL?G2b+tdgO}`{vC55PAonC)43U`K-npdWjT)CE@=l5j9d=(97B+9c^JCvdr@E2@ zDuPTPmHa(29OzOX{_LawbZzs^<4^wjtAG1{>Xg)DJjd>?n3!qNU08kZ6#&3M_}SM! z{EsF)r0HxqHb-ThjNbRwyMH27B{C5D>@PndVj5r-Q++aR{z&gL-uvS>(1c_SjK2QD z?^EFc$yL#JkFaJi8hzr2-}5#JLEg>SZrl4A+z6fee@5t%m$du)yfd1pVmIw%GZfS(fu{SL|0*rqAdHA|2f(9J z#`GP1F}1d_00nihQ`0eC4MTU=zukZAIke*V!3+OeiOrk6{a4@m4rIZp_LehtcS_1$+N7zSo+ zsdmMXAjIbs`indF?ugb~#6%}_K1dKgi{De<%SU=ohokr3yYiuB`4~|e>g~FKN=}5b zt?gW=>v6gjEsfn}(^vOCe9JRySF;tEx2Roh*+|Of%B1&8?d(TCz4`5nPyI?=uJXXu z)jKO0NNs=4Ja86>Eq~8I?_f-}1!CpTb`IY**bTnDdwAmtBJQtOKf;9vlx8<$Ic0_@ z6fav&G#mq`6^5e31&qRg3>e>pfk;4;O%g-^0! z)^pfu%Y&2yVjTw?Cb5u;wCT!f69Q1P+>wr<$#-&q>f%BgdqB1{TCRmvQERgjTjt|m z4|}Hl7&-4hb5iwqI??C4hJGp7`#6apPJ~nyeX&`7*cXKX1PHs^`zZk74DRL$1O|HA!Eb*jw`I6Ptz`Q}iJ3JkcK;c?5TVBhykC^5Lt2%UtX&6`E zjrLx0G%yIW6n1_bh~3W>)#T>e)&~s&zRyBoN%kAVcS*D@ z7!Xh;L3hG(=7Wy5C2u`=J0SKLURw53=3nVI!48-_W^SdNy;jwa)slzJP1SXbv<>K86#b74pf(Rd z@QrHjxYPd&w!o6eH{^dJzL`+$?32BGOYxs@p+IjW-ziu26*k!^iPnCl)_N4aucK*#^8|3D>>kGkGgIhmEizR=D6A(a?~nBT`_;KupP2>JHTNVEci*2 zQztz8NbkU4JW3mCCtUARQTbD%f|?X*nC4?4}$z6N52}!S29B z_a16xyZs`BnVnKqO1`c01)r5|q}Nqx#V{Yps&?2&!@coyUmEfcn!M9)SQ9u3&f7*0?dFUo?da4>A@K7Twk;0%m7lrgL%as-SJCI>_0NTZ>X+zoDStUfu^}-Ng4^XGa97&&_?ilqu>YYaje2&c>ge#Bgqvi^Aa zM1Hw0R^;m5LA_O#B-J}MEC|SEwT5n{d^3)PD@mp0yLI!5HSC;g6+AOdsseRv>VU;j z3dp`4)Mi(EHE4*!6}e40%`#%Rnc>}hIRjgXNS<9;5=eGpIJD8&wG11f5r^GO8zB_+ zBvA-Hv~7va%`8)M&p0$$?-J-AEUZeRRzKnZ043P6oV#ac{Xl6DhI{Ao-2OZ_jo2>d z4`I#GI^>pwx3R)aTd-1KD%q%F?pDm>n@wuVvDDgy7Pl%Fddw3hp;0-wTrOe$6w))|~YHG%KGHHu87lOTy! zJ>n5w(R|&PP>BFy%^!MRBf~`PmjM6(pq08@$+cBohd9PI*WCJa9#pG5>~O)l#kC^` zwnFv&^n0(aiDFTjLrhc6m#W%+Ek7d~nUi5M=yMI~zE9iDEYIJxJ$Qj_)2_g2-)UMi zY%s-HD36VUI4VcSD@jV?GVILr&oL`FLLECQ{sj+@NC2ifK5n}~_?wzht*)fxw#unQ zO%i=1O`-nD#|FFlEvbM_%(kJkpW}E3vUhvJ`Rro5{n@oE;qm*Op7`^I*+1xhbh{F) z+{6KDzHvDcyGtPs``pd;Qkyn*Aaluk)97-{8lH7a%4if@2yZgd@7~yWL&3|QUw(AN zHA=M3cmnX!PjWkVkA$fU$(}y9d+pP}Ilo0=(LEgdUkRc|l2M$5VaZ`IG%u7EKX@%M z6(G#<-27j~0oQ~#(l@C(nQkRF+$Z|e!g^jjLS0XF3VG~U9wJYrvhN^$ld4p~gdPNj zt^S8t%X+Ny7!?Uo0Wt=@#Mz1lX=tp+21bcJo1heX-N(CKy(-r@{qREu>XGy^->jG9 z*8vLYvJL>y4E99)5tQ-(0Frl;dKZMjVq0he01VY8w^hC@8oJ(Am%{KFpaRE$1x6tQ z$fkZw#T&Xs1O}{=nxW{U{uuxuqyj~4llq{ARsj}5V9X>Tw$XnXGl%Hin;$R_MvrAj zb+Qw34!gYfV>UFnHjMlIxIQ(rEq%K`m& zvdTTX%V`FWv2+>$O>2iejXo$T0f6`UMy-?`LQIqA?gs!sTH_$Qkdr?F|6Ox{0X^D% z-T(kJSj?{@430w0pDh`JRTFi&r2u^2Zt7!j7oZ{6n3XR}x|K(|A*t2W%@Ux10Sr`h z#RA7_T$aeY$DY2_0R@s|D62zP4B2jvKN-+8Ij6kcg?$0(RN$a1{{xF-CSoy1-IiGm zQdE3Ul`y(XhXRwE+uy{yPZ^XI>9|OkM$O%dqv>sq*nHQ6qeC#%u(s2l?xFUy%l9u&d+&=fi5&+% zK`ZphlYi9dETVP`AZvl~-)mMzlww?{Fc6ZX3n2vXxMkH2tI)y<-ubUB&tFUF?P@j` zTtRw$4pYC0Aqh@Wz#mq{yo47N8otbB`H3Uz$^Iwc^z--bwj96j@BF%XzVa&m=PlPh zqP_N};a`{@MWoJBKs-G}j|(-qeZ8fLx_EB=vC*e*WK%ky^{ERz-6PG`kJHXSst~y{rcet z3)x&twtzEVd@^EvCTelV$0uVG)aQQ9xAew$jH;ehg+smlps(xB?GFmQ9@{W#OkxJq z?tgri+-teAjpnXcJ$BAd+SQ{$$2yR$z}g*`%>#HiiQteoUdin*Fw(zDXAdCz7h2q= zf-w8}F3{N`Jy#^t3as-HNrP8Gd9f4KZZF?@4Px+(cVEcBZ=U%VpBL|Om3Nl(>C@Jc z$J}ZVr6%|Qvy-`r>m_1l**5W^8>4(Z#~vPjC>1vV03ZNKL_t&lrgF7=d^}Xb=ov;i zl4}9Y0;xD;_?=AZ-cjqYktX=$oNQ9~97WK9W{e%VE^{2AO-7}Z*f4i5SYiCLMlF3~ zG;xXZEy6-O&0uH8PUXBCg4gD9*)h39iW`EwendIXH?|L0MZUW5)**Dfp|-c*)G3Qj zaWW7+R=g`Pn-$V&XO&ScH?`3gPTQSo%c>t2MTp;vrB*M)XwrP|LA%-4C@=EuOyTfy zro&#&A6_mT{z4omIyyuQ9>Z8f6PV@}lC9q43hZQS3jchWt+K0nlqbVoL!`O11m!|LVCPNat+ zDcJBIuY{}6hb^9Mt2*3aVWDQ>G!AvL5`G<7Tw{fx|Jhro|dWHDDi!RZm}dcOzQmnCdZeo-F*z8fieud zQhwu3i$_OLz2o<3%{=D8iw7-NH00?}kcTd99cpe^Z4zUH57-LZGUE+QA-0a+fjHB| z9Y+D#Dc8G>d!PeB<=Tj$rr6S%fZL!A1ag0J^WAj)2vD7q)2A1YBtP5W#{gE+-DWz8 zO6m2r(Y{zfb(NSFp@0^mkTT2@T9?C?-f!&H>T+9!A;@hBR$56KvfjP-QC$&(GpB(` zqnxIu`T+q4qtAu)?6vL9{@xyJ za3j)ztG#+5OIvRq?KJ9C%QGh zopB2jWdDAGXPVw)L~`Sm^j3oIH$6^{tf@^;RSujW8}Fzik5&#v&+#Qat~S?qyxtIp z@L*@RHQ1jD_a5x7A)a30#13J>It90u-Y@D_rweMO3?r&Eb9;VfD6d<)3Q5s!dgs%Z zn~F3({#ZeflUb85e1`b+uPly7@Zo@U@g?ZI#Imy%*L#@dL}vXU*5eNKzqGJW51$w$ z+Kr=o^Pvl040c7fZ|{yDE>uoF`R?*Z(XqjBnMrv=7MuIt+@3sBBE=zp)bIT8C%g-{ z>K4rBs}`1Pnx49yGee@yAKt9L;P%<1U@_#?YfAz#j;9XxL4$YqGy%EbO6v6Raoxqt&X|`_%3ZoU%To_|KmT@g%_+4La zGz-0M!4R2uU;J)=Y(^<{>?fL*0X4`lQi6yv%PJm?bU_7k+be}wZyo48Kl2t8OMdZwO>pnH+t`G|HK!2oH5>Wr%H~Y zkX9uN>aIZ$>stqvm3+_@mb{t6%{$Q%FBB=7TD+BtH+-p$tIJ-uD?X`Ix8Dz1W3Isq zgx`$Nqn3#KaPMs^sf2njrLKKyKQ`27n)YINXlm zp#Q6FZaD!ANuU?*z1ZV9qiFTSkSTr5-hUqf@I?02_nDbq&D7AjDy}pf-RkwFWY4kl zki^WT{$j*2tN8p1mqvm^)@|GJ+}zCAFGDaZ^XsNWf50}8d~3BA3$LvA^asB4k7+-kvgEz*XMeF{ur4?E&EZEQo3{ECvRuYWp zbYBaqrjN>Y*EC=MF45O7wahg99m(g&*8bnfy|gjZKnuv_*Z$j3pzCg9apo#rPZ-yK zyz7Teu07aQ#J+pD{#3BX0%6}zZa&cRTMohZ7T1nHGYUDVkFLIM$lfr;eSCG_5=R3P z`TCK1eB?BzwyDG5W}rcJ?E3=RXk4A_ICT$FUD|Ui*$w{!+BrQM7RWMXadz;&>AL=W ztlQ!-O0C*xSpfDXT1G$i9=bS+My9+Hoz)^*>Mr1cfZ-P2vc zLc!8vEXn1y!NISbUcdU&?B2wME^7*Sz0J?A?@TB9ybjE6Qs2I{^Nhs{hGzvsmpcUF z1nciEJkIoNcPh-u-rXPnjg`XM=0tYkEzahH_i~83(Ko~wrVT?Ju~y$z2Op-Z zTkowO#m>jbJC--^eC$z0jrrB=eoDw(7r8y)@BirX_fFcZ6*=!5?o}}^Y1nX>X{BWU z*w~HvKXiHj-OldcN%*)W5#G&yPlwuG>>L8QYDO%-TA@-9J5@i_Fxg=saFuWDrfU8t-`H^iGph=JDAxo- z%jB%2FuBB`tCBfKMw?XP-j$DmDtSp7hmk(-U^Zz?lOR@*9V(t$sLEX4baSH_Pd zLouv0Sx;^6kd8FFu`4QgVb?e4Eh7cCp}NOxJM$&-jCuV|e#-8l5wxB?5LHhH+>)y1 znW!&{5>*{lRkRAr=%#|hh)`#QASC6K4ByseJvwSfI>o$W7P69NHaE9$HLvD`<2Jw7Wc0jdcZ0H}uE+-pNtQOPBdwozSewNh%T6k*%lp3yKt z>1ExlV#r#$0acIh?D+K@k)N+;>nsESiJ+QcET(U(s$8*FBM+P*gVPYr$5R=H6Qh-y zz1v3w3P{(0tm_Jc*`brJVOt+wRJUAY9zhTj0Kn=TzVO78J@VQ~j9{&D_OeA*AsiXk zMTDa+=T0d3s$Fkreb0r30?sc?S`s{pl82?JsrM{6L5Y=QzW2QgPo5W>X}z7s%qW)? za9u12WfWd_cJ>zaGqobMTdc8sZ9#aUgR29_=tllix{o{gn|%o7DnZ;T-B|uG9Xwbs zA2R|ze+ZtjbP>MzNi&L@Xlm>F)nk}V4LeNgG-<~h6taBSZ{qD7x>G59!o8`$)wQ7g zp;GFDK;(j%u1r$_ly>I`viGb{azRJHq>?bqAN{1dhmuH3fF808@pO~dRQDx6ZbM6? zc>Z)eF6M9j(Z~EExAVg^qmuQbW6-T65g|ICG)IimdDp1egzCBd91)W%hNxc_f`b~} zxo^ql?~v4>%A9{Je9Bpk?pynDGv>iHOoayQgdbK|2(R=#HHI@Nr$$PZmOU^4!Hspp ztQm$MwO!3Pb~ZDVh%FWJiX@HBK#R9OY9+a_q__9VEnx&>U<`ozc4u?->c+@Sh!^_& z7J=(c_UdkHLc4J}`oxHwjg0!V^zJ7X1cr=Lo#`7;o`#gBl3U_=V0XvzJ6A{tE@aR! z3hm1oa)K%?^{Kvl77wz1W7$UX#c`iy?wVop#N2H1AZ5CXyTVVUh40{E#Mg>^@Y7c< z_C6>#bGZJ!B6>ig0m8b%TC)v=ti~WJ$m7_`=pWQWyBLfF$0vfgDMXfu2t916`qVx1 zaqU4i>Ol~dKKNY%Srhwh$aQJ=sMB)3*qZ0N-5KKyvYlFxyr_l4U;6f+@Z^Z4fBHw? z{02VQ@WZF-FMZn^a37L0^T|(9deY%8zwkHTnzDICxp&R}l8f&nb!Gedw_tJ*F?YT8 zr~lbCVgWbZR@F8kGnWvok-~IdVMecXDt@ib||5GS7L6X|-cYYABokp4d zPuBl*!v8E*aNPXhFa43H0c%}Y`@06k5gxbPJHLJVpiDBNv+940!05Za`*`afaQG8v zAMe}S?U?HcqHy{lLQ=OvW{^-uA0h*40abNOR-grm|cprThFI$rZKTMS5KDBnodgT zVsf3fCzMXIo-KC@q760guWUKa+1kaCnsCn=fZO$www>Jewn%3Ud4Ii!h+)>u`pbo2 z*K-#76_4wAMdr=S&=LD~u5j7Z+(2O$&^SEM(Ho8qwyzj=97{;}O-aYP{l_ihbUm}V z_-e;etq2YAN9DV>Ha8sanM9FU-|) z0(X4bvev2^DqyqK2LC2eUg{)Y9fGB!WTLt8Q%)Gx4qgr7FaV%&tugZDf^XyYtkaia zS?Jwc@4mY7wPoMOdmrc4zmHq&n1`%x*MZ(dtmXWXrBM`JQRhqFUpjTR+wARqL3-21fA(o7_z@60 zkpTepWD&%=3{eyriIew1uc5lq8;wj3-miMGJN4qHhnbG5EH^8HrXF=#;Ge<%8#w?# z@g{Gv4{t7fQx_Q5y9&hVvYPWToRpJVhZ3J;>ms{V+A&G%eN|qP)vCys_)cM~+1@DD z3iZ$`r&nkCm#61lUye5C~_Nos~*v6{Vpq3d`zXj49N-0$fRVk4uq zLc7R^0HQ$(ui7igVg zrq_GWEKf!_9#R$5JkNH_)&%A|+01qvcG}Z(!kqDYvckF3r?95FqT^25!R9*wjFue0 zcvl}nyL~1HZt}ZDcm06ZuoL3`s)N>#+}ntKKrd{M*qlfRyOikZGP8ocv7cHAoOHGh zJAOe0n_I88D>fi_j!sZ@!dHIR0x9)y)^A3EYxcyFUXR%#Qvm+Htgrr8Tp0h*I zvyVl_PYfFG{gm-hO`9KWbQM1pDoYL1z~c$<1#ZJGW41@!y3@YFs+$+oq#a6800~2# zKE}BXnl%LpkMtp*p<_-@Q;}y6?K^8_Umh>pPnJ;-8~$G~eg#o%L=sGQF3cPA8rcdnj#V&3o3p z?x@DI2ettm2)RFiE0njz$;p1ZH$5F;V#SK#w+h6#u*}(dJ7Yix3I#f%qS)#>p+cbD3P#V-{jQGaJAU8eBxOhOhIclEGp$&p2d_o&Akxl6w?-91{z_PITt1Q7Y54*iCeck4*csnQE{Hr!zypqN_J3 z;p>uh528&{b=)QKP)5;o_(bo+W{d!ocInxtA;hUlT7&7Ui#mmLB)(Kkz6VLhea;99 z!y2z6>@nSr8-N4==!Ryf4OLaex-5&Tjsq7;Al`RYoP#%o9&L5neHRW=}o_cUWKp&gn1!P!p~VkA)fHlsmpnl`lBYV-V3DQqDpa z7$HoE=@c(3*ia;sg&qoebh@9U?s!}mWz>rXaA6;KZC$(vGZ~CRJ_>~@h-`xSAl=e3 zn-vrUrg|>b3R`p}?jD{Mm72r{vXZBvH3`_L748(vn>H02v$}Pu#IHuM#4v*60N|P` zDw-jYi1Ln=EI-=2yQ1x)5iGJ z%HXk`V$Rw`5wy`}|Gp>p)|YL;yYD4K1>8Mq+sIYyzQ$a7QMt9R<;$(suAR;<-TSW- zry_e!?)%Bj$b;U!b|dpi`MBg-x|jQKeP{QF>AH3cdh`w|ZXVQ%K;e2$K5^Syul>%g z<)g**R_!O*-Rd;dR^{J35{^9_)z?bj|G&SHTHRypZL_yN7zuRDt(JaEL;dIOiz$$X z$4Wo6aL@d^i{1SIfL6Y+k0|q&U>j2Rj_#19>$>!s(uUg74M^pE z9HN^Ye4NR#sDYRu^7i85Tsi&GD&jaf)`cPVb`xuGTBlmmats! ziDak||6EYd1FU%#W5l|`Uz+XYVG0Wj?r}BC!ONAO+>n)bZ~pxs%h_@tW^me=RG1XE z9#c<|{a@*Brx6HNTlZmtPv)f8sh*;Jov}^pq}ymz@7Le{0) z(cP@VseYZhl1kd?IZZnclgB9Rg*vI!) z_D#rf?@6?_omLM{R<<*)-cY@G7XaWIwK@lxK>u0B>o?QR`#q76gQ={xAOuQ(STgy4 zapqu0Q+C>oUnmA5R&UT8pK$MqN}BFzb;=$kCDq(s=ePvn4PLai7*|J5@a`7h_{Z;i zh}10zrtPhz(9j8n4ZsdH=2Yr!#S8Sqjhrfpy^K9XGZl$1|Nn`DKZl_kq{&a2BC1}n z$D_1=CfKO>;-><>5h7pn(^$RcSjjJhX~v0Dby1v87X}A>8~5@}S)x&Njcqb0x|rLh zy1rrx-BvRJvbi;Pm>px>?E{6WwhaiO93um$ESpqEtdaIhBCMZ@$F@m#w8u>x%1ks| zD?_zrdFF}P^`pA2!$PWn1$dsS%aGC9(NV-2$JCs-al$uJG-Xu19P9|%*d*x-=N5|N zhO$zotSIBabRiO_5XcSr_f~G2+eS&WcXLM~)g{!M&Vcu($Sl!cLeHRG_vhbfGO)On2h?m#g+Y%SFjO%gTh1`8w)QY_R;g~4@Ce_|0K#uCrgP){nFakty`M!7%*2f8W21SEmtC8uG{I*-b!U=gmt%w}PA;>59F zSKS?c3LB_c&F7$fPcmhN#i*vV2S#vvwbK20=kk0$5Pf!t+S?ox`twM`pY8}aX??7{ z-?AOEZI*W8DVcXYWvyx&9rX5-`7JhH-L;|!=b7%1TV18#Ef*N_rg9d^({-$B+S5E2 zYP;f)XK3ELHZaVvwc{|I%(u$Ds&!Rqx%;17fBS{|$HuSi+(ZM2z+-x18X~;6=maF~!c<>?4o^|4S_;08;zOo_$k^DO+uLD_htwlf zt-(=Dv{Wg_y-{c5_HH@gnb})--#N$_?3nWr!E>dvo^R8GXF{+YN9wgmpXY;jnUfdW zO~hn!q8c=eAe*?UhXX?CZj-@}D~ZGWMi7Bqr-QycRq{u5V_3woW;^XM&qz`zy}K}W zT!WdSvDtR}?Ar~0FO-#go^o&JVvPf1(EH-c|Gqul@mqVSxfj=Zv;EF5%^ck>b)5zf zZxP_NKl`XTpm?p1K`muz_1*CB*Ne^f#D+Y5=Kf5w=#0){ZhPvLKkvT(b0W0kiBzVh zpti??6}s_hy{fWJZiFI81g@2CF{K@c91vm5s)}|K#xIjY2hd7)=~A?47IpZRaGpQTbs1%G+o99Ax0S{5EIm zebOE*9IkD|26`ZP_wK!waO8dxQDEFT|t9eGK^;ib(^Cn(J{wSov!2On+rJ%u%rk+%Jo zSm^T~L+1bVC3XF9fMlv&VGPX%i^#fn3rS9S9QIy)ZQ0jr)#{ETtdwAGqIPZX z9K}6`i;upcP00BnW^YfC0u}W-zA5^t88CUEcfWy}RaJ zfA9VPq@@%aE5)8)85xn0Uu6Es6LC(SZ*a`Av?ICv4-Yr4zq9+K9RBXc>g34hPRGXI z-My_8l`}KRyt5_SXvJx2j6LW803ZNKL_t&~H?!Ph5N=-9ePx%`157k0ILFU^Dbmw& zb)TZ`aoZ_z%>OhI4OwFVnLXXsJz>J&AyRs11g@X1#Ze3i6oOP<|Y`j!xLk=w_ zRkoK>J?9DEqOx=?<{LCSA=nlfKK{8#ICQvtf2a?!M2pPB z>}hd>T|4|y#z|K93vIqJe)+2`?`&X^f#@-$yxj^fTPu!(=yIoxdzP_;e=69UtKO`J zyZa)H;gIl({T#RCTM{Mk|BbmaEH^vSX`**2IOLPuBCp~yY zOsRY(89B{qCBtit_>SKN!a%hQhf+*i_4z6*QrAc?kBKSXA~g-2Z>*bSZ2$laf;)yT8T!F)eWhKSdu8uX-~a$sn<`_@tXF>2EMLF(ryM3w)%P{a zv;fdH<=w&@Wy+*f$RA!QH+G6mQ^7-lMF_Ng3zXfmyg*{M;`V|F4fuL72F=vA`t3E% z)OPtg7gO3f$uccV!x5BbFbpAJTaYvqwX)CzCS;&aRcrfCjvRCj{FcZcYR&-W0u=xi zmL9#;v8-Z`f!mErbO==|LM1aoTp?A7d!5SX8U&If=_- z`cS)j#u0qM=AWVhaMKW-F0CRSIo zaS{rTbDo*{$dILv_u=gcPw*_?*z6cOpXoG1$CaYnqA!{}ri#$M=|z@cIdsv6sBVjI zmhRhiB~We^5f>DD%CPUZAcgZo9mXt(a?uh62eR6z`Zt(xT{IjkY@c|uoP+J|?WH!I zIaVw1&pa0((h(vhU0>Q9J@>f7(n4$-uC_ za~|3!LxFQhy3{(*X*F-;XCPyv)lR2t#K0%c_&IsEz8gdzsw@scM5or~-zmnn_EhN5 ze2l_%L}p`FS*_u54Yg53$_N>Vq`5GM<`{(#cp?2R#zd?&*Ukoy6`bhi;w)c*;S<}< z+#b}G@g^VL$yfYm+4j^<{(Ud?x|)LwPUX!t(hwL(w(brM;yv3t&@`mqEmeGjdrA@x zdHMhX!Y4hxai^fMkGKluBjf|^tta-|g?6)=@fl8x z)U(iJDAwK&lrmSk*-0`vT9P<(^|87}Ax^Bb{F%XR9-iVBeq=Wf-A}#%HmaRg|06PI z&fQxn&_l_AcJtl06~a*##=c` zJ$?OKe@NToz=j^ZbE{I|l==)D zc)Fj^Y9D-uwq;^tl|cxr?2*s)^yF)9)@=3?k9E4my5O{KGLET}Kv%`}&koj#A`|@Z z9k*9322Q6pt2Jz*ZKmbr)m_;;?QxZbJAYO6ooZG+AO7XPgA+GkS7?6y13$qu$==(! zW?$229ytGb0 zgkBt2SB|)yE?da)-t3JV(L|~HaTrIRkd4b`>o*$)6AxW<_MFNz(uz1Pal3LUln8XR z<(^Z&`NVRU(Cm_$_X#@~9Xu0$bYtsmDsGt85qPApr--&KtOeYL*mpuS!$1)ZgF5VR z!Sx4=&ZGe?ue5e;bJ)@Om%Z})k3Rm}6UcpvFm7x5F znZLXFhR2!Il=AN0M=<&>0HD5E+PeDFHwt@Sh!39eMM_fVv%mVQ)Tp$7_+e2N_t$F0 zUcHatY+cCYG;^=9n7b)L{?em=cn8J02zG*XbR#G%aQ}K_yiH8SE^ME?wN<0Xvnz9I z$X)LLSl3Raf(~3}1^VSzzNWcGq13s(*T3f+;ljvq?$w`!;{F5n%w97cNL;cxN?-p^ ze`o%bQ}En7xO>49Fw-V3}mxb>Y0vnW!u$tYb&FRkUqG+Qtt%g zX{qNq5mI7&h_V~*;;uKKQ`GjST@vc$_hORI1!BoBtz3CU=J)n)z21SItF2tc5On&p zzdzbF;2rpKU6FLNHW5D|>2gi&yqQ_|wg5b+FTQ+0y4=LE%Kh>OqT3!hc6xrJPTV)$0#QP+y3&b^xe*)~hP=wv@)?4N z<0|B__1eUuteRF-q;UkPEVSTb?%>Z?a&prSQ+|!&TouQfeg7R4g=tMoGUOO;$HslV zdCYJ34E~p$5|;vz$Yxpvoi{GcLQ9{n(i zrbVuizg|~m)ifd$E1L!YKsAh?r;PZgT#UVo4w00Pu<+LAuJDe8ykE`&0B+WDK4(%k z4c#vFak-55x%Pr84ppaIenZ%A)s{J3LNL$mY;FTo zjva;7PPWH#7w^<|l?u;Sb3}3e?Jb0WaT}h_HXs;n+57FzUYvwF*=3fRs_w4|noKN! z`P(~QYU0T0Y1f3^9;W-^fm)}Tv4uKfI@sro5uRPKvLR^*1VI)iCOUo}(`bkmY3jBe znQLq>SL&z|$7#NOSi|Msgcq~b;_Oz0`gDsi#Rt-z9fkR~g&vfNKycBKxk`bhu0gv=Clx z1qUfkl02HIYn@x$S#w)03)=o()|5&`b<3f*8*`b|;2GLeI=1y@W?HiMx?SS3PA%1u zy3Op!;K1k@JbaSRaDwZ&g9x<+JJh%gTM(p+*_Q8MmhUtbtMe$(_qo}P*WSqQWpht& zu6)m)WKt&v$OkpAzG!zK75UG)r%obDt0BOivGB!Max~Q+V*H+?eceF!J+bLIgOUiV zqFo)XM2qd@fL+=PR~mb*L0+n~-tDZ<%|3j1MqFQ7yiz*EVdPpR_r=6uP1R!S7>q+I zk`?by)O(wXUF%r4F#Odw=WjVo+4%TiNob@#bFn4Chb~DolXzfO=z03%Owt}QOZ^9$ zff~A&Sy_|}U4!QIg;`CPgX5O>;lnENQ`{XQ5Abw@`FG1#;4!}x55g?k&dTJjeP86n zY$-PI8D)2n;`_UP>q7ai)t0k({nrHp58`DG8Ft_lB<-NYMantQs;|kWpEAn^T`7l_qr=xClPllfw>pq~AGwjYr)aP(E!iz5C z<3)46%S$!=5~&WjU|BW4H< z&Uo6H4(zEo$1bXeu)UA%n-12L4on0_SX))BP#hb%;DB^lQ;*o)W1U8Y!}^DgUJ|7& zuujlcZzad$an1LNYCFofsQUu_IIKyi?bso85k3+TY+=~J!10HQ+O5EWW1ssyWFPYN z%`kEG@Bi!%C2jjo?r!>CMcEfX?-ESgTgJgKzMjzpPFI~3hTG2lG{5&=?oev)>9y{x zrD-3uZP{1-zDx{-s;?0_nu_ch%8?yMh7n8vocY{iZ2yAy^ziDLWc6(c8K?plY|S#GX0h z&9vIjCu5>TIKA>rn zq7k@(nardo($Z9gFCMOcw^kSf0LYM}SaF;W5TVArOMNOPWQ?N@!)XrD+%Z@mlFVr8PT3 z4r*;w^0%OO)6_d}OI1a0?5pq?#f&z0@^@bP{uF1g9G!&TtcOQg3_!%8k*Gn8E!s)9 zWXV!d_RaK?W*J++QSmv38JB2p2rL$K_q9YxYTYra^K|DeXB|HA<=&<$x3Xc#U(e52 z8D;=A;@G;|aR3Ok2SCu=H+Kg|13BzgyfSs*JT?^?@8r^v++7d4_^`EKUjD}IwO15S zfgPjl?#C7UeObw`-hANV?(vm^SkL-yUhAWrXT8yLz9;}7cca?g6AO3iyEoo_bANBj z<#%BCf0tDK95{>|^Tv)3M3>eI_f|770^uIrJ)|p!A-YMUR!;hQm=F~|Ig%xWZLVTj z761ToVnkJu3|%sGDViihVT-Rz5PJgluZj>>Zz0}PS4Z5Vy;1RS-aa$}Y*o^Y%XO6r zQ__J4?^*-ReqG}gwP1_U$&}k&M^M&`_R+#}b#1#87d5l8aCiB3GNYPJbG=p7Ei+27 zoUZPRZ2&-C5;$E20J!>Wh&W0m3pCN&I;eRgXUhlI)Q$)MP)q~&j+a%v#1#OrN^(b1 z7=}1mSiQ?QSeEH~91n-$O@XjFeIppp7}9P#CeyC2gN=K#CPf;=LarRq>55Pt={jq+ zH+CrAa6*-qh+~MOfix)~WJm?y^3}Aq+?t9_Z;HT6Wd)9wY;}~u{aq&kCiVsW)f!Kb zoZ*L23JDU7JwaC&TAYbF;x5NQbB`!Hn`p7Ic3jrB8aq|Ohx1q@lgm%($G)?1 z9qXq+DHI8JrMLG`1~|NwPa_;E!a*d`+(`9I3r#6qxKFa)2;pN0aq4tvjiPEqGm}2_ zl2pyjG+H1Lc5g1tBMunN8nY`4f>1Cm(~E1iW};fjl!dZK53L_ahv_AqQ{#@5quJa9 zLDXZjtD9+u9-jvH0xHE56Y2d=FVv);+#3?S?;mwB~)nPE~#Ljhk>B zckK;T==)J`e{)XhbaGYngGOg{)cFkUFkr*pu4Pi%C}J(B(6P@%da{WJYW-p$UXc#^ zq2Y&Xiw9%$V>#j@?^1*d_6Pk7iia__gbg1Zvb8h!SIEf#Rb2&1{LU4)*T1y6iQDM7 z-gA>zhJt{$r-Zrpw2)roJVrG2WT;Xt)Ed1L&q1)&${!lZ7wxHKKTcbU=djForO*l7 z*0wu?jdEAh-stV?O5Sl3)zW^7T%M=Z3tC7u$SEzcPmZ}{vftv*rPtpH`?`;PW)k57 zIq1=^3-&kj4Pe1sYzP_5Sw)RRPwHs@UgLx0^ck}z1&Z6S|1358YNY2mwKovF@|x6l z8I(Alw^DtlsYDWQXH*}?Xic26tyqc9{;kB=Wu0}bZT+P8co>fd%9)%e{KfggcU=>Z zyMA$-`G&JNU?^khojI?3f(-8X89|A+N^@}ppMfEqW&*%BNLHaNlf$uos*ne*LN6QN z$r-vXx~it2F4#4Z74b#eB2JtUIu5h^n#{YhJNLT=r^IT}^i>T?rZ`y}t57(imdPf4 z5J$%N{p`Roj4|Y5>>%Yk(Fvo}YR1`fGDO)}ca%|*kVFaf_uNM>dhlvV$tJ)FSn6eY zPg{1}d#~W{pFy{-Yxmc%IOEceH0The5SaqGTv~JW2_5>jLrq&r({f4f&KyHNUU4t% zE^K%`PM5Gt!2SrP!N@=^iv#g-Q|0*GOkf5xwBFT)En+$#)t%(wdc@(PN?ck-oE^$8 zA)EE@jN-96E8p9=ZHxXoS6Pq_9_c12wl)%}lbTg^^&c#6i^-G##d`Sdw{Y(e=G9#p z#A!GB`=z~dix@)^{_{J~wK&pETBEFyb|o)6)Oa!bAe>-3&IH!H4lxylfz=ONwC{^Lp+=4cC1Di94%M;;^&N8hAw(5@Xz%-f`<2M# zh4R%m>9Mw47|X4EG@3dh8++O1#!=dzNI2YN9(%uX*9VQP;jcHUi8CYSrZIoG9zKzn zylXs&%#O5K+XL;}>-SC$d6ai+Uq&i0#I$Pcz|or}iRb?HCccyR8*Gv>t6oRI5}{)*x_c>nLd`OJyOZ?ArDs5c3F z`Q3;AK%;$nJ0=UV>=#)jC4`qdE1piZgp5?!25h>@fxtvozNIOp$lw#YnrG`CcTdEm zxA^_-fuomEyzDt|4`&BWGnO;={M304tuaJc_AS+Fcc<(rzconJ;skqCJ~X-2CKi(p zim$fz#KcL@*7XO=?_~Rr996v?!_OfM-g4faTfLbIO$|;@w^s7gT~9yCtjLmab_MA7COZqo6XYrLmC>@wqI+92RH@U;2Ff;*}wHDG8YWKr>kd75EGB}MxY~jbGNseDa(ny zk>==KUK$-y)xA19(wh>|t@*m&Knnm>LOG;wCY-Zf*?c>caP|!k>8{P*wcy++K8&ZD z*g!9v^Wfy83_T>)=lv~S)do2GeBH7Sjcm@{>8;cpy%D2wchGcQY4D+`uD)2b3>9c2 z=-=Mk)?k;-Tjt*Au|K=f)}8q3=k@qXyB-)D?%TXZIl7lh_XddZ5Y^gIt9&icsxCbl zh|IWyc}aN87rjzC)I?qH7;;_JJBDtWIZ60$M7jSD5HRBN4k1pVkrO(GPKJs4YWw7H zypa_IQ?z#>6{$RbdZnQDg5o57L_?W|`Hn;dAsbG*~SP?dK$rQYH?`RLi_gju+(mhT1_u7^5$>7#Q z+#N(UT5cn*N6kvRF8z3O^C#&o$;EN|9>X10J7D(=Be>aYUSn)M(0>Ve zvn-`k?CzUPgq^Ijmttcm#yTV2{TEKaxC##{icXMhzwI#1NI8KqhGTxWpJ#j%C~h;t z2$>*VM;#qQ!_+#0Vw!F|ype7nh+`Fp0nxE6U(Y>iZi@)z9gUwZ%90f*EUm*xq@rtv zvc_wzTo*lJ6m5i4Vzv#lX%z3(*-bOza1yowmw&>G816xe(BP)37$n3uN@7mn(h2|o zAz-N`C3}4tR09AoS_t=Xv=hKEhTE}PnkQR?&zTf-T~OL>WqBn%XG=l|Ei_28<>K2C z?2>lGM#W>NOu;PF(r&M#Tof(KU<`x+07eKDx8tNU*=09`j30#n0IbvH8lcI5j(Lvg zSUL?elF9?eAuI!`Xzd716LZM$;I6Ar2zr5Os&c~}oT4Loqx%rJ;kEVosHOEy_LrJg z|EZ9LXOU)~rgF}1JL*u}k4=_#v}V$>RLI^9GXWYx`ECXm$S{)Jv=2TDAv=JwrN)mr z6A@sWSX)E+c3et#_E9yRO}#NK>r4iN*yM-TUcQ=;2H?yXJu`f&f=3>^Um z^(DA-nRCxS;fk$T?|2QlfsgTZnCEkHn>Rzwnf`c3uVP!Ib)bjC0h~H*n!0QWPV!@| zCdSnpChs#br>%*Mnt}3CO~$8ZdcUx}|8DTq<0c*QM^Lrzw8n<2PR-wqT4suG9HXP& z7UqJ8C=hAu{iA8EuBhT(`61x<)3rB1nGJ}c!S#~dR#~CZ?>#{VQJGYB%~?uIzE`g$ ztqZtC!>$LoaLT|^RP3;sy8_D|8$?^-eH^tjYVSSQDYd=`yQO#Of`QbrBs1Vp zTb{%BmDQ}oZmy%F^Bb?iWBu)pDk9~{qvti#&28#NHXxdPqxg%R4=iO#wRtX^1rn0C zTj`sWR)-Pu&g+{(O^WnH-uua);5g4RirhNXj8IHSuH1T$;uL51XYSAcjb(RZQV_PS zi{1hcjIqTZ+M~yonZvJ zN4&LAla&p1Q;FHuj2TdpT6FYr&{D5m{YI{~85(}-Cx7!NaA?C19kXw!L~ zRwP&HV8uO%n?U3qe1u+XnHE|TXot}PG7-dAoob&waYz^@1+Ef=80uQLa1&vcW}f;# z7%Vc_mtr3zB+_R4001BWNklO@#CMewz#L~`PsGa8QvgC_AEkIE1?>O zVU?|`+iQ0*!c`K5vq(_=(QT~j@cDr!By_0Z>i>8o<=FQ_HApl#jVs>z@FiU`s`fBD z0lUKen86PI&ILG&+MO{U-g41>pv3#F-@g9N%Piru3N|c-m#w?VA!u}OQ9Y#ga4R@> z(((|0|E=Gn%|XxTV=K+CS>suFDe~GI->B%O%YV+=+i?dd-P-x^+i!Vih&mm3XW=_R z$2dlB{rLKyB?6C=jwluc=_yru#&!p`^S8?(R^S8g9fFR*wZ^3ki`@*N** za_I!>+ji=OI35d4005?v13zvR-pKFma#f#?THgHAn$YPAO*jx_Bs?CW`1IO$qJi-r zFK>WQq&GgE*NaE{SfPiRFTcCLUp>O#ytDFp4|WEh4=kmr z?!1z#hF#a&jY8~~8(pVd9{JFG@Xo_;1iPdQpZwB|T5(rs0RS{T_VQo-Z$TmNe@9y; zo2gqQR{02Jb@z}Rni?Pomp)7GoO1%JDVRqac3EIxPw$iw!W_G$d7YkMn0R!oyeQLb zDmT^ZC_>b9p~F=ht{I&M)!f4m%jv1Q%U?y8qUlqqWGHs;k(|AR#8zX3wPF!l>4m0?+A$s(PYtKSAAkY~ugeOT?a zxs+Nfy>z9tE1=kA#-1dwey49-TdU8a0 z#u+*H^WuIfG5BI6HR1FF0BkWTa>hpo{wvddYg>DP>P%6;*0;U;g;=b-vQc=QegFIKIi3&c=ZYHu8$N#u zlH;1zHmJ=mlHRAvaL`hOin*sEEfcR=3kz#&3-bsBnVaewSD&1jU_4>Fdsx&hh;U=h zUKk-POH!?UQ!`l z9#u?-lS!WD-s973=pfseu^+2zs@2{N4NX6I`2hy?Z{`nh8&=}((4jO-J5{pe4e>~^ zCAL}9UqQ~^cewVPWzXQVj}`A7B!)iKC~Pm@f5(gW!3Z&ZEYYy^fy-xq`sQnES4)}o zYsB4iE~woYg*?oqgZkH<^x*KN*lKnbX#R9#&W70iDavU-$Jb>#{sLRSNnbeW!KvMR zHFW0U%B}ZTc>ch?ncttq#A=I$8FZT%6#0_NL6RM{F=eqcg$LTp-?p4R-H|<&w-y8? z*irTeemPx=2jezTL*??lnI6m9SG|!Yi)Hvu7YQRbi`%}VpQv&ftAS7{Nf9+CM9h{p zAdZZ_i;DHbFdjE^AMvWAg&bJrE@$O(&Cr2*Brn?1*M=#0aw75K_3if#iWSO29v*D( zSF1Leg=(*dTt`&6vHc1}4lM*>W6^mw!Y$ax+yUWIpb(@an~*zmP&u&0V2#`Bd4KcH z+6ElbE+jUtEn1oV@%R4VOdba_f(M?n_P?IpeC71i?`v?Q!|{S3v`Z2v`JVa883>kq zT*KaWvwhxbgC80{MLN3F`W|xh4D0Nw>~YdLZ79n&mUcsv9k_bhh&0*NzVK=9{QUgj zQ!kd&es!j8N}uaU4}8PvTp{MP8*SA&65K4veM9DcX5a+`zT<6wM)q-*-6a)9yo!iq zam8bd2S(ha9cb+*Kl5q8L`*GMA$nRkfglA*C=~YIG%)LhFN``8Pno(bZH^gk8*nmD zkAKOu3_wEw0InvPP*>TKA~=mYXv|v%e4jx@gU8&8$yrvwHf@Jc0n;1<&QQlt@Cr28 z|F}hR7GN%1d;zv}*@Ol@_7qGYja)VS@qoFh5YVp68VydwVaD+6Ca^fpWp&@k)3v&c zoFar;>a-KJ+=wdYUCarYuzVq2DAPS&p&ar9MS}G&AmIjL;-H+gwUEX}2e7WG_zAI< zff;xI$qR<5bcDeJJj8q2Fx+YsALNU(q#HkTYC7T>&^CNbdJWlx`)uh9@VE1{YVi_(7nZSe{j)MkRKfo+Wu^s3vEtfq*{43h#yQ}4^VChHV z#=-Jm-ixdq(i+O@F}nlx4>4@>;lz4}P=6O~gG4kUUc`DBfme?`_9R7npmsIz#0An*(nkx=xkua|ZhhVO~fe*jqq;?quh!=`2E zVi$mby^BG~$j@IclQvL5Fnk2)Jum?S%Q7*^b&S!QysFF2qR6ktRd>EA{o-#v44`y} zp9!S4?f{BT&GbZNU4|`vf~B~&m>BwHsxhzR6sBE5na!1Q{@Q&X-dH|-Js za(WV>U^vBko;#tA4x70QIW%WU_Hvz*w&O5q1cru>~mB7e;bgIvLD%c|!)kLHhm@yQVdr9Hu-!~jCH)8Z^6x28U&jw<@RWaN% zLovke&$%?he4#tz>$p*Znq;`_$r{+*lIc zvD%*6yY*#1XA=t?@6{}WVx!qx3b2I%0DN=1QJy;x+y8R$WUJmwN zK3YW>?U!tk0q5Ykr&T_T(c6 zvEb2;r`eHD`l14`GlXRuUN zF}S%?%a<1qbBlZBty-%C6w5L#000KV7z{Tn3kX4$i|ggO5FQ*I8A#u|Z%W}- zxhd2-kO!D;Bi^Zw3kzcux%b}e!KO!3ngD>0Ju?`b1MvYDiPMsg$6~XYMfQ8yNQY=?-51A_o!LrXw8kwPecZs z7(scv&OFg)g~Nu<8+u1(Ad`|5A%8yDt;4X^(wr%l24%~eVqmycT~q`;zfhMj1M;Ix zga8z}xppWma;hl62(DBf&IJBP$J`cl2& z<9#B@Vbd8)UiR4n>4!I|C~rtTE;&OP-tyWu5Id@hBk%1v7?T{PuYP|$e2A45@n!OG zz~%OOwsZR_tSrwk(jGR=lMg)F(R!@x$-eun+p)$AE_-(A*57Ss>vo$B9=-L+Umk@A z>J$+k_2t$2+Q8>E7D)-p_-L`C8Esy|5WB=UO35O^BG$t}#-3!VnFjWJWidE3=S= zcbAvC^m4-cB9Ztg5>6WS8Eg4lZEbL8|KI4lZKhwm{+rv1(>^leh)}RjZFI;fv6Gfn zr{>(keZ$SPfFBr@=djPl`bn|$(#u~n%TYw^J9zZUmpySxsh3|HbZi|ak2?58KJkJJ z#XJCkM^9YDJZzJmf!UcVP&)WfoA)9(jAGPd$4|F4#a3m+OuPa*%*Z*n`ba%8NZaM% z__IyyGO6UZcP!2FGedq{R|=grXSoSHs&}g!OYa4|qlBV+5+=1f-VjbznU1;I+YkBF zx<~>4PhTpGoVK+xE(Lzm2Vc+*?r!;(b6NMJ-Tzg~@F8!xv->*JGMd~;uC_jO>~W}N zLwob3xkx9yFGNbBwbT)IW78+X-R11gZQtO!dgaZ4o2FkflocQNGo6o9MJJ@&vzB|xq-DykjRkt<`=b}_q zUi#x%OU&>i5!Ibm!~5v@ja$-pX5*V2|D#Rii?VcC+mE`9n7 z?nz*|RhE9d1LKCOv&JOv)c}Oro@{#cb!WvqOZ-|uz6f$&&U&7I$aT2e)z*Fk@+6T!gGC4XqA${I%mB;$ont$xepj?R+&@0kmAZUv>dfc=#f!i5 zZ*T-bhFy|e`;~BHbo2-epbg7G(NSh&-Wsa8q%j*F=@6{*fp@p?=aKwa>z#jv+b0|| zp)B_u!By3Xtq1FO9KH51_Zw*Wk+XP|X{GhSv}^B(aJZ%SjPlY$tuq_xdos87dONoj zAAG{jq(Eaiaq&Xi`F_1N>l;05YLxEG9`}63aXTuDRD9eAdMbFJ#eC*7tI)n)Y^SzA z|9I$QOauFkp0NR&Tj|Wb-}ridA+0oXdZ|12HepF{OnsgXEOyE1Vrz?;K(=0A{dwl) zPu_ZEw8D3@F4C04w|;PVeXeNhV0%Bppr0<<9{KP7I931Xigy3hxxRE z0j^qWnTT+^Zpa1zzzl-)qq{79-|Za&0Q~IU&-T~8^Y`C-rK(8p|6s>`6tW>(Q{CZ7 z!rK%I^~f_Tf)>5xcY1I{exQI*ID!0i4d2Rd8AIN?2Xm5R*t4=w?&iGJR%V%9IeHj4 zKQmGOpbj;I3W0^vzQV1N)2)5L!3fk;<)&#g0osy2#}`2P?r06=4tha{hQZ?4*eE?{lpb6^L>cU` zFIEj|WwGf95Vj+`dQC63mevZj?fu&8`CR~jBA9B{%j26g8}nFv;;hfrXY-9X0RV!b zC8iz+8Vvvd5WrXzLLi$jG5+Z<_@d|9{&Pceu68JL&h(M)uO!q4EVT9j0F{=wfwWnX z_Qanm7;qwbvez}?3S-WsSN9P(<=FyTsILh_(Dv5d2bIIS2REAWVt3D=4(r?A>gDr& zNC+PtABZDEs5q&Zu19CWtHzWTTu(@iQ;yYa9}ioZZw;urBZBI z}Eg;HuP2~UpC>zhV+om_kH8y6t!Z~GQf2r8WFF}R_08lDQ zhyg012muTu98-b87;X1^$M=M~LPro6SFMlRc%C4Ay3Tv+SQ^*}XDX}eWOG;C@01=k zhCJSON%nAQ%Q7^`EI=LLMnDuL$u8OE?l!8tr!H{&nwbx?-rzC6T6XKmp{&;*%s$AG zPHziR4s0Of9CDbG;jY?7&0}-U&3*_xFiIo*t~fm$v3MQULvF-Wc)_MLI^V0=D^BaW zi}$U_O)iA!UbC)MUG{|AhWYp%TIL%@%YEE-o~`zjtRI7={-2OUFe zApQluFzNF5unr6=tiAl8tab`nd4K8k!HF_uE7|kU z_EmE~ZW!8v!vTFK+_e_14!R%gT#ZZ@OJ8L%Y{L04nwNAOw5PP2a z;+tHjMi2V~7(yd9`q)smEGre=J2kC7z;Jun!Y-wAnq158Lwop}9kt9l^uo^1I8~nc z^sim}-XAk0$NB;X^Y_pWH9h$GHSsS|)rOaS%Qs$L++J~dBi2e)_vfW%aiR5N)P=!wac5e)8vKMG7V_N=u7&hpfW~@BH;kwtlF}biI1- z>rOgFP&+SO{UaAUO5)+bQCH^1E}V0<55%@4TP*FHdo0_&287PuM%FilH!0Wm|HD6} zM~5)mUjF^}YKcKxVC1#G`rUBA0a)Mn|KlHy_CCwlLJR5d`0zovZ2RHMf7ED*7;v>$ zwy=nx5&Jp&!^5R2>4*SSXU2jW?`QijEZljQZ~@q%O%q>+3U#(Jd~fjvgU4v$NY*yn zk{;CWUrT(-XCVkND~6R33#wkd{%0xYi&)gXT>qNa=eKsG*_97g3Uy4ni@jE{% z=H71m7TU$XYyS1FRD1A3+#g~dG2Gg~r*Y512P2>S%I=Yg;He!vN?Is$Ajz^}{5%_5 zH4S4~?j~%qrQEF-2*lntk^O5W+32v%&lTMta{FSdy>B`V*I?)FkG|P(Iz?g|%T_72 zIR5x&fBf}7l<)yM(EaFx*F9wKjx^qPX5Ol~RKt+X-Hlf1Cf3{0^);^U_jS$l|2Jdz z*=1LH-3R_TIiGWL&Y^MustQ0MqtUt9?8Ih}*b+GuC0e#+dD&yx6YTNwSTpj_vg{F+ z6KRnYW4G8DjYcJotD!T?v!*z?=#?UY$xVm|c^HFA>oBh($(k@NlYTY*N(Kgi`brKz0c(}=1 zOK87i9^J0!J#hcP44x&zjP_T*mqt&Cj*0L7{yz;mnvTS=hui`0d9l26e>g zEc8D90UEj0-?Cr+gKr5#!wj##f9tnw?5v0v{&4T{MNgOz0gYQ0EZJ|DT_E)>F zeLdmyo_OkC_3}VZs>dw%Qo9yzZ0WxK7a~Jp%lq=wKg87b&g1;KU;GEGi4mKZ12bQ( zJZuegbjlUe!CLbAC1(KJe(+Oj>IH}Ik=VzW(@omNjC?Lu&%8Aid*SBY=C2++uEmLD@?hKZC-VVMv&^4m-WP5C1 zQfkA}PA6#PV%nt5Pq#0}cu#7u9-)J6FWlJgJt$XDaol(;r(Ow31HJaWN@o|zDUFqt z?@Ye*#mvpc%EJz%dj3{0k+csZiT}3m`~R#F&Te;&jqr8=07@gI9oNKCLF$jiqFt%# zX>|mK^v>C3AlHz%M+gb-DXCwOo2rnaAgJ!15FDfYe_bxhhT7Amw#Y-KTJ^=!9aHt8 zp(fRyJr$XMHJAbbjC^i7GJC=8d_`~0kjL&l(AzqM!cb=q-i ze(p1d2&@}o{?bR5WyBdlHBDV~gGkzt>n@UY+YT&%rOwVPdD;!oUVE1x8tLS-VanI8 zE&J?=G!92_PF?697J0csiVnEzoK_AbPP2B)TJ})V+GDDu?>F~yh!dy1(K9m*5m&sV z1srUE>KqIzikJd&p_LK4Spa~d6zhl`2}+cLc59_pp&hnG005MWXg4a-hu@a3t+uO+ zR@b-)gow9|(%y8OX*PU6Eb^+aJIPB5A2Gs;|TWrG!QK}IY?yyam-R63) zxdXwYjI|F}?=mQ%FccG_y>s?~Udgu}Jt!Xl05BFkcQRpXATDNj&|OEA9ZYM%drx_3@RhC5t9KsVRPTgXy|hC#*9j zs-zR+(+_LQoBK-kIBREKC}*xVV;JWl+rDaq7px;J>Q3h2g=66(Ni|uweW}%X&}+#S zjw^LksZ(XSjC4>$Qm+5zDh7B|UT&x(+ z>#9VMv|BsRvF|Ms4D=I;yB}bK+^BC$CvkL)cLGJBAT$EA48T|>L7>!ehs)dFuo~MJ zqfr*cy1IJ79U^0Jb*V+oKnD^5*%r}r0lPcG_z72jOcd)Xy25<^jWSJFitqYg`o{KP zX^is%gQkpw=U$xj%?z;wf6x zez)X7#%Dr{mU_6p9DKpMl?aIb4XgDqj|aky)?cIsKFp(J>POshe_>~!W(FNUTm?2R zJZN!e1aXKUlg-y`fnlWYql&h>Zu z4k8wLRy)Li)q@kNVK|+>phHx zU+ry{j(qO5{MA}}eRnwZGNGi}=||L~&*y#DH|{?MsWEk}P8^NP>WA~QpUX$@IL)tB z>5s?pUy)ojf%eV% zSpY!acE6aL8aS*u(%4JaPJUNj`vNXP`5izn{0bu**BEbh;|Z^aJbV{yGm( z%8B>gEfNd`Vow8HFuj^9hyPRC;b<>c~ zzw&ESHkS(Do)69VW;j_VypgBmqd_}=FZf)Z8_);(n*e~&oGTe~zIkP> z79Z9sAAcb{1eiUC%LM=+-O*a}N?3Uwv87O$w+xe#yv}2G4ePQPZn{lCE83v)+^b)< zXaWE*=6V9fd59gDSJPe6hT!nsdMVjoIo$ghioEs3@Q?xPVI5^oaJmdpQQZ|d1*@`h zayB{awzgXr|M6Fpf&<>Z7Ulk_&$-&7w}N~As*kQ6$o%|0@^F%UaeX8ApSHH8lcbUAuQ0+E#JbL$A-wGc2rEu|v<_SSuSN<#o znJq&tA&7P562SGS%ltEU(I zSUsk?%$|QZvhUMca)%oH_}|eKQ&fcxFz@efsSsz)nHj;>8{tG)?7F_lxDNgoodnEMaPn!)qZx2bC$c6 zjZQ^CYwbb?250!tXEDOf=*V_yuz!Py&o0#-p+0PaQn@zzZFcO z6C=o*k6dr6p z9-6dWUH+i2s-E~M1{1EXJQ$)GCF!&$?I%t;lT$Aw6s5CWgTq0k!MY>yWT$n?KP$C1 z1dOQbmSyU0yM5~TNvz&nZr5y4CT6h`gt}&C>>)#d?QH*ORr2WV!CXgPU$2CxhOfT= z9)w3yg!N(e#xM|y#vqz>xB{#Lgv*2|ms%-DNbnUpn<^9|ynBbCq2=(}}W z0Tc`v#G|3bgPt3Ms*)s`_eWSWznUAq_+quIImu8%gXSPTHZ~0P;WXEout>YJM=iBB z>Lmdq?4fuNk*@3>G);(5Avy^ZL*L0ZTpZn~4K&lFJ!HgSAB%NGqzRYq2fpi@cSm@8 z+X|pu-!CyWTLm+Rn!Ud!^_j?1oOvUo#l7T;;!IXP{P;nHi8%c&$!eHcbx~CyF*pn{ z-Oj$u$8m4lyoXhW3Jyl)V$9Q%5jlfQM(W?a)sG|%INjj( zyImn6AFi2^?DDFkvw!G_+UH{vE9?8r$WdkO;Bo!2-W9^fg>xtQkN4~DIn3_#VilP1 z=G+3u*bvqZ_^Dc}Gie$5$&nA={5Ub?)_N~yGe7a`lVL(?fl4TEEpy;-PET_#*R`L0 zZ}i2lY+So)8#DakbBDJci9;Q~cc%B|ozTm#Spz3xRZC(58gaUC0B6pipzb;c6(_Qd zd%BOPbhnyz2XIF117X)Y=5oh=g@)W45B~bt{QM{Hy>skhw1S=Bd+D4>D58VOkY}aMWSy@vG3Gqo>!o$jS z-uvXxWV*JmM@HvFv8w5t3>Xg>a}_-AwMOy1H%&eUb(>4?Js5rFHPqV5^xp|n&ia)% z^D)N|I0?xW&?GH~w0v(NLXXOlT{>Jc0;at^sQK66yd~zgt@yMTkP5x$4xOtimj(*v z9*ZcF${l7BXI>&uUEML=Q%|W71)aR(KRC~pcgl1+>CW>G(}sR#5a$V3g0om+0I>a@ zo$ZD1SDKGIL`oRKKuQTeo?RQxM53jMH8U z#4iwV%fVfMnL)Euak@#e5kmV;F61F0(0=!?n5miGBK7livyU`w}z(?cXDe0bvz z;#1GFe&^z)%SVSNJ<*xW=IxNw_k9 zDsjKV&Ah5=d}R0G!=bTxWaG|uarZ>8I*7t|es6}vHyk};A=`5K!k3u$=tjrBV%e2p@FJ69icchUhn zq(!QXwrWng>KateH=$}whz~<_*5C1CAzKe$AJpqyVoZnl(J|S?qqgFMdttP0g~vtqT5G-H9zLGg(5b{WTbytn zJg73!P%O7iJ@Q8U4d+m+F5pdnm_LdaD-r(ibl0dV%hE}@oL|`|P>=V;)pzbV5ZB~P z0!>}9`%w31FBA?UdkxecyBIv7&!0gz7b=mNryYxLtB%>~>Ibe9&$RX1)y1}J>f{TB z*40XWIyu4&J%QQ-(8AT4H|-?!yB}Vr2T0H^#UJ9OyP@B zI$vw(t=xTdavJfjIG+ymnN3U4KK#A+PCe=NdpeN+tCdIJCNFkDPZ0%GAX;~>*IJc_ zlc%0sxqZbsE>!L}0RX=k9dl5S91DE#_V-QCxQ8DZ??bvU({I zn_q2MN!HGh%6@x7N11d&u2?BcC{UmNa5&;xE!QgR*u+S%w`cqCM?dkVrqzqN9vm{s zG8UrBwJL)i53ekhUDJ+s)BuWDE;!sz_0$kwz2Ogew%R#AKDk=_k;8LVA6ZL z4=&f7C%fwV{gtRNRqGz8rm2~R^0$I1aCGGG+BzR28tdJ^n^ri7(mql%3_l&-+`BpA zn2xFQ^e!zeVUmmIzmqS$pyj0f2&6mBbd1VXgt zMi2I4W&%-R3>gRr?R}%Q0ruHpYg|xz)N>KqUxe%a7Mx0T09WvSPkJ zwA@|JAt5}=b`--f`(44AM3(Y=lpY(2^EML8Gp@+l?87bA0e34>72a{ym-s|5(=N!Q z7@j%R-BLWqf`^>~K#0~(pG_*dqIM4kMBRc>2a&FSlVw@?c4a&$Gr_2m`}p&W-!hFQ5fuPogEIZ?`;CAW`OGT?4#CZA7e~YCQP6;cSW~z9M+&P+hXsB zjwC|>=Oxx{l(cOX#*8TCK{3?2UduZS+0p5J|NZRFUl$%8)Ou2-q_%()?$@J~QS;(8 z%IG?$u0+D9?eqd*8^Tb78vn4?QM+-mU0p17YY=1^@D^q`QH)Xyn+RaFaEu~GYgoBo z4dmJ=Cto$p@rKkYQH@8xx2AM7Hp$3?ro#rzmXpvvUAuP}pVk^oqFwi;eCmnuSqrB^ zBO~*PQ;yPs@cGxe`W;1TaNxyu>qcK0LV-n4Zh(*^=h0f2%}rZ+76mW>pfn&%q^x{$ zGlzJaX71pp|98#pE|REn{YMxRYlGv+%sY`Cpi}4%_*ak01Z}s>HAHbGF_>kyH_j@KFN?YS20TaaU6<$-MTT zKhUauCdvQB@891$Xdn>Wr#`#7cd2HGg}wc5UCw-5N68HH=%;?YV;Hut{oCKl+)P_- zhO__7TK7XfARl@ervq@I9j4bl=-V(@k?J2;GP|GL^F!X--`huQ*i6>k-755QhXdqe zh~RC>d~R{i60*DOtZnN1G+(QA&LXr)E&;|vm|=*%g-ShhC+1P=x^}Yikg*=yN|6b)^KwV z8xYjQW=%8bwSwe5M*2AUoo_oIM8)v&AOGRM4KPh^bab=ytrD>Y?#|zQ@JQrFe4%FJ zt((y_C+dX{{@}Nru_?iY{`AIg*&LH1>-w{ul{v;sF(KzTUwBwXDjb2#R0|6@1KEF= zD`wh;Ra|}a?_5Je7~A{k$A8(2hz%sP@!dZhI`al$=imPJzez`5f{56UzVmxWLbD{x zE$6=*7@%;)c6(`68FVQm+kUjH+NBC(lP2(f0n=DX25#5WRZ=L9!xN>gj7&p83kl7@*%P9gKH)6oz#u*XU*% zrMrXn;Dd=u((kB>;y)Xn+wQat%lgCH%Wvj3cW(XZ53jHF^O98KYls^F(9x9GsWZko zDyR2?7EOLChgIhL|LUIqtq)o7;m)JqfrS~ofZY7JAaQfKg&&|eGa2zbsJx95LeqF~ zuUD{R1PgmdzM9^AXAidwPvC2%y-PpEK2vZxkw^IGBiyAKFkg*f~KjbK&8b-lk! z(lNp9p;K;~Pe2s^@Yl}ihc1Qyo@c)42CL=)G+n>2xU@&BE0kV>kL9bnsNKzi@HsR{ zia-4GA@XG3H}$>$@EZYJ*L8IM_WFMSZVb(x`Sj{18a3<>G|F$i7oX(YW$%ao>31MC z#yNUduKtD_B^#vkU#;FoL=EXU-A8QY^%4&E1lM?_u&N@O@UA*=DrTKpdixK(lPN+k zS2wZ#wuEzNP3`?$WMsEn?hRV1qUNvFPz&PntE+R8gQIRN9%vtaNWJxkZ||(_-umv( zzW47t2ZLeG-fihaO9X|WD+SVNvo99!H&ucR6^Ks#KLDp%*=%;b+dr*~ z_#`SI>y1FIGraoV{}zcw5teGNS`LFWs{GXX6P~oIml?eF_r5(Ic!IR!000id|F4w? zD%u>m@P^JFKjg)|t3ch8xxiSmbPK+)1n7P^@l_Oiw7d2l4dW~UbZW~uF38f0?9^uI zUJV^5i@EEeV=OH@>W<0 ztI#SJTYdR(wW26Fsktuo^9V{=Krsy!0Z^cdZ+4ro6CoKCcM%jxdxNe?jYbU&a$m`+nq11Z12kbVllU+RPu^^C?uJDw_g|3ziCnI zW}4;uL5jWJCi6lRxLve+r(Kr(N5*Pi{qXLmx@bU=$1s5M#$?$*2tl(&!p$s)M$Rja*|gu0 zy>U+%l|-kuQqS-wdV9N=EzPL|O%Zjus*rUlYUSkKM)uQ+)#;a(m+RfZ{#xB=8vEsq z;Q`WDG|EL(Eb)$BAtEP+FIs1QZp0gNDMKGOCg8rV4J=qT z8-`03OK2!+b70A4VOdkV7-Z?N-fhXG4fjBlE6wv9=_P3f!j2>^;udP_c!!I%tk@}5 zy6!PjSVnJJTMf{6*mSQ*-zAM(FP>ypux#o zE;2i9bL$g?4C>=?l0s0cx^Klq1hXZlm@m?18AQ3wMY6{~GjYmXXz{{G^>mP2bwYGftbC&L3FDh&;N zFr2sup$SU4>6!MLlNa4K+!7hPhaP3Af_1zQ3TbSk$+@7B6K>G;qEqSFf5O0g-Ww6yMYrsN6@jDs8@+t*&0F<~r?cc4LVPQH}0@9=w^e@8-aQA=%jD z7yo%Y_5=~nA8h_rt3ufK@1&?uDiwhs3GWvW*R-i>YFVMkE1FsL7>tcIb)D? zzbZfR*)JHB0|BKe&#N#U=mT{GpzM=^)yIfY!xwuFY1QO27srnHd#i^Rzwr&F;Oj5G z7qtDu5Wd>5J$COU3x1_^hzs-gw9N_Ei@WRDCnu;4>BLu#QgT+uqR^KcQ4vQNKg4S3 z)7B`7SjtOZ{(4V*)`Z1i>WHV!Tc&j+a?&~2wCqsom0;28YH%Q!dId63nDV?DOd-HD z`5*wmuq?=mixtIl)P|W3UF+N2M{om{G|k?}fZ2s{%diFjlfCm^y(g*|;ePg2SgQfc z@%-n$rkHJ9C!d=5;y~9iAkRD%0Vr%Da(Ma~6h;jLpL+cQ1VQkCj0IlSB?G0Z?uH*b z22`Eo!J0jC1|PspxIG&h0drkl#@!BA*YyI7X*?@X=y@be%7;2d#G6OXz(fYNMUNc& zABrsmqWnH|6v}sSD-t1zZg~$LA+<@oYM6c8t0*BFP?~z^>8v)kZQLfjaku+$|9gsQ z{3O5g!(zTHVWUav$)rcuV?C|C@t{=tt8cx0>+PjK+ne}WT{T=EZncMBNXX9u8}@)@rl%k$CZ(v z{`GIjc?USS9=H7l871rNdT=+0CS2{Vo1CoS2a}#>whuGUj5GV4^sgRadU*x)lP}jJ zG7jM^83kvbfLX{S!!P~ZS5@EuMs$q(j9CFZ-k;_KuDh;S2Ko$BPzFGO1o~NELNGjd zj;A5ZP)(yG4-DCa+J>Q;LJCE&JOrT#pX^w6Tu1B%P67?Uh6N2aiU+R2AY3CvO}BY3 zydf9ozGJpJ|Ge(r^DO8@nIi`LOC z08GnLtR)PsF`m(QeZhO{3E*INx0mHk*MXBzqak%wrJ){fG%3kD^yKTjC!x#MiI@M6 z>o?yv7e|^)H!_!cbu8q~-aP%nKlgVwRXwxt=zZEp0sxlVwO>w5aMr@%gHi*Y_cTf0 z+)+4w$JeVCkSR9%C6rxfgm70MKR5iDHanD2r>0`(rjZ_O(xZ51cCh7QzT_GD)$`|% z{M@;JF^SrAH1)=>%$*w_qPmNO6QC0h=ql6Q6nhz^7*cax+&TKBt09%B2X^j-Iy;ha zQ-8hw0V>gzMbSk()s(+Wi5IpOh9mKN;ftQFdw=Bc&$sIvDI@@(mcQO;ZM(GwKg`zF%8;sI5Ui_eC(|?= zBV~)SB#XtcD93ko)l1T&6K-3SMJc2OQ5c_^2+biJiLYj=9Ew?7B6JiQb30XNRDvJK zB_UERGe_pvwXWM+L)^%XyW4Th-0xQN-C|L*c-JHqV1^?~#z=^kr_(6GsIIjC-`K8( zDjN!Me4d)1VPTXSP?o>xhy|crq2q;kc`@jb11fqqqJ_*bY!Y1m@ghQ#)6w(q_Xe~6 z>4Kx_7UqhFD>OO5P{Z5BPo`3?N|hBfgB#ZS@Q?tiJuthsdu3eSq`BbD?&5N(=1tDg zc6Twqh@_C}p?l1iu#e!Key_i=kHbjZYtM>3PDb|i?y*FGiO|rNmV&vQYIpYXj|LUo zNt0MYl{#)NWw(ismTrv#^08d^ER^B2;oNg|A}9Rm^Mlqsge~+8McCdz?W~{iw!2VY zT%`nwJ+Rt#gV#`>WV2yzl<{XumpU}LwRYXYSY(ighuHFZIiDR+Y``6zveyb7KsMA2 z?nhzKsx^B@SvK3NOs2hRd)V%s*eQO3m7u+)+s2@07!q+hTHJ3om#UE|XRcu&$w)P0 z8hD|5*r!4sskhT84HB#{#Mqdbc`^|6peP|2CEXP3h!e+6+eE#wS;IYy-tzLH{d#6- z!XwJIgMtgwdVUTMkl_Z~<{LVj_Mu9(p(|`#(IQG<09RGEqh{kJnM=^RlVDcbQcqjy z)R9Pp&JwU56{TDzoZ4Mq4a=RKE>6wD?ZL>=#Fg9-=H!#x&Fom4$dxvLmM-p!PQ>4= z9&+v~nT(^CAIjDf33j*TiUue8BhYZc@5K#iwrAd2It&k=Ddykg&-0F4R}2K?-raU* z5YBQ!GL~a*1}fwcWzd|^JHSW^uL~ZrCG2jk*ctz3s}!6HOBFbo|LBU~R81pnIQH;H zve;#c_#?9!3b_dtyO~>b*oO~V*66LlE1t(#eXb66lhzW4+_NPDb#9qXntWvQV4%4Qt2FRC|xt!v|c|p~XD2lWBm@K|IeGzM4v_%sc@(mfrt#bShTt zuPxtyP_AZL>z(9O+@5^WK{XHeGr_qprzg)fMG1=q2bIcG+qHeqytQ=0Nw|@K_|rH4 zKs1ke6GP60Yl~0FL~ar=O_-jm)gedPYt&NBopn!Oo>$OFe~a`d4H(s`KmY(B07*na zRIyw(vJ98jjQXGgabBOHiA*I2$A_#zSBdX4*irLxwd9#{7ZA;NDa}uqYd4nb5xbkb z|KSJ2aT_ug*}VK$unXII|8&Y6L!iKH2RFA#=_^k~KzZR~M&^fZZrmX&n^0r8vdx=9^{q`NM%TUGV+&-Q7E-@O}qDrnXN4{p5|2|vqG z%{yoT(+I9_M2@s>Zd&uOmlkqD(vYwZRs;=W}mjf?#WpZ+6F0RB6+6h4Fcpy2w@ZZRqx0I z8=y8HUr!(Zf@PHM{OrN0p~>Qn`(_}NcCldVft5ba`4jCy+NkHJzWOg`Jc7bAU%dEP zR1pKmPS8$QJp8;fmA>)l`kZ}~Jk_`Io$}s+4io9fIjP)RhgY}!gP}(ye!CPTjP1!| z1x5r*E6Df}_vmCS&fk4-n72Vk<)O^MQp_^J=ri5gj@^;q^`g`5!C3SJa`;e;`%?@G zBolZI0QQ1~*uOUlblKCKKCY~EX^RW+>-nWk=y!1qk3?^7u58dyJw#@3z z1pIL!5DnQ|y~L_*N%L_2jPfmx!M9vt{^5>nCz|mJ@C?D%-`yA)kKW!>+U#biZY!QG zA_wie)p+!I(O$!Eue2>Ymle{_2Pu!+^jd<@wv?P<-Z$PasLcu zV5kPwppJXW78nohZx{Ps3np~kuJ7lXSxIDs2#y5Hl?R?ljyBMa&muY?hH<;C{aC10Ev?vy^mmYCa+L)T1`HZfGpO?XCQ>C2v~@p2A|e$~3}(%%uKoQX9~Y{8 zy8VI3^aj{?vtuvY(ud7L^l5VMb5=doL|=J%>hob&{75Um6@Ssy+U|uCo>Q2_y2l60 zeHO(^@}S+(wyK?nt!iVlXA?2|Jwq@f`%rMuY*~?UaR4AC0AU7wbT1ix2-4H;$9^aHEj*EK^k(OPDp%eQM)-5Si;P0KV~tY`1~ zv;xzE!WtW?Zr92tr-67XA1qy+VwKAF*fkl>m6W=GbrQvIEDLrdX$ni}>pGI-NP}JmT#yM_rg|>K!Q* z{`D|ZFxPtxar?H>%1XO^#I@6D7f-x8>cWcM{zt&(9=h<_<$wK64frk%^3cKAG3MEC zZZA^qH8S5S9uhG6-O{siXYo)KdfdRA{*&6tQioK(;u{NH1w)$9_T>B zCpgR_a2TQI&AQi)G1AW~4Uwj?u@ed0bzJTgjtt* zwK<3Dd5jK4q?N~y*A%(gb3Y1pAf;&yP5CY6XfAKC1pL%%Uw`HF(>C9rXO}ddF$ex5!^{T9^F9@soVTMQgz%hw*oo69mfJ74={CT~@Lv5gfU<$~r&=cA zDjN3r_~yHpa3_1f9CL2H13)TY4+V+2zaE{uj3;cS+Z8Z7#GseW>b)KI_XrERk@{8@^b{J(N%_ z{Sngf%T|ZZto?;8I)romkAL(wJ3HToz1x5ByP?_7VLiv2fATL9u@?xc_5DBoP2XN( zfMLsp?}tmDf|79S(bf+SmRQ@NR9!-RSe~)B#tpg1v4LTdIPQ6-LMW-=SSZsxXY<0w z#F>l5mcHn-?Vh^3^^uFX>#=X|dU}ac#?*^mqc!-(AYv~TH6T*wUv z(hrxe_cRfep4$BW?^!4v;S1Mq{Mb=wWlXDTA%(&L)GKm}x5}MChqZs4%d)Ph%~U<9 zIa&zFIb`_gMUoV7WXEyhU!ou0thQQTdG+O{wK2H8z)`{4wJV2ui?l>FeF{P_@tvRg z{1ei|g*U(TFA|5@#MIM&`5*t+zAF2Ueqp_^D!P(Rvt0ewl__4R@$UEj^p|K`f`q{z zfAgO)zO>A`{&eBSFu~B?NM>_alqG_6aKpzoKDvZM)_BKSDCKn8{pp|l&$Kg&8?BW` zcQ9$J&C}Jlf73f2geljLe*b?5p;@Hv{_%Hy$KxNOnaa<;{jDgzHtd)&Xwxhe^#>cKSzyOMvND z!^6)D!BG5#Bgk22uP`vsG86i%nXkM?BIAHDfxO&u^U`4u?6`1_R#Q}c511hZDokON zhlUI#r`0mEX3tyq9_tb5`n{8);@z;F@}g7aXP!e@X##@b;ha5IKPIgqU8()vr%SQ! zvrsWcwzJs%F>113&|*`|R!>bm8+i0!NVm6>n{j)Yzy8+Y!@HS{TczTydgfBO*VrpB zWkm4F->3tE5WD}V-8Y?8Gyp(HSDy4n3R3@X(-eRJfd0m0Zo)Mo*itN#5(ZYG)2#)< zLSwz_vqBt(>x#jebZqi;{K#3$GWwNXx4A)c5zDf?Btw-eI3rS-jmLvdxBNgPGVuMJ!mhyS< zWqkpGa*T#Xj)7)^fa8OcB_u%xrk=M4Kq~cySW~QwmTtnfeZBR#4fV~HPUC_*#Mz$l zF(+mNlO*k}wW#Y>T5wGWvLfv&TKHV(I)G@XIPPu33FhlNIMp&5V{T}S$+n110R z6{sVWp1-?26dbWjo-ap7Xx`5T34x8AK596UHGY_BZuJNQ-s=6A0VduDE=$X|9?K0a z)9j?Z6R9)lxc&Lyuy2ZYZueV-N)K{uh5~3?>5~W&aSlTXx$Q|ghPb9G*X4dEUs9T? zex>GvsDmbKs2xq0>qe$-4(g4Kx=(LSfyj(Ywe%ehtI>j~4_c-0LT7*DUSqXyY8&dB z*(*rZLXc8CtlE*OFjl%&=FEO4Td{gJoo5wU0{~cN!@4jMM07=yb#>qf9WB)Q2h}wc zpOMMc{{BwG96*kToj#t=7TkQ?fn>x`Puc*+BfJZaCoDq%haKYGy+)hkf(8iFvm#on zw2MoMs@D~%lX*YkH}REd$FY`jsD3~dGM5DbwdLOIwyLTA16n`q-CXn0p^O#4yp5VE z1;?6B?e*o4FDyUXX`WVz!fd94rkDuyU_OXvZ`K!nvKOnqo}mV|{TnITx*u(qzJ+{2K2(#G90 zle57ma4aw+y!bhZc6SdrF?|2=dz&`wbueaI%`ZV1=D_FKBeNYnq&c2@E@LXqlVc<95S@9Xt&#@M@A)u3A)Z%5t&J;kmvD=C?VxJS!q=_4lT=?!kCWQ z5E_H&X`k2Z(_N_Ns0lV?d%aQKFP?vGT!7H7uH`HfzyM(o0DvT;C^oP;+Dh$Rp!BZ4 zx!ZWK+^->t*4@Wpk&qmAweI4)I6+yFX9DDFTq|oIXIkCm;Gu!U99m@CEbGik%z$+O zvW?-hCXIFb-V3k1p;Jx=UOMV~1;xXSmYC>T;%jF>r-i55r^de|iG$YbzczZ*Z)|0s z`K5oP75yRvMfiUl#a6H=?%GNf{E`kv>?dxhtK;-bo|W8FleTT-$gfY(NZw#Zi1UMl zP9hv{5a9ep#ExNR_obizB@GK0U3o%y5w4RkT$|6CM@|*diA!ZQIPAI z&%#?Q{=`V?r3U|aKXT!>cQxKjFjGjL4iS@~F=qq1>A&3?2lZh{A z10C2ro_-veHBBOE)AnqUQy3iTVbvM`usP+GEy`=N5BQ%$NRlO42R}|G?DD>bk+I(V zd8N7z3!!7DU(YwQh#U**v(;RQL9HY_=x6sdH{2VCtAl;5lO&NNUCZEY?s1NXVFZT} z#Wbvjj#6M|`k>nCU{Wt(7wa9Ak>FzvuWTA{^Zl`BzM|GlL}+r!K}+KY-2hBXYplNq zT9#!n{e9otEm^E=e7jO~KT+H3-soj@<1jJx4O3lRj`sic+-VpfD1OXTHOzr<1Z)|) zshPF8;}(n?tUGb!MV$^1mU!fge-Ge6+2%Rpi^Ld#F@j31H1^!j^HR4nbLKPt#GsaW z>KFbYFN~G0eKIls8^iw(U+)zq*>N6d#`X8+y*Iu0Rh8v^SDR|zjYh*XJV*d^AVoJ^ zO1ndynLR7bj?rjVD~-h2(QqUVDN^K!6bO4tANixtr{-Q5z!9)J)+>Sl(AhN;FrhuK&`Zr8f)s=M!$``N)` zsm0|w*S@m4K``|2hzYjuX~kL}>sq;6_tdPf@F}a=ZBa2iF+vs_Hs6r1_at0x_Pu28 zZ!ailJ#+WkYUy4@_wB1pGr3@q+v?Pr>#zRV&H3EWBSEQ+@TA}q+eOm0ZwyqASP9AW zxISsfJ`w)%nZDC{lG(eK_GoUbqc>Y`PL%K3?$1fcl!LtAH^EjLr(^6&Q*jn5m-Tj% z&wikq5M~RG(Ao9MoMk`nnkW>6OAccP1v_=*5{HMoH`*Pz(fDtrZ>LuX?T+o#Q%uZK zZe}*_6o(F;*k8Q5v-NXr{{?BTaeO37^d|MlR;QNK>MM`y>)Z4H&-O2JTv5_hqq=`J zpM0ZRF8^lh44v=<#>dB=eLATE7{Qy0+*Ot3b`1akO!NN(SU!>tPz(Touwh(LwD`%} zSFc*)BQ)*j_C?1KD_G2;z)4*-9CTRs>$;`wVcgy3X1lh6;Z|KX6erlPcAARZiUKYV zw$}uutL3`;>c$4wP9ve?9#n;gA^Usz?R`-+=>$dwL1v@wOr*_qSDR2W+jlpzL-*W|KxpoQwz_f%eu66Y& zsW5XJmkd*vt-Xp@F%t=?-Ue}}Xm2S+zc=FSBtKS$A}S}}-MC$@Zg(6@%yp*Kv%WizbEB{t_Q6-SwiJISHLJP|k!u6) zKYW zTIIdg{NrdDU6i_g?XF@fN{Z@A9 zSb$&4b=*R2J0I{f!C@!ad!V>p^tuN$sYSQTuxJ)|XLmdA1xizuHyeBX!%ySZ&9&QE z0!9RziF-M35A3Ysl53cBx$#gLX$K^>%LE(-R4|9XZi(}E_JydI%oPx^S@8uXs`X`&0FoFEOb|UO6CMQ;qLU5I9rP*t?W|O` zd*q1_+E{B76V?PCXv>xD2dS#01!}Stc~Z9(CkDz&=>Tu-n(8pXM6CGhed`ORmZAC* zHQ&x|k_@+sP|239i=ejIpfzTQ?hC$9Uc3ym)3+|&2*rFxfq@YeCt}orqk=o{XHIiA zN6x1pg@#@3LF2YuZ8Joe5;&RfT$~9$DLc5WWcA7LNIvl-v{-6Ib1L5-E~T@@b}rec zV24ZBzB_?a_}NMFNQv2sch54)xYnXcnT zp{+ZEdU@rH)lV`W*}BccakQ>&&cC0qcyFc_0vBx9?YaGpvj2Siuyl(}-~!wa1T+xc zY;mqoa7z!~;ns9sa85OPF5P+^vrg*uMrNhzv)HtLC)dC`^9wysMlHo(D*aJmKj0#) zZY3ndCbF6B;P?@bt@Ggusd-Fd|2E?7MRclFU2k}4eP@v(gv7(XW`V1$ZHG_2X!G=$ zN}34u%@FRq2KOdTIhd`Tou;ej>A0J1ZC#-c&Ia$@ONaXq4Lsh=Tv4q-H@g%4xqEw7 z3Zn1-r&q}-0jDqQ?7q+Yjv(oUt}{+4NEcg$u>sK7YY84J3v2dj@8U*dU_>PEeL$TJBlmW)M~>6T^zEPi=&{GX6h=TE zZ%jI9GcwLKQoQ63V|3=Dxj?)J7HhDt7h1RkjbJo7Fn{qU&Ys6uyj!!a4)CPtx0PBZ z>S`d(Fhu)=hUW004#H6VBk1z=+^@G2Q{%ZtS4Jx?&j<`xYHuZ@G@@SoXmRT`??bjL zul?ma%bUTz&!ijo8};nLi9zm{uWfH-V-shqdXeWuS8!UzI3#_;-xC)#=e1wG9i2Q) z)5^w!4+jPZ1-~cR+;I&aWE`M&E#>Js2gANn=321-WTLsT?b(Y2ZOM*|k4?6gZq(WY zi&j=|U8Q>t`0<_^?xK3!O-*9|8C1@q&BQZ zlulPTH|(hG8du-M+#s7-*CMn~$nGUKRdSNIYm%=VFc&~1B;vM=-9vW!aaV|JZS=$_ z0@8A%0aV&<6)_76)fOa(QL}g|;lXWwTj4%AY9(9D;+=c$&;dMG%?q!@u|WIIwQYna zRb{7q2XT%751(G!_n-|)3JA%?mdD`|wANVG=6YC%bUbi`0WxB)`{EB{!bZ7696mXf zMr?RwdZ@oQl%RqQ61NhnXtnef)#3=N;C08q_+VWUZw6idx@ctf_N^ujRZ($yg%}!e zKKN+$^2L$ixSFyVK40p=+kuh8a?cSBu6uVcZg%qV;PB-ei;@oaPxk}*3Rj-TM~;>X zrF9Yb9p^NXQ|Dd}_c#<0T+ZA?M?MehP1#bv|JGZh$38iC>(caW>)u>$Rx>S+{M&m! z{Ug57>N)X@nJ8Er-F@iVP(58hMlt0~&QU+N?@AMkH=6vcV#fNR1KGyAr{Cy#wOQW8l zAj3`{s_=3GR#z^5WcjoUun@+wyQ$4CIvmPZh4XEl!i@P1bl^ZIu#8t>Tkkm)K$w>lLd24Qvw7r>bj>d-vZOB2c}z=33RK?4HidiS6rYCf+?=br^}+mM%^PLY}Hb z_IVZ;?)gJ!J9Y){UYM%yD26d%^Soc$H57v{N`_)|_5=Wcl#^#1KF1*I?y(uU0n8Ds zrPn3CfWfe6Xmv$`QIv7JTe<8%1S|%{9XJ`Wuq}%!w^hQ1b@LsEUs3Wc2F5#tW=DOX zRI8M^zJa4gJ;;$l4C9TiVt5fqvo*3g2aoMk8WtZJvD$secvF&e(?lsPVc6UD1YCy2 zaufe?E;(uUpt#LO_iKWNkq2lt;fsFu%4T}`A2bb&9-eMh7b#-6bhkk^!C}qqiZLaD zR~6mR4R*B9+2sK+0RSd2Cv5Ixu3$}(Ox*wiff%Bo2oIW-F5du_JcPj1G#!vA2aoBE zVk9dQeQK><-d^4m3n{&J8q*Qm_@r%ZerCa5NPTx@oLgQ9<*vUd>sh8qHjoKh?Z|!iH)!12GA4er0 zN&8*nR67f6M0UG5kcfD_4-xvv-BxS0nct}APPjv;3d$YLNliO^2gk-9!(kV!4C4Nd zv5~33TXS&j7GH-Qx-saPhx8QJI@34X&0Rs+sHPifzD-#%N}75I zLcp5U6{%(#+)iV^Dv1Dq0ncQzn5(l<&RJp34wLy)2L^UD%QLd*|G;jI_Cx<^j*z0%FGL`P- zpfKug8;EkWig~t6YmxDuj@m%w3mJ*ZlNT{%ggPjQm;eAE07*naR9)fLp+&wr&eRZN z;~6KZCC-nJ;+YuXIBlayB*WQ7P`vM!J2E$Z^2tQ)M2pq_c4%JYk zWx2M{S;W$o-)ygexiF=76P{}J-G5qqbt{j&cP_@&&9QVEy% zM*~HrmNmVBuVd)U1#iOK#Mx2i#i=2TLoL~!(W`{vR)8Q}eZR4%mbLZ$i?_EbmP)7> zwYL@s1ko&>Gld8Jol z2RhUA9gVl=KiF$Etd=0n$IG>ql{z#Z_Trl|?sXK3{;?14Eo`*c#Rm_T4YVRw?*_W% zY;~!Pz7H3^y)vdiqV%@!bK>eH)$Glj`CYhk*VV3!Isaw1umf~cZmYU#7^c6zwXEy> z%H5kGYr?&7Z~b0{l7zN>*f6$@wad0DwK06^{?Goi^WI-io&4m_|Kd-J-D3YkpU$>( z4SRn?ZtHV5XIO82;K=nK{s}?aJp}dIkN+HE{TdVbWp*tDQ?xa-@K;Gi6G>S2O++62 z>KCS|IJ@%Y{j|aaum9ki7JGy;YT0^@^u+Ul5$LVIWqOaef+Iiq*1vcAN14chpMC$| zS)5Upi2dqY|1t2P!BB8PNoH1FfrL!==FPuLuC#O3yNwd#i89vW;3F4oyilbay@5Vs zaFR3?`rN-ttYt*X`Qm54zOsDFk=b@?(9+U;X@dhwgE@Q_Mw8H6KedZT_el4v-}!^d z{6`cUedF(bl;t_tf26`U)cCMZE2&HC;}%yFvn+i4y44@U)%yLP|AlSzbc1sJEW3G> zw&5LrW2@7Vc$BtDQl*wjlcrXxluA5rm{NNFLkKc~X=HD|jm$oTXliEZ!-pP!!7z-S zi?7T+^L12gCbPGX_Kz!_&fYgaU=-3Mq)h3j?c^%aO};gEJ+;-SR58WoP}>dP(I-7a z$BXm#4_x>nYa5V*Y|v-5QtZHPo<4jY4i3Nm;hU7Wp!Pq$Qu3X8w)=&Y2#cP?6QJdadfq76ce@&canE^ z2(P!u9wz7CLTm#=M`wQd!yhn~DCL~J`pa)y4TqZyCo6yG)Ks#AzJG0})+%H6CYAo! z^qURSc@s(DmMHCZqd~vbVMi4Iz^7+HhNVe^8T#Mt`hvD^9*#WzU^z$fb2#6HsUMYO z5v(>=hy?B@#kby!nd7JcU_hV0(s=C$-}Kqqm1uOa@tWyI;oR)PdRDNH`h7M1!v}pM z_GZiV;rIU179R4tkvHG{_pZPZSSo+_)}>izpuh)S{ooJ1#7%E#Qm$>oLP;U4nqO{i zcVWrOn!q0!4IQbl**YCakM}s}j zVE{&m@@RC_5D);s2c2@Waf6};cX#vGliys=W;oVCtl$3dr~h2emaYsRb=jWDSeWhT zVa!{xS+UlgEtQ&a(`qLq37dReKRbB!J(1KnPtUG=0P4!C;6W%H29A;{U!BheUO7zD@J2Y+kYze z7B0)r*_HlqFrdPwg)fyq-Y)ImX&{U#qpkcVjkruxbM@?qLYatN7+}55$U}lE4V0wb zV|KkJ3JANCTXWyq-dL$#m-5*SF<|jOSZa&v*5cB#VVc8M=Qh{;$FlD+e|)7~d-3>a zJdKdy2L@L8jYbo7t)nUc07KIf)-^Lt31+XdwCPH}^$>1a*jOvYC9zHjt-->L zPRpxTWdRx^Q3!GV|;uR#y)BX=Zet^ z!lz8}hZ#2xDik(r?GmW|_=+_ltH)2D{KD@a{+*ZJ-3|?SUYZJi`uX_DZT_K0p9}F0 z*}$uO5GrQg{c1STN6&rf;KQtLw@JPuXD0^Ke9aBJik7w_&la6NefTNHSmdg@Y%oF6 z0Q}65&t13|2Hf6_JE#Z<2gcW`Uwq;vQn5@7_@!mOmD?-reW1(r#rc(p-KT)+RlUgs zsK9|9hbM91NQ6c4jZVE>FVRFSUDSr14vuwn?u@s`fE$OMUfIxhT20zDym9{u zf>Ktd-*1z(cFwXZhnw4?rl+ z^;K%32Ah5+<{>OWI|&U(hCDh#xrlDQE4LLy9BA0vCLxq11M0Le z77JxGt;%OuB+Caoq|``yey!`0&bLxwuf;n;wNo4uqVNcnAgvUNT4NU5L3<09MJ_M# zDiYy^Zd0rnlnoQsy=T-o+*lj6IRQx)mawWzH8fj&IDW;)OvLZ0&FBY(u2y4 zfq?G;_qHHH0-t@gwjl>h(>pVLBC>A=N~%=$C~Z=4u+LcLiY>frgWi@sW)cfD?ea%m zb-7g?9-9mYKN}vU*eFUFZdH;~;EVxu4FevU)-6G@=W*4tO4#*I5;N;s(CtC{Tjb5V zmYT}Qj)L$9f?2y#uiMCQouD#0uc=E5#~eRU^YZd7)_bE%U|5u__MNvUnEetBfrD2$ z^=Ryn-(&m!?#6tpW~V$h?W6kX6@qk$WIX=Z^Y6WN8Kdgn^+hB1jt@mX`Cn#9*6yff z<1=4@_e4!Ce^9gz`NwNjKA2ay=Sf$H!Qw^bVqJC?$;A5p_F0c%gnH7pfoI)q6%7tZ zLpBS7dSK%91+QY03J7R-_aMJ zW0Bn1FaC26W#0*3I63n;s>uXq_2Q^HFs;i=g+EtK19O9~ed!wpOsR0-IPh8!lw?_y zfW1Q_5F1ht&4e)qBKscu{BL8F(_1!15B`pCdEFG7eXK*Hqbf|I`|mhUp7L(r-?2_b z^R?QsuSHC`PUC~&!;%4Tj37z7cIGT3v>_UO`o%9aDN{H64?Xp12m-WO^-5hVxgzLl zLFDI~Wdo%L&wc_J25u^6YykklhG{B>fkH6Q{$5q!wk2n9#1V@Yc>k!)?IkQW$i!$s z`2YZ_f!KA`)$j$phtE1n1p`bc&i}LO-hHTdXlUq6K@f2yI!U-Fnr2`=IDEoNpdIVz zfw6JE&cT6mz2g@&&9D-KUIfCroI#GDw|`7oC%ihJMCikIp8#PtvF1E_47kQCG<{^| zsEuL}nDvns!#&*f4U44(=aKUR4?nWH$y*csjQzY>z7>WaChE~jWhF$hz4C5;I}Z+$ zrGO&ITd?IZ)QnXX;iSvu#t1`GBvsZ;6L_)8&1Uow)&xDB>SbsD3r?K8TPTi?1^@u2 zDWYZw@P_wcJB2_n=vF5GSAYSP1YiBFuj>?L60W217fsTQQSLq+rVla(6Ql-!%YPW7 zBjUMJy~A#{?0WdOe_PHud-4l$`@ag>R~zhZb^VCIj_mJZgTT6SV4>+=A z&!>m6c3vTSsl%0+NHEr~UoeIb>E!qmU;TaJ@fVoTR&@9aMfus`a1!f%qE3w)5Xsr% z2Od9!!n+WRv5tYRq%Z)p85m^90Mbk#nTYH@=~8RDN)o}xpG8|4lW`tB|M`xV{nX5F z-MfBwA^*L5o&HDumw#<{x$nL5t>aJqvlqVhjq_Wc`+vGA8&5!D`T0-+gJFvW6I%Ji z;m=_CH3Cae__4mxh~{t_1wVv&0F8>Ck&Q%R-|93XS9&I2wp+^m?qdehhDs&(aE%Q( z%yvx5tj69~=&d2iHsI%*k(!DKLcG4RbCcHFdMs2T*u83i$+b$mC$1WX{^r7)rXprW z+Kg!}HNM+3HYrnovCkgy9e*yr{}FR!=yQKKJA8&wtKx}IO;mfTboGAUIP5**1Tgl& zZUINh>=|>*nqR-NHyt>#I=VmO8|E*}j&KjgBWUiJ)hj@)aM)J zf6Pe`1R@qz(zQ&zt*N`2rB~avWf;L5id2&Lf1D2hpl!Vf+jFhD-_O{C7=2_YeAXEj zcO@Dd^z>M4@}d5onb?#OIOP9cifdOSVX0MB zRn9RuLesCwr-GJp*X(ag$Ppty>~-0~-Z(=Z_0&f#w&y|lh&_B%x${{sbgYGQ1m15d zCmuU_!KJkKn}&YM*A$W!aRw^sYafJQ45R;7){6agTz59*nT@h3y^bWMgB28nkb88W0Opeqyz;rvpX{p#7Rvjr#HDF*Revm;HxT+zo{*bvZ5 zj%d3Rge+b%+UkJ7$|;<4>{Fl1Z;!0)ootYPKxMR=$D=onRc>+m%{EKsTlsWsX6NRg z@Z}=aw(#4FIfK9rw2ca@ndbD!6HZqi7GjSl&h6JaeBN{vVBQb5Zx_1~WD4Hqn&9eS zC0;LTAqIuw7NMDwB`UnpZK$MUVEt8m;(mI+7(8*8>1R{RA4zm<;ww+^D_yB;aX+Gv z)YhyFoq2q?*EWW0j=BQTu_xCBNyJo-n`U=*!x7F>PWM;UQ{Es9A6H)ai0*k@_DuN~ zrlI zEWWn>e$zg;`TC;`{x#~@!1|5v#11=}YAx&=10j!Isar!$tm*9S?WqxI`GtvI#}sEh zQAo}4Hk_NMe7>4}cF)ZO9rmXc(7+KD?+I#=bvYIyw~CpT` zUZy*He~ci2nZJESkxUr9QC#pp{{j-Ss|Z1(EF{@jYsjJqbfaqCuG=R~aU*q49* zlP`QVpk!uxj>K5BS=@hs$4IX%1d(r^D8C%RqQeh{JXW-Tu=n^M+~-&hy)fXBVt z5q=cViWSz`P%J_@;~9Dx@}1DS#ok*V4&`e)_ux|MBYqT?h2+-U=IXCrue&5&{-fnH zl98}3Dq=OYX4L(NwWrjU+D9J2Owo2^#Mw^sxOMu`Q;L!#0YFwdQaz)&-1^0z=vaj! z2Y#|NuXGG=s#C51)ZWU}c2}2Zd%KoZpYx4OKdV`JhyA1v>PT(Z;Lzz#dBFzNp7_Iu z_l8ahSp3o7`L8b~Mp=wYP;QLUG+E*w`=r785raEC^@vt^0CmJ=LtRTSh9~ zG66)|?#hLmC@MA)qG-@Y0~UKe=j>`0r8W8C&pAyo8<*enZbCRDw&%7#y4THSWnxL8 z-l1NI8J6AL*rDQ`D@Ad@VN&;4&15EZs{<<5?1n(br|Zof5hI!1WU(z_iUJkxn0nm+ z`dYR_TZZiIRwVyx)lz5X*Sf~XSlGXF>u*=5V8_5{%AC^*&%15YrMl*VtbUE9MtOal zr}{N!YPNp%DY261^*uVlJ{zi4h7OHRj`~|0bIgfH)#l*N{c8c^2}&_)VBW!-w%e69 zh9dO7iTxC++v=pHVK%Jw0>j1>2-EpR?+WC(ZFU;P+|v8h=!!1w-?@JM+PCbSCtq5) z-Z%2gy`u+s^zxOx9y<9{3GT#9WpXxSlwEwhyLD@pz+2|*i8#E`CQcK`+4@bQr&Tx8=+A+zp*C31>8MYzH~>EHJl!*Ggsy5vm+Du)R4`pw*$I# zoHy+{u-j|D_^WR*02_St2`l;zKKywC#Sn_b`MO-g#de{1?}mHnEvK$^ai44Z4Mq7L zv{H8ToZ`sEG&T@M*2gZ(e$RYf+V_5VOV608Jn#rth=#M=S{O z3;xz<+L0-=+>4AK2YelG7eq$G+Pl{L?HYhEmOKkrazN>gHEL&K2jZ@i zwutYjS88Fj$4Rq;xs?wK>5DgN`Jd;u?>0*Rn3gV;vwgJ9f?)lSt#-LuxR;WIvY{*g zBwAq%YK_y5NURC%RAq6wUGtKb49;~Rb-?C`QmiC4B$9*d9kl=uxzFBsLXNm|_UyjM*LbtIBBG8xVW+H` zWxdPL*0>A9_ZpcSwZbY!H~Rm+Rzo0&LeOE>*(4KaQHV^QU2E5-MuLJIKmY9S)bYN` zd=mg*m}W^5I-0`k>Q=W204U0$*e!{8J4)qI@j9$9m5SOgd84}_tb6Hn)|G>M@ z-u6bxYTB1@e|axk#h4o3>eD*w5KbBlQ0g8RJA}2MHwsA^0g)3CcmIGiWa7@JB+UbL zOceK~vh^|~9v>bRAQAvTxFS97!CTlsDrd4mN9AJW%#-~}wi?H^vLu$$x!B3!;;s6b zN1yDhbu`Ds#(r(RQx~}X2timBp+xL2UFPa_(}*;AQnNDy)042Xi{k{M(yuQUDoZ(KmmOs>+!}R9#I#6FF^!Fm zTvqIR)U?NPn$oR=BkmgW%P48UEhi#iI*S-fnHj^ zQG`mvsWMyd_z4>JL7VGq@co?=hL({!ZiZrONlsua?qglU;h0GwgH@W5_0XnMUWXZLAh&V3vrZF0HLy1k0!Db3vw;2K|&R6H=ys@i($ z1qu#%4?OqMR}~ft#~eTw=2S9nZHS=X=b5AJrzsUx<<>Ky!Ipqv4Qrt6()G3}noNte z#9+D8y!Gd=gBXtD4;tUQs!PU-gVmCS;(TOFMHsW#81aaGz38aoqdjF?VXBEYeGbb= z5P{*YRKaCY1$s-#?!fLL3vH1Q`~5Ysvv=5epiT_*hVdqlyT!hPr<7U8qq@3BJZrJy zIPNqJkzuVP026n4^!XDbUecm9f~p`IGTPOY@|8MfQhnSB?#b7g@@AsnzSWKz$O!^5 zJ!HaEKaZhdBMoPlQBNjc4@R<1MSLJNYQ4Y?j=K_@^1D>6 zfVYU9g=#XtgIQZt_LAaIIvw^VokVbl6%~Syox=&I+-e8MV(7xW!8N+a|7}aZrfe3^ z1U|VuSC!WP#EUsB)0=mjHGEs>ScWY<40!wPkTxVl4*v2xf9%F`f$3xSl7A(!3Q;kTTi^*z?-C2X}{zwsVCG^)r(;jjNs_vq6)ZTaC}{;PQKv;hZy z`kg=SbqrA?vt0P^VT^%l#LYX4x+alKwwb;KJB$j&<^%g&fg&AI1D7_-k@3A8U(ez(_Z*1~qUO}#1{>$0O z0P0gWYFC|3w^;CI_p-KF$SvKK*Ea3`giy(@Uw?}MP1TZ4W!^6n(VB@~EA5TgJ;Zph z{GbLT11M+8dp8Uq^l0S9PN|ucAgtKj%Tn<@xy|X^X2vlR5id5<<%7>1-C0?Lu#uFF(xj|zw&KT zUY~sU#f8-O1iBUwADz3qP{X_dy4`;BU8jW*4e{11eV)vv4yb(uyYyp!Zpk~N2Rr{UDL+0 zx9*ElrJHSI{My>zu7GA5l9$gsb=ZX1)sT+pvk)|^qZ;*6Sh3+I?%?j+>8@}DFkrTT zS}xTag>2t+lW^E9r`;!tSjW>p8%;Nk($=mvdEwMvoy)S`^y&L+?^&B$ZelwbX^852 z?Oqu*M{#?8@XAt_5%g}`DssE6njIq)rT+3$e*i!6?8w-|shx0i*t>e_?8NXGgKT$m z`TB~nCl~_P;iaY~Bap1-wh!QEZ*IK3TikPFv7%@v->R{gS%JLW_K6pgYik_+{VqM} z_P1b{Q%0kY&U^_jj1t35Q=SFq=uQ>@uay~ku6v)dRj-T24&_D+u}b47*6s$scJzy> zs@p$_<0u?AUBvdU$m*AMUMOg=1N^(4PUHSg{(3n*+prXq1Pvi&wbH7L#!dvv?LB`> z%1wp+cKnX(o_PBA&*I=5FQR@G+UpiKQp5-yZeb7IzCW8bNC zPe>&X{~h-p|6yU%Y@`^TiPb zYOcwg$79qmQL=ZfyAaO{IvzYY9kkH831X**Kx_t3uxtXyl;Xxljy==g%>?gMOUvCZ zZtI~Wzm96P)wWiLFr;h6(DGUf0AOLGeU9k+fU1jkf$y#zq zE?A}DF_)^=bxkVWZB#_TxG&l;qFUgRDqN`d9tcj;GC6V}Jk7BE!%YmcoAr&gOqGFs zp<^yvlt#jMM5CKj&PGeTrfPP$Mk{kO<{$t7AOJ~3K~$p=hf^ISaK^BNm=ds(RSbr4 zQb~+XKplb!Yuygl+84PyU8Spydpu0<=-N)XfqAdA^>y8@l40pC*SITc^}*wjGYAYT z*1-Wdf>>PE5!!~6dpIZ4cxP8EOM+n-E9)iHh4MuaagNJEwa=y7!Za{?JFOLx_5c7} z85rhF%Z84j2#sQF8%3Ks(w(0FhW%CB`wRR_EO8i+8u* zhTSu02VHx!SX+^IOH~dVvVl#T9D}>L<-1mU5h3_=7cBP8PN1aSZTm>PSxME?iS`mi zt{RLd#+wC?9p4mAfksD|se9X@3Qx10k(b8p8Q9BMdZs5dK@Sspw|Ua9cb@a;CGI4? zav7LBpG8gMkT|%VSKWn=-!0{w*J}c{vyRTr?A=;0v8Fw4v)UTz?A;bIfD305wC=)P zJ0{#?Fos;)7mme*6}!jz!SBtN_q)SWC)>#-KVos<+$6+7kF&4?;UN2wM76s`;&|%0 zZ~UOjRjlEP?d?aEpdUiYosL@*6_Tkps;5);f2dhzWRx=uttMhtt7hRs5X}1Ap2Q|u zRa+L7G8IDa>h*iab{D_T*a&v8Xewh%n~RXn{p34e2o8lYjK8z}eJS>LidBB<8&mDO zQ;L$_p&uf2TZm}-YL5_Xyeb6}9joo6J)oHMKy&Pw=lNoxcKmcK{(PsfbL0zO_q2u! zb8CL||A>QC^l&n`9WTe4EimOeak0I2!1;OiO5xb7Cxwsw-XIR=R5osXN$e3xjCH6z z!ilrMMcECb*eqr!TdA9p{EHCY%cP1(I(DI*Co^_Z=SN{}vu63?0jZUE`oPy&U3 zZi4^-x@qcyySCB}op4)lsZ-x@2Tv%9w$*J04GPj_7=v|FFkvZp#G`c-12gT9Jc}3w z-LyUT^4CP83)?J@PQ5G{y2<;eMuP?o?3RwFf3*Mkgb0w(CyueuqYy@o&U}6tbwGgi zO0(#giny^Lm$gO@XiA*3r22dl@KLs{Q!$2Zqc0;Ufs!P{9wqy&LQVznbo1Cbt+7qm zLZ{AsCSNN-QX~c)tL;~41n$R-Zf-|&0%-~>b2(Y;W$Br=D%f!_###*o(pg9`3>3!H z6x*yDAo zHmrp28qOISckXOFC9Fs1%pm8d-SC* z!>*xrAvqa&k!S~bWoOhGkIUIsp0l2J)txGg*9S(vNJC)`#=rjJ*N}m6llFNNFDSaH z>+aG=w*KeCCS>MQZv=XuG+6k({Y*b()m1wHx^D86t~rKmnx+{*P|uzPh+=5QGoSmK zhQW}gU6}fufiXZ7MjS4xmon9cBjI3deY(p)9y#t0T9sn(_={gss&ucif{|g$1**le zZ1Ksba3gr`oxlFSfRkvI%Uyvr6s_<#zw5w%4$yPL()g!e_=F=k%T4^7LK)t>d0#-n zHpgk9h$4Z#5HstX&^SF{EfI8df+Q&1pNu)C^jTL`wGB9!HvA0hJttZ>Ti3hcV#V>+x#K!YjjCn>jU|tEpeq8XAU?IMrSdH{oqs~CS~rg zo&;m<)b9Pl-@Q}Ii`i`mxiXslP|tj5fv>VRwd-K>I@~_JwY+tyhFk2ZU0tlxbyo;- zsBANT|G%Zjf-fh;YmRevC48`0zh^i?i?80)OC!729(1!@`n^rkjr{-66^WoDR%hLE zxLGqT=#13(rw^_UIsN}LR=QfJx$&ELh;>Sat~J!ISGQZpB45J&HH@-zn?-G#Ypj?$ zY1%R3!T-3AE{io@SLKchS~?DCm<8EfE{j>Q(G~fkwAJ3M3T=+4jRf3qlOFc+?IGt8 zVYT1t8o_X@-96#OAOHX?1F)-zt1Izv+|NWp(__4e)=($3Q3~`Sjr1xoLASXD00=q~ zyNCzTb`euei6V5kKPz+r07_Rct}L?l1OR|0?XmcIBh=sBDwIpz^5(Liq*Hqpya1YH zh@e?rlVAvnTG$Z9#Kzo-8SnpCOtrF7yYcp&{BC>Dwo|{>Ht?)tkEpZ@kay5DeNMwk zB>LSa8@f@)!Y2X`$FD5jGn+xUrjqR0R_ye#Kz}>irF`^$*R>!tJ8U8x?CY4X?fl|f zfqVt5=Haa+;qCw6A!!?4%W(w}z(~;s*{w-#tHYPspl)fvaz$bd8q+r9(4nb_sq`p?P&?BW8fzQHD=oE~wsDZ#*t0f5J>!FijtByh&vd#; zzQ05_i+ul-kMG1AbOLdZd`2u4HtTr~HTA*4sg|Q+(hvqCijs7>S|bMoq}yIfL8($Y zP{-X9HV;C2G$G&|YX~)2);nTpx3aRDsgw+^3ekdDEZ4dWY!va}+y}3?QcAJ1Od_Z^ z<*+ni0D!)$TIx`sj?YX)gJTv1PD2PpI&j{niFp!&NLA3%jpk9rx0o&MXIcON41rsk z%C(Z1F2aVsk1dsp8=X`WHuB}2&5PxXYK89X+`rV>+(&rU-d7O5-GQ$&$L`Kwy2}KU zw~TF5k-8Qa)9W#i{e~cRRri%tvDr-K8Xb$)W&$Swt&*gZroAT9ANC(WmG*cn(PEBR zy88<5a^W_`Ao3T>4c!+#bjGob~SKiTC}J1PfI#)W_vw-mU_vyS6iD ziaR!?x9dE5dZ4BpfAR@C`%ol*3wbEdHr6~*(ryEus9mc@TWdUlrij~jYH5R~1-;wn zf8K{%F#(2s05VkZB}ZZrh;mcz`%2Wb5Jr0I;Ox^9Id%8-{}An4u9Mz5@rNB8BA}_z znAh~?R_3|{QktHk2=NXIZAX2W)ZfPp-;A(1UvEf6!wfG2ES9?^lj|Jd(U zlUzGD!VvuM;FFNb%pN~wLN&X0ef9oUX{`n2^tP&?qKmfmY|Z^upF;$MUe@r6-<2yY zAl@U@;_>`m)<+Et9n>qC9mYboH+!|os(ud{Xs!$XlUDOrY3r_Q(ON+7$)Xdn%(Wg^ zt(snaV708@;&*C{a<8`VYWn5^UtfRc;yVxC_?0HDv|P8^!N2MFx*cz5;kI9F_R!X; zAhr_)rQorF%^tPMSBUG_ zkB#P7rK8u;@*}!qM5`G?Q7sYoL#0_dgnW7^ z#B6@slu&fo>&k5ZvYZu6ny`OThDe06_63efNeR;3o|&L!B9FUS$H>VXeZUYR?iJU` zL-C$U!|L7kjL#HT9_+b$ee8HSJs0;+x=gaLc8kec3A?G{S1Dpk$};tCL(~*YYsX|n zJ%;XNw-mdlo;zQu<#E1ea7ryzD-5i3ll^GFVV0%7{UrMTGWK3kb{*E4=E?b-n{%$5 zt5C>^2#g>pQX*wj5-F)A+vCu-WcQ3$x2HWb9mbYDo^FM9kYrgoQ=}!5AjJTH0FerX zDpbx@H|Km$&i&vuo>@I^ul^tR`d{|jxAxxa--*Mxyj~f*iN1n>^u2m(N;O_>H>iXF zF3cHJwq`xp#OjMo{1O);#*&<$h?}GJ0;bAh)WG_;pNTZy5VfSzx#%i&#SO=XTM;x zTd3q#d)byB;oxq|R(a-3H!IVA`jMj}pt5U_DRIHm11s1z%|dG|=^L4*I3Uw%Hjr8^ zeK*pTI~WA(Rk^o)6+-JMEY@NH5!<~#nl~5 zC3RqzbC2m-PmwAZsnJ2gh2i12b0B<_OpNN*3B+N{jJ?p*m7I<_*Ol`69smG_SqA{1 zf(1fq-e$eg0nOvV)NpC&L$j&#hi%(3bkVYme`v{28XY;aS}I*D=f!pj006a)FBES# zI@$czFDz3WJClvun$%(2e*74E?i3O+=>)}NZmc89lv;PE5^_=p zOqhw=&OxRJcPd^n3W#3+AqI>YM3mD##DjL~N@cmIbahbTm?Gq9A(m$G zh9;ZF>b17sCT&YqtCYK+ak(s%^sAbnQeD?>jpGp;ut5kT)!A;okFV6kZV`kK(vQ#d zhh*J&|KL7jb~kG~@s^k-D^t-K1pp~!rgw17tf8maz@B?+=1?p?IToJrxI>gb%H$ze zMQni}>>5<1zR}ndkH8^v*}lsR3;_VZXT{A2*Km&37L-gK+cg@Z*&Pra@l%gPQy!UGeC87$Px$G*dtcsc7m~CC zg;)YyBDbQTdyMfcmwR9AK@4N(wJJ``w7A|o!I@zDFp}`un4J=9!?0zBxv-k%Xc7ki zSl-eI1I3+ar@Dzb>Xh59kw|buOd~=t+06aot1BD%y8sG!xT-%<5paaSQx~qU+bzF| zAvT2d+FmEcK*;UR7DgkAR4Zk+Xd7(`qurx7dgcAEU;lt`?>u#;J|$Yt<1exiU^hMh zf`le{1HI$9cP@hyXWN}z9Hx@g(f59~1u`&efj2i+P!I$=b|II6EE#canfsS|_Rq13 znyc4e|Ke2?MiEKS79DN?bGZ8B@%@>016rIRgb|^&kJeVH2{79!*-+2)ZR>@q$}i|` z(lHW+>UDm8*{(G?qdtE4qO-D#%ft&ue}l*#^#ZtAf7%GeVG}zrWErNbYH;b7|5>)~ z`;WPd_dl?T2r&Ef{qKK?);144{^Gs;uS;YzBt3n9@qQEb4bNEZ%h%m3*_5a6{p8Ci z#RO>j<-huK1b16B^Yfcu@Zlr?_}9)W*>@@gghk@NT1meHI-wI+pbXHn%I=!*J%V%6 z;p*Jg1uzoLW5d9k-zP(}9#{WQ|LjkxdOz+6zV>&&>oeOZ8o1s4My0}I8^E2VlBP6q z`VQ7vvxCTvi512SK=e^AzdLZoJtV=rclKj5m3%+N2*|PDA1SA`Ib_^;cy8gU3%%^N zg+gU-zop1aRWRDcojUmX%N1ZuV8TE9?w|E@5Ya!du>CUPMeWj&<&8yyP6WJ-`t_A) z(kaxLo8SFWaC#7z>vQjY$r(9okmVn)zkSvlX}jI!o*-5f$evbuJw>W|K&<|DuGN)5 zTi&_-s(T!^Z8<&vs(j?E4XA7HTt5He$Be36y8804?xfaNjc-V>)D@PzfIx?UVt=avrQF&7HVMhEEUF-UwnU< zKDkRLe)82ni8>?z00?=0`mujo&0T3}ikL3YK%iXTfL{L==L>!N!E!PCR?wdj9$dG~ zhm2+jQTL+9MqwhnUws|%;CAuo{MrM9Nd>&k#(T@rlvCPeuYBp7!HGeN+q(V1AGyNk z4q)a_mgg?`VpJq*>bg*p@63N-4t$br-GNmY|GZM_s&UXZy8;R`x|svJ}$7-!E?F(w;M$@O~p7f_=_7eceOOSu&J6D1XpL z?d?XKLK*>{=GIKQNhja_BIt$KsaNW~y?SqHm^p>9Bu;IFrz(Z*8^n141ye+7)bJkZ zf#-&(S=_$ZqKcsZwq>g}!pvAJ@iQa*w(ET26kx5K2_yzk3k4H`4WV33ma}*;!f9w@^gv*f3lOfeF$O}wfhWVJY5@Syqvs_wb`zr=#7#$^RqY%Q^tOar`6j5r1OI1Ej8mLAsyFByEyuS(6vT6E)U_~3_2qsP3_ zlYrk)fDtZPDAK{>A!+c&a<(G#6f@A=YOEIb20gBt2gHc6 zH4#c4n%LbprL2(moq1R}vp+Y=zD2Af2 zsOumWSg(~VrJ+}F?@(M8N|O_z{pFeo0W)-bBYzhF0Eq}Pt{yy`@*Q#^331lNwJV$Z z4ry~QjF74*P&_?^dZrqdJ4xVvoV0BdvR$6NjM)V(K}MX2ZJKpica6IuGn1x3fFN}8 zRB~mf0>w}O1pMxy5Idsp6mJxu0VgmK~+jB zvTi^L5J*f&y4KL-0##kx-jea;L48L6_EFjf`Wi4tgtxC?_tovehr}y)11wj?qeQ3f z;1ZttV9<0ykACE!Fv_@+xq)AGG3%yg;mDvU!N1~h^gL8I8Og~S2mq-6u$LhpO~}l_ zVSJ^8$O_`Dh+p1{l8iNa(HU5_P6n#)NV>zcAN!0|mO(K_{oZuDDM9h9boV40Pj)2< zfsFlneZA9YnG&^KH+`{k=kB5Ki+ewNefHre1k-eQ$A17KF4cZ!{Im93h(gt7e&>tn z#aDNie)6Hue`TjY*5;PNM^iSpMSa|B)H6 zw8}$cZqgeY>(`rDwWL|xsB0iV2QaIL>sF`E7fIXdDBzyPSYvH^>Q_FpRvJQuMnZ#DaNbnv4T zfV^AEjlvGV(g4sh0m;@B&y3qN4GWaDN1p}()l|V}fAw<)W}$}smV za9M~2CQ}p}cfcC^p~n-a{rbLe`lG*z8dI2SIqCakY`E5g2+vm1>Q5km+dX~LZJn?$ zFnhI;V}6@={dR;kx;pB0T+~J=K(b(b!hG}@5N<5N9|Fk@r+b;@21yeLtU{#k>Fj zShj50qTMv;al%AQ7%a7BFIgxiwC$%~_+6WHL=$nf^fqDoMlXD(n|TwOy$C@fGy7rC zjhVop=hrB>uO>?ztsL#1cnM4p(@&lF@Mr%oP=?G)&n1RD@_Oa`XMRsDIgPDr3FdQt z_nJJk8(sD_qja-A;5z*}Ryq>>cxJ6|;>`16-TTQQ&g_VfB|S%!^GpciFf$H5@p+Io zF`xZE{m#Ep0r&V5pZxmYT)Fb?ONmHu?D3~Fy}cWoKS(@wmLGdqe6V%lp-WIMwy|GN zLv;P_<@())=#9O(pZqZ(+kI@vZ0Hz`9d?H>{y?Gq^pnntB$>!?DESNs+Nd3SCYZ25 zh=gFnwjdA$$~v2%oP*4v;Yrxo>1DS{n^%7D-WQDZzTML6shQ7P0KI$nc8Q{}XC@(B z5jtdf{I_~ZrKV)M~)=U58W^;qnw9UD)qv3RsJXZyFz=$>4W~C8!P|-I0PeL#DfusT>%V& zMm%m11C^H6s(@~xrwCOc&-Z$TjMxJJKoM#V?<4?1rfM0e!)p=<>th0RX|H3upl*f_ zj!;y<9Y@$Gs1k`gE z>PmHQIWmFYUfKjwfZXhAHpPZQoNvrR3%E<KT=+APQw& z>j3}|JRKlBeFzD(4vLnk0svqE0NxjpstW1mS_cQVWyIo62!%?hi*!8BSL1LDi#0$AOJ~3K~xdv&~7gjSMM4X^nu0Gwo`>0zvzZS(2hqJoleIb zkg6e0q$M9})R--vh(y?$im{X<<=sTA!?=}pfD~whqXWUALpCruB?Le@&xFS=y0tUbv6+mB>WCp zhwIFm&~cl{7~xH_(^E%Xu?*QAY4Sp&ykPXOVP^qW!6&Br=Qav0NpboP={nz!L%O4| zxlez=Cvu^7q4d)rV&i-dd6+k?alyVC)4c49}dhk9r#HmBH(5x-xM1z z#TFplbir6~LYC~5DP4cC;;g})kjFn9?2DZOt9ZV&f0B%1v`=(EqrFgmC%@g)Wg-}j zU-W^BBN)wWLx8X8g}u~n9R$IK-{|-EXY6@I32+34!B#eBw-uw(SOWl{3juYJ3Wd+F z?JX*joWH#ZG9>LKT30i)|D003IWRm**s>$kU#_r}XRHs>niOU6yTQamI^`2IY2tXY zw{Evv4H1Q7;dt1h!hDxNQc)|ovYZvndZ>k&@gre{vBp2{r=7e2s2Rslkdx7REE@zo zH5eO$!s}p#0+L*LqlbC{4@*9{a}S8zi$#+88+TfK{=}ug&W-)LYz_E^L^7~-|JM1l z&$l5jzSly#}p~m*T)tLVz&CXNQ2pI7y zipU<^|K;ts2abMv5qW!TsSdNJVd{3|P8PlJ;==VelGu4HI>=~QpK)BRPc`-LOa_m7 zyG4HRl;)0ZUjHw6JJwJGJGoT^oiJ)|&dqH)CuUy%kKd*QFnshd(Ce!fZ$(B95gFm? zTR$8aIpOj2-7VaVrJh0^&D`DhQ!`AtGgdsfJbvLho+k;~;br`{v@tgEWPjN-uCCj3j!M5xk|@6~x)JZ9w^w4x2iI-aXH4(=7`LGIq>w@aII ziB$5|mAUoZxxtyZPF*jSibQIleX&YIA_tzp0B}H$zqf2VQ|%jnk}banOf*Kpp&NTEru(p?+9ak8&jtsM z>`D0vwE2PN9|@LnYt3wk8#ZG1rHtq&;JPQ)-CAOgvrywuW$zXldm`dc*VpdP96h26 zXkmFVlsF6{MzwW69viWC!Q~&W`-TS`)XjR~b#ijH%}ZBq?fB_SK$$lxx6XQW;Kz3s z<&vScGTPsX83VGbcNfx-l|kY%DlK(fxXC8ES`lc4nCMW)WAq#QTHkTQitfC#ojCLu zhPjpetFFl>5#3oD*-5z1awy-RE(G1a%xk%sp-D<%?bw?xEXM4XmdIfigy&y*XL5Yf zc33NOKMOkhEnjHqwab3LL*7*AC?z{<%yz!1WiVt61$(XRH9(v7=30<9lh&!0I!BTd zcDg@H{;!Q4_E^2R+qvs-&Th{CXuxxZ99-^yqg(d)D!q53sN0a>8dldc769>@j@#-Q z;37~2NoOlaXVkz+&|P#Dd$yNr6-YF)ZEtyftJ@7W=qBeH#Je6koENn14Yc`0~v+lx}z8#JOb07D$&Jzo)I$MVKX658l8J=RS}ZSwGg z+*{tlp^fylQXcS(Trm%hnSn8M@jBKv-)-(0k%e;^Yl}vh$pNj{Xr|Eo&7HuZ=PT%b za3<40Uf>57sl5adlFxLI2caHO+xa3+=eoQ~L2^b-I1{pu7;T zw)FmJhFFe$Xn6fWI(#^e2IG2*%4Tn|5SW#E|K!MuL-9V^;f_6w3^p@Y@^VkiNqkFF z{(B=X)iR5+kQRFY0ML#;k`A_|dPU~563?O7{dSe52*?7=03?Z#Vr_?jeJ}?gEdxSu z$uta&SEZUFR_5?rcPW)QiJQ@;IPrUO>c!-D}>hX&6E z6AuL(fg>hh5n;eTGzI{WU?1UI2cEGJCPAv5b=o~X0CqeOP!Kbsp_UstRW&$t9D+$( z;tIDiP8u4(p>TR*kPD0g&m@OGqOGWU3yp*aP?Dko1ONai;>p~-<+t^tp4b_01OR{$ z)-@LL1tC`_pZo$rzHK8awA*XXunQ#P90_!vyr3^WLIm369N>Z;te5bwJ;taX2 z;to`AXxXOOJ>ZlQ4q`guE3}=pTIQe&8#Nmj(?kTG6t62x+l@OhwI})#(^Ob@#_4Lm zm2GtQ8f^dobgk#~PP0a>xYI!#2tvZ`Evt(MEf5AQOsw%{$6;{HTJB1vwpu}ShlAka z6hgw1Y2>;+z=v?D(Gi9bs2Hq+ba2AP+)}Rs0d{;SWgPMb#`>D8D^g=KUs>|0C3Ord zaVx^GdpiNsejHGm?%>gw)mjoHTgQ!%rdHX2;JRAN@rK4%Wy40Lwj-|4d-pfw-MTKx z$CI6tr-u*%4kF!|<8ZmOf)Oq!tsZ?icqpwjeEG!4F{T7c7+~FxAKUk?M-m?-kRHo%ZdJ+mAO-wFP`;>eJ`k zfeh-MO&sR>y=&R;!3Z>ZDQa3F3fO5(6siQ(g0lR_A6I1h@T9Nm`RqaNy1#GO9XN)D zAt&{iQn$Smex?cd635zmExEVX7OJAK3H)+1^@%|u`S&L6W>*AJ_p=J&pCIS{aT?8d@9lZgic&D!O;V85f6cfbC>f7ulq zWVq6s@BT}d|4;>|{%Gmutjmvk!fXO>ZSjbifsb6xUkZnxCK%!7o1aYvrzDO1+aG<^YlLB5-|N2P=`|3!xU^f^Z|6)h zW9fMrwyGWuIpJz=%S3#JgwL>#=NW0j=ksU9^Q^90vH0T^8B}Y~;^3`!FH4y0jo#VT z=F~F2zYg1%VwjQ{SiC#>(61|{?B?1}&mVbAqjvJbVxN1eSGFsy=D?Jn>SXLz4@SqW z)s<$hG&0~3j92vbmd!;#1|2;vkg-Y*PqzxH^wv8`6 zkVDfp7M>csc-Aoz6B8UuG@RV{==2Dz58Dvc5B=+qdpvzI;U0Vj6MQ4*UNkUf^GYR? zX|L~Ak0)N-d{88qq8D)?)4Lsm#8w5_d6ZxX<*$Cw2ag**?<;@vNgve)hDP3A{cD2- zkm8A(ckgIaG!SamUcDAbv8|r(@?ZZaF4)I$z#Dh|Z>MLhVruO0N#++n&@Br99Pz{; zXz2=o24{yf%rhKFin0b>M(#JXj4ejrktw`0K4(r@UbV3+CsW`@bk6fV)+h zD<8apfzb9(^XrYe-O_h%{(wzE2%g`WFC)iKRb+`1>sq_u3=h+ez8l~9Dq&>6TJp?18pLvo>gdYWx@4u<_>Bf-hyZm=`tLW?pV1vgyq znWIVLN1Y~ECsR;QT7`ty6m1I(ML=Eft*wGB-dg$qVRoVPEd<4AD9)E_&gPy0lzImy zp%V4#8~BZ%%YkGh6!gJuW#ciwcy~~(?bf!pq|3*}C|^8;AnfkaJL}7@F6aIZgvsmm z!ha8#005Y9cv+m0`MP%oC4Klmh*2}PhrUy-jX>jqY<^-Qrrl#)p106^AEpzRq9 z;-z%*xeWu+M*}=9M6cl0Jt(Kfh zR%iQQehZQ3a$9AmxIE@IJIIo`OodauQbxF-c9hX4iY8j&T}4IJ2>{d^lDTLY^@Uzr zXrno?+uPS5z~un26v4DLNfX8TQm1>ss|Tj$ggiKI%j>Y#z_m0k&x`G1Y4yIHG|3UF zEQ_pf5Go1$E-us;#~8E|??JA8u@S0~jHy|+14WTp)C&mRjX>AiDDl(LKvz}~Ab-y7 zdXT%*vD_tCQWcT&j3K)G_=i4|8n$^eKABR&a+z zL_8S5=Xr#Bq-UCA0;j77;QrMJImOeHy;r``JRpLj<6!5SY__YLpkoF;C_Q@_%BPN{ z%z4)$xH;gLEq$g5xBD;%<~7&Cdng@3Irwvfht5wXM6FCe_|CiE{tALnTfSI_K-w_Y z%{_!Ca|OK7@c%NPKD?zmYYrp?vn{xpZ(mW9r;X`VUq;|U!>l(Uw^~Jv-FW$r$HUuVDW<= z{E6LYllsoq*S?pYf6vs5Pd)t~jJ~d`Z^*m%%Xt5|1x$2GuO>!b0s!!h?7 zWXl$|xd^s*Z8c9XP7- z75>trsUfepQ9SqQ-&cxmWAptu`}v?_we8-B-w)OM$a;o$o&I|`car`5_EP!8aeukt z{n!02s-lpi>`8Ni;d~5b(!`U`>fR*mP+$0?Kcw)O-tx?Z{t)iMRJip_beI-%JuA+A z#N9Mh6b-~jJ`PwQ=x}{3HVgokMh*i2VA%lN98lZ3|B%y7RScbX`ep=GvrQ`ql7Ov( zkYRzU4QY`}A)~761R8$oQ&@M$2K|qGgMW1mcTDAHxTnHc>P2%z)T%26%=8h{O`mSt!K z0gWRzZ5rZk-S?2`bynAF(-$5$i9u6ajyQjXag7uqam2)TDYZc#jH;7pQ;TtvyKwoF<|J&^vb56EBA-#Dnn&L1 z%s+skirF%SdM3vohxFoWfAoc3Yny;FKmCi(;uJ0wyx;u8|II!1HX_DNs1P~w1l#xA zg+J)uuRn6>VILp-Tt7#ZG}kD7LK~+jn5K0CyYykm31fEWqrdhCDiYG$@@)8H2v5RL z`ItAs$puN$xet3Ob_!YR;=oe5^}A6f(=09~JUar?mG^Zuc|S%-f*G5nHIi;CThw6QtCc@Yp2O+7>~ zF(&}QIt+PCLvCxzM9QBS#`RdTS8LLuV$bssjOhqdsup>VTPB-8r>Lb5AZ=-c0Jw-9 zeH@pCU1Jk?yO5?qo6pM4dBiwaEPqFdNLzYk6{PvL(pta&_t$bO9EDqnB?#QqI`c0_e^E!`8-VvXt)+SxS_HG)V?-u@k?Uo(@2ntbK-lTeh zVreiC)wbnFuxLdQDK2q5e#C^Spo7sY41!SGIUayYN-mRb-n9%Hqfk@}h9S^wt=ID` zu%<@RGob?rBW62Ap|ZTpto20ypwQVlX!H<$I(M&ZsD`F1p7YcQifQ@*?qYNKJ6HFv z9h-Pmgwm8B7x*>WvTO%hA(F!bUVyP^xVxfhT)%-4ZnN8HuJ@{_GT=+q^K-ThuC&U% zkv;@-IENUsuO?<0+qO{x(XBec&)ag-88yui+$dM~o7G0ty3=k?I=nChh6kM8>H!Es zLbsCN6T16iXHS6m@zUx-GruG$HL+DEBzq#tD3iQFBmU;?>E}{m?$PRduOz3=I$bV! z;Z~aq!*!Rce9bJ3Ra+5P9~Ejnni`x?@lg2Tj|&D00znR?x2h!)#h!Ta^PBH{JD=Su zVwVYhr<|P+55-BnV-s$t^R!*F$@KbzLb`vY3Rzb0*D}|~NwXvLjW~N-rrjc!V`k=oVwt4%LA!X%X5gx| zFXCzafR=uYianDr8$Xv~}Je_z6esfpF*ED7r5grl_0M=j{U?@6}U0Qd*e@t2@Tw5L6~iT&Li2iH{%*L@WQlEHnYt9UI9 z=CJo2O2wp8d>;oT0K-3CeT&W=tmDSSz`5zU`*R&tfEU=h*6cNCU$CPm#{<~=*MIb~ z=WD!-37uM7_1;hfq~Lh@ayDH9BRxIPXlG%B*b|<$BDB?pU|Zs-D1yjplLc+7-u92aHflX?}APZWfDg{-{!4 zlzW@=xtH5uhG&|q+Xvkx*wCHDeJT*9f!&?np-|!QB@JrmaL_Vls4hPGXo{+1csmC^ z`)dwrDdp|=V?ooX96EizZ-f#IF>`Wu>d2!3LLTmS;;^iDiZYz2-#Jm(527wVZZ^7y zZ(9x}@bTww4V+S&>`?v_m(U9de)|byGiKD4?))`xZSi^@S^-a9BSm$BOXf3u?L6m9=GeEaA zB`tO_7rI%Oy)L*Yb-c6>=TNaOD#bM99%dPLSZzLFtXvGDD~r0&d*9D(;6OK=oULue z=xC}>g6mlT03ZNKL_t(G&}|W=&0f<`4P7(<(B^g1jc^3%V4Q;p2vs|LUBPzb4(pvt z_o~^=x0>BtTM-~SLwTw0e$V9|3P&AYAL>%e8;!k!ES&X5G}~OhU&1yGpIe(DApnGt z=!kfKrBSLX*h7#mgA2xekWe0dfA8*ct5~gR+);_CUB1Mj!O)#fP_0X^kRc$sJI_8AhMvR3bXoqWtTsV*- zyM1vKb0|jMG?a_JaMQ@Dy?qpSDpHMZxeXn51Byq-cl7#JO0vGT+=SskqCAQK)dQ zdH>dKdabFowe`0P>31sSNCQ`O+QruJAOXX?l=iC(mtah@BVwv&*k@@_H!YSnZ=+yz zoR3ZboLcH>CBfk(r%y)hm{Tom^m|>cEC}LGxumL{U0CTa?7o`P+PSwerKMhek1pw4 zNNmzhEaz3O)SOqhujY4FK=E$wSPdu5&cb*2pYM4?I90ctvFQ2e6kM?a>APU3w~ZW1 z^?R=8`o%it&~C+!J~4%(Ac(|5AFJ1RZ{BEg=4$;x0KLa~XB*A;xbA$2KnSxJn9BM2 z=WAQ*Bez#*QBn-kOM@seVWxdan~G8l?BD7v>ZSL#SK$7!6Gy}9&IN}` z2uZt~pGK%f7m5S?z6)oY9@az~VWBcJkN_c6gvbVCCsG5GNmCB#vC{*Gm6|W;$1u=L zUoIXT*q-yoqc1&t@i#k21>06ywcM;B70#Y@o;uw+`|Ihqv;4)B01+SR==WBaI{^8e z{AL@}>=r9eU+s1GNEXiSErEDq*o&p!#FO0l$`oXuckO_aENiW}qmF&-s3I3)x9?1y`E|Y9SYP_y*~y1YcRjBz zCcL9kiK}$P#Hi0HX3<)QaE$Ba&1!mYbR^#EE{kv6!|A>bl&dWKd4zQECw+hUgFD^1 z4x+qJ%U{)`+p~tT)oQITb`9{qGIpO)wxwrb=XcI~pPWO5Q&p$pt-3ki+c|fuTd9R4 zf&htNz=*-d_Sl;7GJ_Y`U^EyZgvBT#S}k?A)U6KcaPRG#Q{`NzPO6jR-e>1LADHFE zz$}LU=XbrIf9rkMdY+QTYo4j9Snok-zvw?s^UG=gJWN zx_I6&barLTX-Hxgml&8v663e{Ekw^u7v{+V5zY&Emp$`*20dctj z(fZe5xM8+tiRVx-+NFN>A!P`)yBo!5HN-2h=e&OHPwrpNf&LmDIRcQ^3O_yv0xY_t}0GIoTB~Ty2NJ8?f3V8!c8#f>M?T)U-4m`=G(76qhKEZ;y}`P8$t^fptmTeA2VDQ@=tPzooy>a01Ssk+=pOzIvudbMaOmW0el!Y zyAk>%ckp4!WXE9npmU#(PLz^x*eEo*ja52jB@ns?nW1bZIOm!81y}Q=)xJ*wvAQO^ zpdFYEa6?qUm2D(Cd+ITH3dkn>7=k3hEzcAcp7I3b z19h;q-U5aYIB<0CiPkMS5gn@=(~4y_8yd>`o!)f&9#0RT-TG4BR0rJ+I!d%x1!KT3 zWMgTsMqtQ=#596HMMYTWTWIho6rTu6utEo13q~UPs1J9VJC@VwZ1nsG!v|GiKc(#E z+ADm!RC1!Um-Hsj#u6=4B^S*!N!lQklLz^fQ64sShLrXaAD_PHa1*mbY3;7W4pFY| zIFruKrE3sEiv1D}_2XWM~M0AR7- z0x5`Kk|@rxzATtxdss?Uin?9_0Ah|nP`5imQh*DnEeM%yi3c(QSY@fPw!7~Lw%ihw z0!_v({Fd?1#Bfj>rK-CJaKI-Q6pzzKt1gKFfWsDdGnLZQ_tGv;1vuMSfnTs%OMDSj zqZ6TJko`e(zp>OO8MM=E+tmZ?EJuz88+gi10GnVy;VSFC?UAQqwg;PNaW;$Q{N3(G z79P&86PZQ#y_n^14LOQun>yG&HhyTmow&33=Ob(84m=YD*Ljdy|8UZ0<;Ok8uEMRR zpDBtb1Wz$UdMb)%jLjn;)Z2a*z>1M0%IC(C6>!A8XbhzFYoh1zjz@fm!<-xZcVh#<*97TBW z_{aP>W_N_ZhQX)~t#+RKmlq@NIir>&|MKG~Pf5*#{;t@m-5EzsU}73g_vBVM;=hG- zj@wyJ2A6TU-9z*kbg;j3J2Q5uZ$Z@H0HttPa*?{DIX2j^y$Z5j+_&Vy%IXS&U9RTYNek~bihE4-wU_=!V&;K=gfDHB`Cd&$NK)NT)l&VS!2oKAnLxY#^-Hd*VipC09i zy6zigrp#HI00>;iu%|u(d0fmMeBzhCs3Q@lBhGRkhj|=MRt|dutWxF&L-5mV$5MQ- zoyxvQMJUTPJ{}&^*m2hbMo+Wz-jLOcIQ(qnn4e1bM^L~QKFT}kzOIEq0!G3h;sA~T zP~Oy|QM+ZT_(<&epGT!#+nRmqQ@<_PC9g|8bNClJmWmka+~FADA`Z+)vhxVw=m;8m z{;ch~uuP>rAGHk!XT(U$k1rqw#WMO`fBGb>M4EafJ2FWeRSd>TM@B{GAp?p_Fn?;vWKMF?kT*tPe%G;ahb2b? z0Ot~<+e|zSL_)?MJ$?2?i=JZb^^E7Ep1^cL?#J<`&?Cps9go`@jOgPqj<5;egCGBQ z>}-gV9vMqNpUGr2!(~Q~Q*qKkw?L2#G>d|v`V$l1{nmel5Y0AEw_B!}uc&+J1#jr* zQW;#^rYdimdVdV#;NXO1JC0__`aPZLR5q^%-21wt7>u%=$3!_ z#$UYO_%Z=56`e07nt6u_1>kP=lb=nF`as%y;pcxxt#MB2$}snvq3AA;naTS}aWv2# zR6^uO$gY>j?rPeLS~$|&Sm2Jlip@R1eQay9n?0Q{>cr2*Sb{g{VQ$8qf=DqX7T!A&Vz^r*)rY7>87XvwwoCHs0&yiWIdl4wE)Kf zT*q}m0EC)QFf%jp)X5$s%l?#9d3@v4IaR+UwYXy8vOerGJMXlLBEp+7H-SZtggtJ! zF$p2UK`J|!J+}2g2;< zZEJkU218p4Zf|bh%GuYE^Z-nLvwzjJ@}>}TD`{Yf97-4KeKJIkANTm033=P z_J+q8uVc9&0zxQ6g>f9l0AwOOcUtV00RWH=6fP2LgD~Tp7*B@F${;~9J1b2}hnx{o zDEAx-(6#Oi7tmae3}9wAxHafaus)@sS(+v1i$k#!;-F&o{8C+Ur5FTjlK=qNhr4cV zsOVEzyXhel<#=6kt2J4&8`S;}c-sUGcOUgj6H_o3C4C~|?sX-_q)|%I*8m8_vjiE$ z*%Zmj({B51Cf0B2uQ4aNKo-I}yk+$%Bv)&F-&Wfa2ymz44Qc{&_d$avMmkKsokLfq zI6nX?{BT|ct$yX;*nGqb79)XaEJ&8LM#zg)r4JV`-@&6Yig6{|s9&X-5lR>J{-Q7` z)A&#fcMY-D9zXUx5gis?nRXDC9#4A@#ate=gB=&^RRDDkYHcDNNtJg0#ts72rEVK@ zCq3aI|A;3z%LYc6P=E{s%;6yf1~DFPk--`->4w{K34$AOVtC(8D^b94jEW`g9IRi; z@A%xJn>W3|U?@OoxXTx0006836CgZQo9N!)|Q(J8A8MYakc(^NJjm7>r;u)Ph zsatv0;uS<`Qo5lC4CI0UkYHHH=G}fqaB0diWnL&Z@9ZZvtc9)*)@glp)jKc6eqY*St#IC$SEu#!JrMd07RF&9Tjt81X7P1egKb=2G~i*K&;(b z0b9lFYy=OXzG=)fyRCKJf5cnd=$t*{ZR-ILWoZaJzc7YX<7SnWYAS}p#i$Biq#Xtf z4Y3>=hCr4bOAQJZgCAiM4s=j<0l*=+G(%3U`|koU$Th*n#|Rg8`km zHJRJlhEYnbsW(>2E5#3gQrinaJ>NJKzrZrlBq(K34)z3R1JTj0{*U=Kpfw|SP4cz+l9^owx}B& zh0Zu=J>;~r+@~#kc!r6K8if>9%18DAYk=7ig5@wm@Pk&_!daUVccJlDA&O=FiQPLp z6a=hSZf%$U`k=M`I@$hdj`6 zcWDbuptok+-rv-#nkwLYbw8x&{;@0HYOpndosBq#^ZXNdol4Za|KYW7d_A9k2L|se zzFJBrYTm;=_B>y#NdYf(dUF5XBBF~hon%zV6O_v%UJ}9$8EZx&G=f?HJjMAfT?ZL+ z;lWQ@u3>X^Z+(xT!T^j-96k;JU^seisreo1a8KdVmHrz#e8-!BcmHxH^8>K$H?DkX zxw7?R4J+^8_{*z5yrI}g7kL+(_?{Dm+NYR`A98?U3;#vIc`)pO=RE0)PmUWhf`G75 zJWm}qoeg~i*3`rW!n`D0?Roh`9o*h{^(8i=i#M_D*sJx8C&0yb^1~-bp<3hMJJH&_ zjCSsYM`oRV6B+#!{lPe0UwgI{ zS6}{XTe{q--F^GkAKJwF+SSz`eD9L!iniwpyl`_6b-RZ=&A_ENJRyCnA67Lpv?8GFk&l%2t@5w|4o@-l=2?7{La77f)t)x|L@3kYxP)u?XvgS z$!YQGK-8Fn=ipw1n_^n0iQ<+|9pTuP2)Bm@|_4as}(}@D;v-C_xJtx zN@wqXSlM0X3*TNWf3I)n8jbhwzImsoI1;=;jJ||TgY7KZ3Ss*-#_98wU@BD7-u=tV zNTLa=vc<=n;1-Ch0wBUGRk0Vo`|5jEtXSW=SB0;D!Xi>B?$)+@PU3;j{gDZP09q3o z`zyKk9TmPp_0p50LZ{5Qj?Fg{Efotz?v4b~rWczQ$av#UXBS1(Tkl-Dw)LvDd@??m zt84&3^{g~_SR0hjKk)3ujh<8tRI;96@d zJ6*%pvE9SQI}X0%fRgDgTkow9-MgOReR$5r&HaHl(q1`FfigOCIBp$SmL7Iyb+PCm z7P=(pYQ>>2XZID0-~omE_V2%ENEor%>SNzz%}%%Z{@rm_gSz}Y#SI=XJ?QZKlfhcg z5)(5sj~Y`OOj7#TA3eGpJ9khJY5h!c{6)FCBg?0aI{W%J{>1GscuMBHRZ`wFwTYdE`5HLAOeh-{zxZ3+7_hOdKgb>G*lK&4j5o)k4?ervJ!Fd~ zNadp}@+6DVE$fr}1uRVlP3VHR*bI*kxWJ6y@zZDf!fc=q80k~Ut!e>z!W%s1U9N5P zYqH#YD+eFnyZ%ah`@RcBJiXmEc|KIy?{(iD$&Ts)6Z~*|AV*M*ZJA{*#YFmnpF$j#qC>dDXSrgT6+Th|dGret5 zD9DB)1Y@UNvyBok1b~j|h_<1X6aKNNH#{A{NyD{=BOw%xnvxKYa%u{+G#i45)oQsW zHdz=#F_xrbmOw&e5S6PIxCEnNFf$SSWH4?BS2Xfwf9Z9wei^Ie$4(}_{3I14=s3w7 z%><*vX44El=u3x-q*Q<*U-)Fy@6NTZbR)<7qI1VH)*I|>1*SOw2k5*LM%w|iVOIA- zWw>15^OBF%ZQVOZ-53n^ArBU?`LwG# zL{-yBo|=w?KI09|L-4FDkwJn$88ieE{9#DOgNCO81JS|2P;8Zqh4(P6EFf=fEQcq9 zS}1(<9H)pVBgvz%cWMEK;8^8q?%;#gvH4l}Q~+TO5XeJj*cVxd`dU-RorcNxBs~?6 zCm9CHQ1uIk6#E@sAEb^PGTZ|Q!r~TzXUN2<)3}K(On;`l$&0GdJQ$GC;Z*F%9K(g# z*jO;*J?Y_wsD>;903bjN3Px8 z3O2i@!h2eSikHG~-Vnn?wW+CtmSbQG!~M~)pYbx2Ov=X?lx}uh%|g0BY=Kg%1Hl+)ypm_e7e4I8 z0$Ur7AcZxfO{V=MssaE6m<`rDWoUg}>>fFhJkZ5Mo*=GUs@ybWK1xu#?Vcz_OFMtd z%ZeAqWYj@BAIfh3eqav}>!RoM{ri>L)gSI`zgEBeb|R;vnU@bfXf3yj20WxY)&6pM zw4bldY~OpQ@(|rUKKF+{-$d5w)SG8^a&N?m+buoT!(v`hvvS4p=f)yMQ&(Gr4}(ZZ zLZp8CcJHN^yZuT#IR}Dl0riw9#l`Y)1XV4oYi_{hhxP~UKHrzxTDyICvDI{35g-Bp z<{@FIx3bKDcxl)R%8?Y@c{Y5oGPeNJ1I{T@k0!B%hOxpSQbLrwKRI6gRu;dPjWs*r_9(t(zFnlpTZ8 zRKT`KiR~7$Jy4+RBOy2B`GoJxP!hDXFO1Gjg!~|r;K7u-Z5lcaRpw`(oWm;DGTCPU zr%MOPL!p1`B!{)!Wh{kI;90~5E2{JdTX!%BR%{ah0I~{%LZ3O<{Q-h+U0g-iZddz7 zL{MKh(Oov(T)VZ^qR|R8NnHOvM32U@qc45s%On&-n8UAs{SR1x3KNNS>u)H>#Cz_Y zyIs{(UAMyi^j$QB$%eRyy#yLQlW=$0amJ@RJazQ5r+V8Y4tA;2|H0q7FPD_V_ER@* zeu%Mqepi-e_IoO+FW24hNt^(zKl@%dH(`3{AAI#^;(@F7(9oOPU#ZxdbAR^w{bdLt z!@;}#*REkvtk$94`pSRvrA8=D{qgnx%!Uq2c;IXKwG;jb7K{>ptiLO|{)MdFrsJm`|zptwrw`EM)jg@xZ8+Y|N;_*F7ne{ScQMnLGf@YX| ztR~7*##u=%)~kc!}A2VyoD`)m3+ISsJEKSTGKC zbTzm0vJ05TpYx5T4imulzxp{gb;016zxdPtE#zGQpv3pT^7}FWFpbb_;&kz^-i(n1{(e`2Z4AbN+G%^chN{E>Vq_*X-h?-P=BW?-txrjO~e0{88(c ze6W=l*L#3dNx*U^QHu;*$4#6x)k@BTjKPF-gYeZM*YZFB<*R05|E8G#Hpy-lfe{mm zDZS-E`*jDVh~>Jdx_zuPr56*lZd4Wz#Xqew<8z@S#L?Mngx09`{n>5oPT8UO(CK(TZi#vw)RQf!LGqw=sD5Lt>FQl+XQ zmWB3GF4vfx3QLv&06>u!1_ynGuQO?KQ|#`Feb1nugr^~Apm?0Nt&SZD)86FB+%zwg z@HC;CYY2_nSQ+yBBCXvO#DIy3M%!<;5d&#DdV%q^AVsP)H#hO6qR`)jAP^7n7E9Ao zL@3C(3B7h>i*c0ty;5Kk(mV8Y2CjVAhAdDS7~x2are^=qOoVU%bA)6%hgpz+pf-Ukj8%(}^T_ z8YMK3jKLu2skCVsI(CoAKy2AHHxJrAnT9FDbu1bk6@D~+=tLs>dBdkD z!%rnzJ$i`EGApEXV=?03Fkc6HP+^EmI%N6G_mMdFVVgfr2|G6DRt+qMISA%~7SBs?=1% z>aTV0OI)&_GeH={x2!aW`VA4cF(F55BBPKbgy3BpkTG+d;UI_{)M~`IY2y`?M&uMw zDgmZ!gSt!OoU*M~VHHRrK-U@XSio2ZGpxYah}L8AitD(pVONk)*0Ig5pkRKqO~9bu zmxQ7ffu=LleJfDLgeObM0;N_Slu6g$;hz7VBXbaY}W7-oj!F|BWG=>3tF@|TK`_P z&Nqx&i9(bFR^yIOeUdP;#|h$0C*T7{&E%7bsox#YqZ{Rx$3y`?uj)I4_y6*cFJ6_Y zFo-{Nj3^zN@Tc{PfAkF*y1Vw>xf3tE{^nXdP4O$ZmBy>kb)C9$d!^p4TxX&I=_u(~ zuIo5mG(19cN|>n*zU`LRVg_lnz@$WQD2C`6&=giK{|TVPO^oG{wBZ9?|J|+e@x9JI zF+@fWB{wR~EEz*p^;_S#=Hr8yC#n4C8vzR%bE`MYY$KG zN5vla+!y{m<=<)4suNLvLkkV$RO#OpqDTB~w~QUVpeGmShChj8k_F{8!6CpDK=^Tk zh3F;^mK%K;i07{TryFABIv>8u7f)FnKq2TV-}$w~A*3m=Kl;LE1r z4481{yGdB|`;ffR%IoA|yE&SMvqD8U_luKfp7@B1bM(|?Ff$s!QP7(^aq8C`3;J^i1pNiM8}9}j3XNh68G^PdGETE95H<9f6Vp_{mS@A@i;it_8EYgDp~INwOr!8yTyO#>LWOQ8GL>-0 zLoh8RQu7MwD;gXeuN}TH$X&%oj*ibgzq_@>z^7y2k#cE000o9o zx4fQ5Gq665bcGGwK1M(@ZBWXjs8Nb=AjSmznr$%v3SL&SFQx#%vIpN!PrPW^Kn0>E zqZeJv!eN>9_s_kUtZaQ~G$@Tq-Fo*;x4Tp_if;QZ4pf3~e)-3L^~a#y3@3_Pi}is~ zH;}6utBP*>Q!DqIz1@ECwKx%7d9zrt6)~p0+bqLKPuw?yPH24iaT~zrJV5{eM0rmO zWe{$Ey%c3M`-m@CRi%GRM z>)i)Rnv)D!WH3=PkqZ%uYwWE&J)8 zNs}Q5HI9AyS3$e#*z}8E_*WVzq6YB7so&6T2Q~*sM&hmqv|@%olfnp}VU7|noWv0% z)WN1_Kj$4|2xBV^99HoKFlHol36Bk#O%#g@=+TFfqmBqpOmV+NkQq9fG8@ini1n)N*t z-Ulnufs3qZPkFG)#&qgrA~=&&qZeaYj2)6n%uxNqIR1(Cmun*7AFpf@_$M`vP7HSF z$hm8^4F}e?PB?8X>j3@@MBQbsbj>1#uRIhU*>ptgRG9`J%=dpXN&8Al@zU0EV&LpROnmZg%T^ zLjwRHC-He%SQk3eT;P9B93?|gr+x=9np6$IhLcnThiDmaoh(hO1EZo!MP&d0z`!)H zpe8po03KMb3jjbv>U4yqa5NplnVGq9p{zKT<7e?M;%@+|)anCN0ie2&A+4EinKJwR zV%TGmdq8TrR2Ql}G(`XaFiLx>d<9uea-($TjyHe5&}fQ^ZK?w!O3;q$YH~wj#=Cv< z%DW$KextblPWjfgq7pueIBvLlsCA=9ELjJtWH}B4AU*>yMWM9=?_Lw}D4#eJw{<7O zJ)xD;Y>G0BZuM%tdbRD?HiMwMdazGss~n5bX|WAww2bj;$Zu44w3;plA3YVlp(|2FcT$7b98)y58}d!8s2A01t&zV-&3)>_NEG ztq7{%-rCHm{eHi>%sHsmbt5np3yh`w79Bf?oe4NNsDXR+)h%7>V+;|F9pAALci7ui z)378n(dkN?gCI2SA10B#)}Tsaj4db{VkH8sSXMOB^&a5Hz!YqI*gulVK33@SAFh;` zz|5i+Y}i3dP6QH0)nExc%^#9_n*adhB(c-*4tm>`B{={@ zc&De5Pi$5dP#qha`t&f#PWl44B_5fM>ls)B?99}>>zg%Q(p9|}8RCMoAOTTHT&k)R zj1~t~x4&N1wqk9?^FmH~VgD|JLLe(gsR-wi+J#j7u%-^?Dj; zcRc1_?630HhsDbVT#M3^}wLF1At(JpmxMwaD2?8w{E@uUIO>A472~k-?#Ot*}2Kf-;!)G z%HXCK!-6A>hdL+1I9AQ-bwXiQk^Uo4(2qh7Sa4?L;Hrksd9ib$m=9#RCx7QRc%6iy z3w}SL7=E00(XM1H)P37)(|- zU74(^9g@H(*SkgctLSlWkA@Uw!*-uEtf6|XpG^c)lM%?-&>;lK682V&AY`{T*KH=$Ttb{$4Zi~ z)5I<|5PQ=wF=DUBl1!hWe12k8k`3}mD1VfK0y3C=7AQPySfLY-ycl2G#ZhqR!OxZW zms}40^r7b$PjI@HWNul9j{R%^F#HefK5_gJH{LBxKO1aB#A@=n$m4EzKWyg`qi8L+ zr-K!UNHni6JBErv{sDI%aRh9JEnB!oXj=KAk3}qrotOlOAs^-r_{%fEddxuw!-024 z#|x%J?IxVd|It7s(OEm|uKod>$Stf~`cLm&kqW+h>MKgW6m#z1{=XWzQr&`9J%O*F z6RPHyb}-&yr)6=}=niL9%7a+Gpdjm23p48{VzSTG0$!*4X+ZJ8?CcN~BovY4#t>Xb z=Ufk+u+IkU#6xTyC&e?<*#&)X<>>R?vU;}>oae7pk=W?kpS%MEcLgOb7JfWrwoP4n z;)}o0&TX>rxMX4jvzJL6X`8lHRk7n_`#?+)Q;rskXGcP?_-|X)AZTvv-LRnXJ~(|5 z@PHa|dj1!(%Qf`E&q2o%p;Mr{m>G# zQ{qE2VHcLc=(XYFvAlV6&XQny0jS+%Q5681kWegay{C(JEriE%?>dyxd;6P>_P3pq zmK6RBkP%0_A#4nwo~vzsAK3`2h#Lwe!zVwYibp5BS8-H#y}Vo(t;&Ha4_WuN?NB)m z$oA7Kf+r+PoofA){>Zqk2n!?LLl0&xrK{R0_3Eg>wx})`3EklpAL6Nyn=A6D|(+FvN>O%$PEVMJNeeK8;04^mC!3>t|7Z+9if44711?e!aOjFt;0M~hyz{k9%vPhEq?PALO36s4CXFh z(nn4#-UJ!BbnxD$jVi^>4}j&8bDYqG9`C-XtS)ee+zELl;^-QhDGgq?Ex5lahC;!6 zcMcGwQhB3kqfSK<00!Qh(sn`;NOZF7eRZo7sqOFgv6pv0y#I~8+Rd6!EBt*J1>&bw z@CFH}<=Lsr&o$zBW+WWh!q9G;>$89En%3<#TeRwR2VK9c0 ziHXQ`z*9hN_6gJDcw*bqy44 zBc~dU!y#C0Rn%OdLZm4+b!Y!w`{qx57=aN!?@$7SQ4m6UH#ZDR0YPxX?vES_4S75R z(|{omr(%OrKM;P{?D{Op5>{!Uib|v&IqFS66po(@jy@9uA@I!cA=DQ_u>$F*+(8K* z0O;_*K*dgJXHwtWY^?j#0>XqQKo1WzYeuRQJzxj$%pr}mX#j0;W)q@drVN}soMJv` z_DWmv1GJABo4c)kKR>7|TL7kLfun?QcD!>rGkhCaPn4AiYt!?%60bw?TWcUAd35 z;689w4Ud8V5C*6Nu^SvX2#Wbow4+)qX>hR<%AgD&6yVm{^Z8x4F+CR1c2t+eaKw&b z2YfRErp$x8%N)j_ia8Gl&L0|TX>uGvep1^_P+XLt72EWN4yR&gda}xZsACzEv`4el z@zYW71ZC@ve>^;uo$0$-T*(01mbqI30H9g0S4;PJMSHJV9vB$wpPHkn=8y?Br08+~ z@sUKWs!yh7Ew$$lcA+9l(De9N!qGCO8FA+y>FdD*@`lh>B*AzSt`z0_%Y1vwgaa7R z>PxrwEAid0qE_F1|Bvy&eZoDL?=_!Ir!0e|=`4#$TGzw1Sfh*0|{r& zn57Ysoz<|h!5-Xd`rDb08%hYaM+iDv+qyOsR|jH!H}~T(^{nae9vx*BtSGCzsUuY= za&Kz}(O&LXc5On=?{zHA#W%+luh_rlsE#+(O-}|9t625*veU;bxju-d;}1LvfQSQy zj59}_faHLse&iV)xmn09p7^~<_m)~}-}UZo3E%l!4Y&3yZ#FjW3s&6%5J5gTH}inZ z-La%H8)t!%eo)NM9Dm9O?x^cU;M7qbq1p3KzrwaqYPRh?G&08My-nY3=k~^b2Yp@d z^|{W>gl0rXe(e#`<2Bp$1>dI$f#GKam;V*CdlN*oy?5U>b)juK+(F%P%t&^})E*D2 zof@){AcN$>J%q39?k504po~_fve1++OXzKAOKt8Ab)pXZ#*gB?rj|JI!$1FhL*I)Z zK6^X=RRtA^_US7(mn4LXrKJ8V@3Rcvmy7C58n+P?%)aH;9mVZ{<^0#lAcuPoF2C`%Gdj{T!?nNt8kc^6@_D}d z7hj6_54(KyyZ`DxhPqK28f*`KHzjPDE$#bvS1&E^!gA5!w*Y_JAPe#tv{`^UC`Z{B zy%#G;$3J?+Uy?4+-o89@@sYADcG$qyxqItxFx^tbzqTLi>&ABZu7m(t4QmWtemTkp zWDS4g_5X%Z3>pX4s&8=~uhvNB3fpuvQst$U5mwgkb|=JpCb-Y~_U+Pr-*bd*;28mrsq zKk;a%uxs{jr4lb%Ter%utep0YO7L4)>pw#srIMGvym+g1f0vZDTuy6ky;mFSq29pm z{mb5uJ_B2^z$}N@LNxOv7QSdF&O+*t-WhxBmmi^#F1cRexl2*q3M|M&mF1KP_wc|| z=l;FlZ>mejkALQi+CYPfL-G$Vbhi86)6>hlKYhV7Pijj~-t6UsfvV6K^o^UPZCE=9 z-T1Cbm>6}ByjN=+0jdb|(+~FV`HxC~Z&kv6Am!h`ce|{Ja=WV*;-lCDoYZ85qtzQ* zz9Yv)E^*b02NMrzH9}Yqu`$ybIcbfbeE;Py+o^e>-}62GOTp;R8`y

Zp*(^01o@ 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%0Df zIH-dVH|@W$&Au_Pj~(C9>b|F&Lz~PIFy#tTw~PT}$hBsQSgu#RogBZAeMAmj1rKV4 zH)Gcp=U+TJlBHKj(xn7FeEB(==-VK09Enr=aj&Bg+aZ_CVmzQ7_0AfP_r4f-TxqvE z(u#m*1Rms#zq)ITwuvB{F1_R6jd3TXpyBzEl9q06c!}A$&GIW z+J(}R(ZNnIuFb^bmf4|V1tJO*Ko^;PrCS}3_Ch?N>b}jnb`(t8x+DL;HhM-+3j%8q zjg|886_Z&=TRs4^QGN7k=QL|3oMBM(k&#N$d3+@g;NZ%w6o;TC3{U4484Q$Dls4Uw zL0r|JjZu4vro+&iTH}+1jL+@EF}>8mDhQqi-AglEN8G#HcpT!O1B`ciT^9@45#(xK z3ITJO%V0wLwAUJ2n&*w0L^~OGr$NYhsBZWlKm9OM2^8NEmIfd-Y;Av_By>fqJ8pxV zr{;}Vg-uXZo?l>HEc6qAVcC@_?}UI?3EG}Q7pUshZy*r>Z&5ryuXU#+0l6dZJc(#$ zG+KBY0Dw?W*8I4M^7Q2;I4jKjS^_T0J5Z$H-_!9#=nk{?A5OCXTpqd3)|s17j8X zzxq)czvM^OkN)TX(F1Ft%U)alJBU;X)N*N)&a*(nfrlqQRrai`?n_+f5B~8V3$Cg3 zPPH#SmT3hXKkFR*t1P79LFe&L|A*Dwbz|tn+K~$4P$>WLU;UryfJFr8uYdmMwr~0| z@(I?ZV9X|ZX!&}w@P<0s@iG{MB3zmCg>MbmOU2w03c5X@>$nn5kI2_fs1aQ9t&Ax9`KF0Q|1ItD`cH;)Tzs{5fg&BEVQ zZ1>6TA36jv^5kq{8;s4?OgfuqWxa2O`JoSOyC?tvgW=5vw%vw4J%1!(Z;V~hO;re%kNy8LDB?01l!+zKa=y)FT4-q zN$PC;6M=|9%6@ckY?sG*?{HUlc4^D2eA#N#QkntRAIBE5dnc#LZotn9)9Jn{U%GV* z-uzlw#;mBY8+M!1^YB!VHnKiEgD()Mc&AhSMn=2%%j6m2zL>FlV0hRinhW9%G`(5q zTtvul1lSZAyhWhzhp~r7y)23LQ(4sM7oG^ogLCr50Ku0L@XPkyd%@umk(&me9~cb^ z_15GI9b+kT6vWXV-P`@6u`$tm_rF(|-B+is;Ws`Sl;6p?_H@|%rJ-E>iW>trJi6aI zc{~6B0HKh+;1E;Ll~DkQ!qAnBQ8KkgM_m7fi03d2PqECJu0pC2kyc-x42FkC!Ez4) z12{h5N>t#Rd@U!eaOs5`H7GVYwF?_JnIxYh$WR@O+ZU2H1ps)Yo}b%l19tb63GDhk z+(f+TBAeJq)&K{w+PTEs)f|z+VrZ0%B)w-xKoEGjd0syg@m`ZIBe*`lxRftOLIp!S zXR32kkrF{)5LgcMX*x#&dL>QsvBbQn#6y**6I%#Ell1&ta+d2s#f>T$Wbz~}&J-N=#-1!% z#|(l}SPvHfz-S;`b&JoGXD)55=Xs>7brcv*0{Wh@_Fj?M4Z9s>&(o zJBg#_I0KM|unY^KZ^l4lo&oa1{**z8=4dx?eFj3~NfOByiW04P1$e_h)m6{P`i({%*uMEuLBeXO{VI!FT~Rp4tMJZGg%HY$N;kr_Mgq(M&!2l z`tqgmblcEIwj}lC5tKxtD6%H*uNcHO2G&#u*>PG_O`utb=qWwW4!aXZ_u9H6fVC;& zFCpG=wI^L9%Kq@#MVQiYQ^3qdUD=yX^z~YLui=PtV{7K}#2uy0sO|)XEU@$Nm`uSa z%=053rE?U5VJVuIZG%}`uv)llx=6mQETq6_&SVIIn{#+;k(6+^o?3}2aM2CvYoXpsVOvew%OgY|%g#fEa)P#usPpA7 zKda?pzzHVhWsoV0Y8{0GkqkhJa3*+so-Cl@fhnoX9;clibff{HH~) zYM0vQ?I)ZyH#whF=H(%t@yAE2@eDF24NvsNDo#P~)KBgfzjhl*vwFLO#V*awW)Ir^ zbm>-y@YCYw+5Fox@BTmqY?KU_Zv0K($wreW^vs>=Y>GWQ3T9^c*`L*HOXKG$@NBTd z<(U3kbreB*I zD2QGE8Xa2<_w%XkrSO(DDFRp35T2dC;-vi9X;6nQZEI)b zevLGR3?ucNB0Q{f^oez)aP}<52)XXb#ZqpgFuU~d$-#|T^1M#L*Rk@X>LTS+dXfRJ zVGs{2ageJUqbH{2WovXHvl&H8dk4Q{6Yse|$kGFEj{NH0ZvKY^)2LdV7WO_?{p7e) zy-f|P#6q(Tkqh=GU%>Y(p}=J<5s?O%^ehU}-4^YgtEb}WMeYg_aT4ER*JrR){Dvb#2?Ps{J+ zd@ln1j>2cCDIQI=L?Io&j2UBO$;Zre(4g$={o+os7dy@7*AXi5L|hW2xH_LIfN97qM9Ep`RGCIh=KYFW->|2C zCZ6(!-TU+oh^&vFU>YXrU9!L`L3!f=TQ{Qv+!oH>gv^Tzhab6m?Xd%gXSSIqN0;cXX zRNI2M%&_0_ZC@IhtDKOi783F4TqVJ(u$~T}RGMGRgDDmET<0`nwdhKoUrdCYBP#jpA#I{FO*M zpNAa?rCo7|HcsoU&kW@v3O#68T8Q5y6I3i$)20oy+{ypwdLi=;LDs?OMd21@QZG-B zciddy^~=(k+HYulZsDms4Oe)*T?6P||M-5tuLBRC@ zGNboY1nIjBlu*$$o#$TP9nJZn_H6Rv zQDTv8O%JWprTEL+AiBUii04-igC@v~`K0%{EG4433aTb9j7)3#H zjmPnH=4vAHP;Jz~Q;t>l8`?w-utTxSB4`wa*a{cgMRR08d_PeZV5&MkK8A6~RlKQW zbS4@FBLD!%Lvd_ONw$dMF$i5_W@QjW5X9;_3=0=Sgrs6|6iWua4FJFpsG-4>Pi-W< z7z)gFE{vAt;qfb6CF_!r?}f?a^%zFxDmMg*{MD4!{bH=wwO{`9_#~vp9?(b1kaYV* z67@R%Q6GQwad1_mts!nE8fPJZWy$zytnRp%wntVD| zlRy-q&gJp8*>fEL03gp88!QL_2!;|W(67s6UkGj2?6Td4lFMDjKp+Z(iDRj@Bu;R5 z$I^3<57U7;2STV}91mZ}kQ0fY9J_`e!b*V(=l0E`WsiO zx506i+Gk6F3NlohScKXa$n;Nh7kxAEtGVX+!Su%JI>tJ}hhMhxS)W|Hn%T67#}Qu( z(6gJX9^m5K{gHZ1p$K?H_o26cVHDxqd+(a_NtMBG{0HBn7&Pj~zW?`r4_!-vMG~p~ zm55~{zWdJRKQ^lCdh2Dr^7p{l!p5fMC;p3aP#X*<62DxC|JO8Mv$_Aoy>dE2ZPnq6 z8eo(PR&>U{{7AU5i*q|?Km7;vyAfzcX5)Wl(h#bQM}Pf)z(AidAL31&2~<;U*yApL zoYGi0unO@<$tjw^AmC;8yJ}bg9MdDO&dz;5kacuxmbt{VcBk#i89Nj7GVcY%GkNO@ z%~n!*A6mg8cgI$Y#0t{%K1k^cQ0>{o|I;5h#01`_m5V2Pe`FawU)wd0{{#oxVUb$@ zy3AyuLDT#)(ZiHpU)n()KgeszUggh(w^$Rv*M39UdHw5iK7-CLMk8`QQpd<7qIjQE z&yIdVp0q&!qBPerD<4u==kq5c#IGmvt@Nw|y2kC=M<<69ZWHRHn~fcC+AmN1{!y~BIltmadVJQe8y4mD>G4toKA<(WT-N;puFRqB0@ZKU=v+5-p_YP#@Y0?M zEY8rU6rulg=MUzVncdxw5#mf7KEjw*qG}75NM@=2>8D>57gek(PL|RBg_cSA2B|$r zP93cct^P>S_>0{!n@Hi`Nl!kJEXM<=MQc|-+MeRoTFio<(eg0vlH&E<@mL?2h<4R? z_0yj}jwRQBwE=`6^n~7c2o@4#{NFv=|9_%Nb4v^_j!j!~12CG2#az=OlQ@yUsv8+B zMGHKI^C;^BsRbJILAXM^u-(v!Mu+Eviwi}PY&-!)G#Gj`o?t8V5v*9C4*-B8=~3Wh z2|72+jtSq-;=GSN`SNjKlmNt`G6b2z@i>MNl;uQfQ=i_A@jOK6V1)>%f001BWNkl8z|ggDACBz({BJ4OrEiK&)kX9yU^1q=WHvu`i5iMpZcl!E$TXh#?b zCo#e}Z{X9(pu0C!Gf@g4bVKtVxlL-4Z001xsp&XRPDev5N6b}G^9179=eBcCW zoT4GjwM96$$!95sSfQCBX%@f&P6wMr{6<_yeg8QVCT^kBNQUZR!>fHa>4*iKO+f$? zhq0dZ#}rdVd)=ggO#{e*aNj~yd5Cz*#pKj6hLUbwslBZsd`ws+;DV({Kp8>_HZtSn zOgCe0S*jd65s}xB+yp&rP7rb?Sz^UD0>_7j=Y>+yfoU*y(SOh_%-KQ+L$f%a`UR&!x8GI)PVOfbm`5$khhNjaXuNW~I_Q z-=ml-Vc=EZm`f~-rlDZ#D3ps9~TIakIMGod~qS&*SpEZkX?;ubjW)YLd ziKv*mK8;rbd%NxjzU(>ah3lXj;9y=4H3;n!c@l1AL=%D$jP;Bbdm=qMbJGxThyZ*`CWgi1VIlHeP2LB6)dI5~UdAB~&TtuIiFHO~=`EhMg@L&f87T%a2$+iHyWO)< z`pODC3?$#4b1@|=;GM?AiPNJ%jl_INp11qynJgA-w05Q-1R`W&kz9$Vh66=*Y@bCi z6oPuTG0()MOigTohVDSv(UpxX8rtCUs~GPe*)x@2ug{F zPu745Fle@5EIWwJGw-6si59r|;Zijw&Jy z;aMH-O>;hP(oTpOJ`|sr1DxsGFJg(Rbv`ukVBt3f^@Zl^36mLK>2hsPhn>{GdQ>Z4 zy_g(P@Kw!xAjGha*V9K6@p%8n8*kPIMaq@~MH<5E0Ve)uhTz~jruPl@DGVqf> zq?Q&T>#U5uI3BcfNKO3m|H|Jy?4594_Ea6jtP^|y{M6*A=CQI>9<>MKo5}y&;PMjn$xTChfiSD( z{iJAFOn(0-KAp8h7%|Y|qCicelJ#cZP8^0~AW8-IP3SG3Mo+`XZcfJEMh&en9iL120?i~KKocf*S z!)KLENqzNea_}#GZ#^=>HD5gf_HXS6=KO-`?hD1=!6gDa#Ml}QDsQInP(|$Y3Av_4nEJ3$kAHCw&5sDRsuTzCs7l*LSVfYTLaV3p+y zK2f=81x3?Sli_7(CiC*yUZq;PNxyH+r_!|M_P3}!Yw9{4WlKn2iTwGgr>$>>{Y*q9 z7-u=Xb*;;;fE|SeNwM%j9Pv)40+LjdCi;=pdM$B{r5-TI;boMOS&A|lA$z5BD5tp?#y z@>+oQwT063TuFiNO!ZSU*3F!)-8cWVkXZG2A<4`>|H=Ket+W>hnDg=k6I`^1$BLsi zkt=)M;|f1ZcICTp>-BQ2Nf~TZ4uYi;yYm8XY;wp`DImQ4Y)_jNqYDPj!t9 z0Chl$zlZnFT|cx?z|OLn!Fii(M~MZ_9yovzPC|HMOl96Lr^_ggxsW2L5zi%B$}ykH zq5@#I`1zHZ%~-u=gD#``7$gwfnKUMnBrI^jzyn=fnv4r`%vpUxg0N!Askwr6E@@=L zwr1i`n5)9Fm;}5L($a9o46zE_?_jfbozn*ux&?IdJ7p#_2l-84N5F&7d91QWe`8yT0UskETso zgrygQa}lzE+%%FK?-@r8T*!B$z2_o z5{M^UYvS3W8=T@ZfzwI3nuSm>r7Mb0x4K%QTyA}N$h&zn778hDaHgd;5_CE6v>;xX zm-@SEcaU6*1x~0BM+}2xc{ok2c<8J=9l~igbV}wRlDnt2?DI!IRlykzyV7OJ)8Cg{Vu9&{{E=gKY~h8m+$K0tpmjmFXT~quICC4j%M? ztTdrq4@#lK!LY3^IBex=(zEm%*MHdWoK{g_SD63+z$DlEa@%F+FgiP#?5zmJ0EwrG zJQuII^mC^*CKs8;gL?v;xB%;J7$)*pLToCjg|>JRMiERam_a4e>$Y&>OjAA+J9)Sd z$=z$4Of=P!v$c^)QQ393J?4fSuIWT zIiBx?NX6=2h{d;3zAI;iYp8d6K9T|_45IM*(y!;^Rs8a|aes9_UnxMq+-ibpDo=+F z6`{#IopAe2f1331uMXO?o*)wis2q!9jVQIAFPFD}_NcTmyZ_*;tA*U)qABF&xMcRT zpM8>8T?9dJRpGxTy4VYD&Sq5bwQ%c&M`9DW4)s0 zA+ZqDL`yRr-!c=jr72{m`JE|HJvMRBAMU? z)e5PSZ*(zoBhR&buoNWtwQx38DWHsqHNrurMl~l&J}Sro7)?W>VI}{gm~bpzgz4ELkeK!!9o@Ns578$^7%WtzSk!Kh zv~2ke{rI>ow@c-vacoWtd@^^nlol;@A1I_xKs@aC(=)3G`D*EcJT>RDm6gNxy>jAP zVS>dQ&xVW--uaf5GLiASVSWv!08gFBwG1ktJ~(I7#f~(hnHVJG>_JgEepLI~ujxY} zh97w7Hz=O#_MXoy{kBSgjl;iOy!JOqX00KfCT2FP*GiqQcGrtr`AlB3g<9J6SN~S; zRU>gJV}N5D{_Yz7p(}6sEU4*!R87pQ(qGXn089#I^Di`HF-61n-o5j>UCn&uw!V%R z9(r;F>@E+`uactUI7N$Ku8WsU#X4ha?)eJ%TZGk{aT9Kr_smw0258$e)RwbswH} z@4r*KzMc3ta>uC5Ui$nO{}Q`}sb3jBk&%)gS8;*c`-PVGPQy2&m@#SBu#H2?ehu0B zr8#O`v9e0_oH_Ptrxk~ zwFm;I<}z6`#UpiX;m#CJK*`fIcT@EW*jGE8)mO@I?f&AE#mkn87Gowd8VuOv*X-?6 zFZn#lUyGQccK#_`{xu>|$bh@?+1q$7zrFi(z8(&7vbS?_mA?&L-9*GG01RuEM$SEwzC`3yy@(FN{_f68XY{Z4Mx)aYzqs>TWU;Veo$f8HxE5Hn6GhK)s-HopA5 zwqM0oC^F~VyL%82ZaH@KgX2%$csEI%C%efrZU8>oZ87{(t*Ca%Qy>EDGpj%{GjEpr zPwyw+jk|ipkk=uQG?Y3Mn*l&D@C?sY|9xqdzz8P{1dPz}w16bWW>85~VMC+R^EPXM zYAwcUmFnhsHC2*u&aAC5NTMWHAr3-<8M|}~Ef`;5qt=1+7 z!wf)j@maSld)*A{nLLJ@SPDvnJgQ7!gP1@Q@stBFn~j5TERu~(3|Al;7*3{+T}@ON z&a_8fER~fth0k7br7#SwWjap9@mPjsGl|B*4$XmFd3GFv(nxbcC*oL5l=6vLACn<} zRWlLFF9k3`CyKsCl2oReNzv%$nLH3?7F6+EmMxCQbSe{t0PUL)5M{Z9n}a=}>AJPyg>T_0T#Ch$M>bop)n4y2YoJLj^wE7qvh2^k>HT?|D|k zlFyrlDusv<0=A=0T$A7{$wavviv>|Munol+vIv|iqEJ@TLqtB2VKS7bPsWF5yDuH% z>2|p=tC+q^Cgl#y*b_7J3AF)3@v%Fm=~`h)5c2P*Fq$W``O#<7;oe>%bDh~Rpt4C77sidp zOg5X^DkdS@Oz6Nm6JmB00SIgQ$cd)x*}c1=D*>SyMNtS$ogI;01B{6c2}tq?8k$LY z{AjH9&UM*(poy}n$p?zK*$8CrN~THNW-&ULbx|O2$Qb_m?TRrSm!wTy zIh(ta{eS3suUN|x>r8Lwy!SbKpPbJH%bs)Q&u_;obq!|fgXa)lq;|IUY z!#vss3^>6sY`{_DvBF3iF$^hEWRuN~6}qac>gIgUy(j0eb54GcFpv$*dR)MI{DBV( zAJ(eeO=g7KLRLnFsCd*jtt(na9y}*YFV>41$Y7hM?JrqidUA{brHdNTzNbj>j;8n3gge zADK$aw}KSK>vD*fah9j0wm!Qg7I|7Tr=~d2)XucGqv^voS~1|(PW>rP#JsS*n4kAe z1SjzG_KT9;_B~^k%UG9&5aKs@-U=WyTmvE4Q9P%XYqokV%ldnfGYk<^PQ%m#h=!Vk|wWzTcu-qQ&{!dsEJ1meTi$0^9^$U`*A>HUN9?Fcp+;cU(! zSOZL%*o+gjTMWeCk z&BfT;(Zbt8e0>EJb-Q0TG)=1do|qi34*NAP?f#Bk*kjNWXEn z@_Hl^s@80gqbz?s**Ep$a(wYCo2$`eIu@fnrkI4cq)IXnXnAt%x;53B;Ak#IWz)Hs zSO|p)0@#KP9$;xOOk8-K#+AZ=5NwamdS|VSjiQ4c#609%gOCl08204DYc@|Fj?Uu? zZ_kk9a@?AzCEd|)9vZ_JjXWxtG?~zkRknrrg6E-fq%TGlm^%FY$^Y}xxrPb&?&Ud@O8CPe z^dl8IcO&dl`0>-ll|MlFYheH1Ob0J=g#}{zr-{*<0BBXuz6`(#KqRhz^NXV&Eo!y> zRL_~4ylFS<%AvLU%m2pXE$9*`kovTF?KEtZWau>3$`b$G)A|YCj zTuO13cJEqQd?%jWI;$Ewi)v_Q@XRn)Z6Lsd&xU|3!NTUPq9^ zr^ii^UE1%yl^X1yJE5}I{kO{Llu9sR>wuio#Lq;$&_|P1RmE@y;P3dsB?~MNneS7C z<%JBayY{mu4RnqOuI#JH7wwO4Hg!eS%*X%tC8qm<-rN7>FX54coDMI4{a+z0Nb>sDA8ANV z0s%MJw#{iNrzwrAD_sB1fC?7N)(Z8XL9x9+@loE_$0D?Efs!2pZuBE16ML&)|FrXH zX08y&Pf0yUEfSlTj}R}G%$DDk$HzMQO&4$q6U;t!2A%j_be+H!b!~pzb(SHSfQr)o z%?0{j#iDsd=6)~S=!75aOwX6%#oGzPc=m8&;d8M3%BzK813>Ig7anjg%vv^-zVQw| zy;5BX5yPMJ_@;OEtGwA8p=y@9jSQ15+68zC>vcqE-L{n@Jpj(8g6`cA-JobO8m;l=Ex(?mN-m z6X~*&2uQHK*C*b+sSI@=4Iwu>_r07ob(97F{bZ&7e>Bbo=jvA>y6bQ#rl?K##B6^y z`n%HrZzS@fb!14kZwCMXX!6Cd^@*ucnfsnOzKis z8-@aedMM^~so!r4VtqQa4e?wB06^1IJ(Ko;91}0Wa5NYs+NKIvLFgAJ)r;({4b3rR z*9M)5Xk=ncal}weoaVrC zI#5VY^AX&JAf`{b7MAU!B|V(eC_2={rZMmk5+>3VnZSuC>jXZ5Q4Bu| zBe>=JP!5F(6qDW(&VJCEo~iX;_LYXN_pQ0#%8lDIV^aq4NCKyd6iXu*Ho_Dn>4-S0 zN+eNmu1o}vuqWX{{%(?F5Mgy{;bF25#VUB)^i0HvzI8DG8;>W=zX| z{U5)>#b;l8`(B8!RCdm`#jStwZuj)O^Ki6Kimz^^10x8BZhl3FjS+%UKo}whm>J`1 zTwJrET z>Xjpumn^;Sf@sguYIyOBNjLM>d(q30kSTf1)fwTt+PER4Ug-s<*IMf$(-c9OTDMdE z@ym~zkv=qh@fVifANM}>sEm^wClN?=I`jt9`gjQX2_e76-E5DjnX1$-lI-S6y7jmv z+}R4xLC$+M7Qc59chW@}kk$bRFGGeG1~Xqz$2Nl8{dnfp7#%GdO0%>7SZf)2*KB-J z|GOBtK_G0gqfZ-N^fYf?q9F8leWKVE<~Jc)@f<}O?d7m8x(stA7&9-}HOd@0K&%mA ziIA32WZa%ZsnBE)B)54kMtjZy z1;H>54PFj=M+ZW2g0K$--HL(PW(WE3zkNS@!QBsbjakSMrtN||JS^oUWQW})!s0Y67 z(_Fcjz0C+qesl#zyeJOQslZ7?7cU0&iOi#T?Q-(r$Cn>mUxNU&JIEcYSSuvITE1P3 zxa^fFzG&?I&BOEsba-unP~^*F-xT3tvwd>C|M_Rv^_L?8nWL}fjjA`cY`0VCUPM8= zFf#iXP!#th#e>HXkB!XrOk7v?<0@iVdm~4+^{z7-grU#!i;l>^AQ+B^ZuSuJdKosD zLgVJ{@$6-lvCMZ*o#WIUy7dT`i&Gzza>t!_%QK;YYMuv15pS%$@NNVN>Z_Y9C0EykKU zhK8I%iw+n7^n7QIfj|%i3ITYP!@mTL@P~(IvrNQMk&il85I78D<2ROOr=jjP;wFqo zDpB8{KOg>h8uuKPGbY!e2P|mqu_1 z;W(dP387#y#qOf>j%%fjZ|ZmFqPM@vT3y?ZAHBW#hqJh#+H?1k-`beVWSr4=w1vBg@52N(X#L_YOd>*?iTKetM13$XzP4qv?-qtNDr!~I!&i^zR zHi(za!t@W}v)k>-^>+C?*fh~G-YFnvY*Nl?qpe=o07jr=!9P4&ILo{q3!a8)e)9Bg zY^A-DNktEDk>#NOgt3R)i|>%|ff_eCt{4FBljd^*aGA+tZrIG++_A8Ek^KSAjJ}lr z*J$jT1{$9rk1LUz#q~2yxO)4+Sc7Xj-#ZrrN|c(Rv-jK_eC?mDg-?DxAio~`6p|vt zOD4gtdB8N*?5 z7iPN+iAs_)cfL7%z{8VvGVxo3*bC*kGHUIyncs@B$mHCW>jUer0W&oldcf&Vujp4E zw6<-dmz{aJjPIXi0c5S(Sz0Q&5Q>xf?}a2EwbJoRt7<%Zy?o9tMmsQy_90BYM9?MnavJfHTLYUI*eIp6Zb!0~J`3_MO)9(Ny&+MnCT@E_n6 zkh~FvSBZ|Rxk13sLa2+RBMIFdYoTjjx20B>Ou};5MTq2o7_wD~%x5gcf)GeO6+oXvA~02#OOh43{ybWkf1; zVk-(EpdAGx0?{2j%<-Y))N=+oLVR2C-~!<-y5-x;a=Qm1U@u`G56&^T=s7(z@FtFh zV61E5uG7~0mQ@(0Uz=-!I+Zm{zG)DV=hJ}`s&X<6W{^F(m4JyH$@qp6hDhMsC_w`N zpn6V*pnIKtLutCU1cV5IQohr#Nu6Se@+|s%(pcso0Ld@wkv4N$jsfDd@_h5=I^9lOpFMe5EU+ay~cplfKr%b|?6-n<| z(GtTUv;jlnbi^W1v+ek9NKi>g9x$`CFMB#l5^;8f?i3Z!>Yg7CtBPFHq$?PMm>e0M zV@Lba%qr2HoaYvx)61?cx{Zdo07qJY0XH2Zf={kSwm$HD2W5*8nT!>)!SM-QDlo`- z0?h5c{58px8fPZPkf$F!R6!R)Api^#Z^k-xiQ(VHiF9sz&9OEmr;TRDldi0zo;QgJ zmAvg;qEU;fnyGoVBD2tZXbk2JY6pn%pis2q*Qmx+f3@cceY|zGH)(fGJ-77gY)#Yn z(DeiH#Dzc#BVwMbfT#^2LHtHk_1t=2oYb^_Up{M$CCB72yld(!(HI67z1UQ@MoP00 z0s!l~0)^RS>*&KUlK6^N#}~_#>p}1cl`(F(-+s5eI@Wa@q-W*{I!?1TY2h~!?_u-$ z(D#h(rPplDxITNH$X2oow?=)6L}NIWk>q+JnV=xrgobmFyMJ;3xFZ#e1HKiVffV3y z;On|lOx(&(4%LFM3_0y*b-U^UhU$MexJz`d{!VY$6 zQV%GC!Z)<)i^cR-Z9341K0nK-7kbA-GwFD1d>J?R+0~swWL28PL*-g1SY?gn2BvJgfpvaxfLWSJ$-n2Gk`O#_{CVvM8^Xy zZ|dY-Xok|!^X?Tp6Z0T{JUkNKcohYb<4Kj~C=A``Rd?^N+;$_I-Re)%nQtW(YwASt ze9WJ@5!g6P!%O9DBJB+g?)K|Cm6RMSE^seL#2Em?$^6$riNxG`;jI*m&y21=Eo|JG zTe>wpt0ivD6Z~oYlYTVz4F|K?OVni?Ad&xNFVm1CqZLi?blEF{Y()^e>Db8yfZ!Xk#1}Wb}ksST3Ih^ITFCa(%JNkrZj``0(@>?MZ%mvlW9DKg_Z50-s23^ziSPq5928=Y;R;=EQUCvawBXc2C~&wY_POPIGE#?>y<9;Mw9A;wXU>kHIfGGMugC#9^l!EBgIk zzhrW7*WX*V%P`rQz>0+wlY>6F<+bqCR&Xl03zK=gc>G+Cl}1TuOE^8hjGE<|dWzl- zjkSeYX)z^A)uj;&gN$bQC)1bgg67N7tFzOwZKenc2BEI00U=-qe#=w|2lmKN2HerU zgyS=&+Ro=+&-r73OzW2T4>wo@Pf|F}O)=GT!>qNIPl-&+!^qsLIW`uw8yyf=nLLmx zX8MEr=8YW2W8z>cY{$jU02m?T>PwqS@i%}8>rSpa6jKWD{$MChG{bci%bNNKEumMQ zj6=TVppp4fqS0(6SBsA7dzL{i(WV}aT6jE_ZC-TR$|&Qz;;@rXM*B@Ao-D}5fEE#- z_gNVZGKzd^&oapv9Z%xq$_#a(_Z=tjbqWZ5*b3GvIq7OtP9+J&wH;t)VQwZGzdWxh zFvHWabFpozEs~F5G!|OSSQ6oMLHC_rcLe&h7se6-6$Bz`a4=Ai)i$0%l@4N>w%|<^ z!-JDCZU7GSIs$W+4d@U7SdF=v*o2myDP>!e;(S!#NJSGMQUenCMFHVW3`wCq9fCSB zOH|GFr=w_y0RW))t))LG+9MQ1Y@x8ho6VtZ7`}(Y@QyZo{EI7em1Gd~qhXWBh|;Tf z?bsSL$3J1@jf!7>z=>JNu0pBJ*ypbi-6z)BbZ$4aHNOyHjRMfx$;?xgc`m z;~67YRX_!C2!iq%KEiwz^cIaCjZE{wo{7$TpO=V@amgp}C4boVBKI-_a2gUSRnpR^U)Pd z3`3=og}1Vs?_}nb!RR3L!>wo%g&-3P#%b^P=dH!f$Z*%-Y|1^tx)_44-e(HzYmtoT zvd7Y}C@dT|CnU9w^v5wcz$`JEqqmrZYfVmecX*0qDU9@c<)o8X*{!U&s(6NRaDHC6 zvzB*UpDd8ex6*vEIH?~-iW%`-#uy}0$U^Gk!eV79%Ci7coQoQhX6_azh2xrOTxjP? z!p|2(ct0*itKg8T4+re3{#qh+qO{_#92Jij&3jJX}5!zr3D39T(|{e zSP~>=oMsBR>iD`qwj9ZY*sG2rDw7j6PUz?QI{J!(aq-F)JC9$~pH}h~wN6ck0W|Q- z_Y%)uc0O%9WsA!**ureT!7I(x>dR6bo?7VuN=*a0vOQ(#W+ z8yDm2${Vjz1?rvmmwewwX^1G3p&v#TT%2{@e1A0nLzoACeDwI>;L;RyBE5aS`A4Z? z5gO+ne!Q#5g{55o7mJ>lhO_>(V9TboQ0SCqwMZftU0sp%rRdj66F+=$i4CFn zYA;V%6%{mb+*I}#vi}UUU;O1S{+Ab~PY`nFPySU%Q1&qZzWYo#941n%zP}n7tCVDZ z{3lOKw$G7N`vA(F{=y|5cRx&fN;4l(WRyf~Sg}!a-1A%LIzS`Qi^CuPXwrEJL$%h? z-#Bd!wxl2Y@Bbq-WpTTf>lt2<*PT(#$2CjFmaNZ?hdOi(b^7DzG~~E+a@{5}lf=gS z?E52Uh~EPMRA(xxdXi=qOm@j8qYNbA?9*}j{Y%mHMsnZGAE(}y*_9zK%^B(d+}R7B z>P!sk99-KCGiY8u`m_JyZ3=S|pw%Z+1QLHQ3f+RF_#{cQ}?&zwb7kGi|Kw< ztjxq#HfSu1Cl-h&Jm$u%+Pl{2oB-&ymY%#Q-82wMy5ofN_HcaK)~`Oxt@Xaj5^pHz z+MCYrFtiT<5$|8iuAQ;Qsxv7h3cn4sR9nLCRDLgU{HSF{mq95{7HHGNs<$H;P}jrr^e~*oA7x5+p@ zIsSWSUbR;-e^z3W)DIz2<2~GC*5eV`x`zcr8b6 z8yH1aVnP<#m<8BHmS0J&&=@6SKp2KFLJbh1qx6)6tL23ft*Inc06@^1+R0R80&%)$ zqOrPJ?hZ~M2+yr9Wg?91*uHN>7b_~kcRg?#1j7kGI+Oq~;PP=a zmC0e)IFL6sH!LXPbAVxt92XxpyJVUi5Nq;BNmYZ1Z(9K9PCSSpRWBa1@Iw&+Gd zHydZ%daGe6SGqbyhg>oVVUQ$F{2+u-R^S&&sS`Ld&SQ@1*~T!0a4~Qc*HLiq%;K^kQGW z&|L)zJOBVhKLok?p4#s0O~n3T@8B@t;t0mjSpvnQw(MdI;+g*L|6EOD)U%iEsCT3L zfu_|E007E#!aHniQL!_0CQ{SHlM6 zWFx97R#PGfL6nprU0BwDle?$Ek?s!xWY0~0Z9c_v3Egd|T-{%Uj!N-QT9 z#;#g;+qr5@1K`xtfvevlKB~K$=cM!d< zP3>L?08RnUbhOqrZyh+}gPJ1l5_!v>IEe|$7THiX)txhZXsQj_*6hFz1(KxK8Mzcl zrz!;m*SpP8NAolp{u(=AfO}%I+xv-T_cFGR+f`I?t;b!1K>-@KNlqH=}($7vzwubl`4w~VIA@S z3$pED4z1SNSbv`8?`-9sj_Uh^fg1#IoF2HqR%8PYK?3E45Go5ZQD^7`P+$Wwh}M~=5V+`81F?Bn~*)5z7Yd? z){-xCGgD4O?~}zZ|Ds7;aJ&@_9V!TciE7fx+qH*J&2wY_;=JDeLYFTY0Q7)aZIrO>7CUKYjkX! z99{OUnmh|O(JVge9f1xRE-(-UMQ%nz*rm&hQ+c4FyZQ^V*3!gs&xN=shY&AeK7mv7pKeERM-M9dCHA@1MCF@|(UE*Ct>PZ5-%u05#nHL~0%CR6<7 z?SaDxSjZ=DUPAF%hVMrQB=Y+m8|=CQ%M}fz1e{Ei{pMKT=~b^zFNfaYEC_78zWTd! znHv=}z8PtKiAMs;^M+$~B{{odCOXw$xtD=3rHo^DmOn4>bff+ukD(Nd z4s3I``T-xQU!RkXM_Kye{=tquSwE$2B3G|^qZCp3-TlTQ^tERDQ6w6kkKHH&9jt|4 z16tV|y&o!5nA_-BFMmd5MFJ=zzr#cr)s$X(0QTd=l4n^W0Fscw+=| z9+HC98EZ$n-pGS7@3>Pof--F!53!qNXD%<1Qm?yjM*}EGh@Vh?Dv>=XwT{sGWTd$3 zbK75mY|+%t=3e{e6%7xg_sZmgKlCm}HD;~S{s=`%!P0MUdI_}F--WOwew5lrXAOng z+jHG=McP}pcBgpyeBM=xxZfMP4>XFz@A0|+`8XDU8<=)v;TaT4#eEr*uM9?ca z_K(u*TyTZqyN*5_T4t+X{}nwm4rCki7&taGM_gsQEIrL@xAyZ&1hN_wjp;6T9*+&UtwatLBO6x*i*m;BUz#6)W(;p4nw}Nfs+XU0ALUj9or3p z&u*!Gut-nG$x`v=MjF7f5)J^N`V&FFH(Y|C1tkJ$a zs(L93Llu5Jex6M(oOE|+6lWy38%jjW&|66L_&Igt>z>>tPu9Ax@Av{N7M7;J$JY#^`1=;22$Im zs9J9D_s{;G|Ga+O7!Dz86`yXGp7w4O5)pbENN>V-xFqsxXn+NPMNVQn*q1 zs@O3=1SwP8N-PFqemr&`gu&{mlw0`TK(g>&I5|^2%g+FXRFo~9p(usKXSo~|^FtAz ztW|;%4#Rj9-H607XJU@6)GeWursuhsry?K%`lerCVoRBLHXCtOFK`1d3>XCU8oi23 zCZaPWlNV`s<*VgPZat$B8<9jDCw=N9HFpzEG(F;Yaybk;bK?mX#qtdgutQ&(>~apr zC(_YnjvFoHGWRp&_vP_{J!0^T7<&aXT3*H_F%%!R0_tV%6nKb5pnX1(ezxrur<_8o~JBZQ;;}#82|u~y%#s9qG$Q8 zEk;ywiQcM-pdg8S&hKAEAR9Wf{Mn*rowdt`AQ>VnB{x3**l$+&#X?$ z>0*jIK?soMDst^-krI!s(WT`$@vV7zzGh|28fr9$0YBNWb>{s0|@I|V9(Jd*LD#G!3h`^u5dzB(7O*3E;&1?!C87}K#~@rfzN}gJ z^DucAmxemG&Qi$~QvwVuk_cl>U%l!)hXrIh)d!+MWFVg^_97WiM88yr1i6+BQ!thXtrRd_ z9ro|eDY0xMN6^cBH_M3)pBeU0bBNeSlnh^bA6>RIxe=R(XP6-rIP+mEN>fLdXEAPW zIUNI+F=YiRr?;=kRUL^kLM)hgufvp-%)`l{fB7mJ7M5wT0r$ z!tFFfI#b87cqY=Fe)yvt_)!i+&#pf)xJVgr9p4N+KJ?=}f@aI8xj(Wb8P9k|nx7uV zhLcYelZ_N#>6xmh?3JL`4w9NnfeC62L|#hn?QG?Jk`&^ZKc9`m?Sr2v!~Uz;AKG5V zq4zQ`cKDr8r)Q`apY*Gh@gT~7_R+;fZ*DUoSbIZlw>M^-@oxOdV+)CbxWQ|OW|%_V z+TM@;-n{<&&)mSXQFV3YFHxBvcHtKEIcZ&m{gahfJB7%l7WhQ>s{f1sYjvW+ zTp^RdQi@wa+!4Ix0H|tB=pic|W|n62^IP95$0M(piP^azRdDgee}2wSg2;K$Yfm64 zRP79L6LECpF;{IAjOTpI6rZshF+Eq0B5-{1GHwE0MWGuvpwVQQ^X< zOGl*oU*W67q*1x}_-EXWD}k9g*Kv@$0g>+b`lB&kT18f#I$24iTs+;Xll=smD!r@m zH@)k8s`Oqiy&Rs;V((8}`|QQ!yztco5FcN6KY@$1(GfdcbH%aUh~{GIuRd^KfGPy{l}`iKY0G9rI23od!?E0flN6Z0e)>QlxwhdpVzAigDaOF-&$bh@1VLt=j{%+X3X4f~%Z=;Gt}gfVLU zz0d2^862U0(7)uG4{@5qAvk`7L5sxh@UL#rb74~zga7l^;zIN%W{`pA5QaAVJGqs{ z=u<~o5>?w#+(~C&omBs0fK@-4vPBAq=C&$n8ivC#*p()L(fxAL7M3}#OeJqbK@h+T zIJp`Twgbx?(J0~T{$;BbsXaAN;pA_AG2JtLD=yV9)pLEYBWhh!yi~~P)HX-M9kFRB zOSjU@1|3;uvx`wj^Ym#(^_~a9p|em~Y-mb+ zEfQOa@Re9gY6TQ#g`T8z0RR9&CGMM3`^_P;K`8v#Nn7amb?}=_(^^ zAP5QL!m29QBC)m53qc5whPzCLbz>`3@-_sa000DTpmofvu_V_t5{3oPUXNF`v#ZSO z1P7wVPo9h)|D0c<6N_^JJf&u~K^%yb3;i=WQ;I+|1WbH$zpqTsZF3yhRvus*ykU-P z001x?9ytb3LJLvu>UshP#`v=8DB92+c{Gr|QD`|%c8-b1ZwT4V$V@Pf(ZQM3{;YHL zH{H}0@2_D|o*W&>`~r(XaA`HBOio07Jk)k$g%x~@nta*}v;i}BEPM8jI8@Flwv5}d z!Ot_Hm}a>WUB;Du?DJ9E1biS7k)3O^*_S@oqhmtzA*b76_>wVcndbF$sP`>BPcnpn zA+IyH&_wEHmf_>=XZ4X~K6}`xVW-mQVC)i+M_%1SAH(0<$$t?@Dqj zn%uU1&v1>4?$h>2UVb-+-l2MO!cgl`b`7*<^s8fc5V)&K6w1=XCGDB zO%`Av%wNV*nk_*!?769p=f9tVqWykcFG41}#ZF!-77z$vxXLh5Gf9(^vmN%6HPC}LvQ(KTwuBKKv5r`#ULPXNjS0Y4yfcCxv0V;F!4dZE)*8&R;$%z z#-rUT5m(d$U(e65abJo~m*G{fo9m*ZbP{P(1710GBk5|_Wb#DFtGIWN@go}GdJ6( zS1NSGq?Suz2q=wlEuFjwE(M;2P$<2b0u6vm4=4yT7hq8ZFq9JS42Y43BGJJCs)Yv+0P}<{>8sOY4ibs_;noX{9cSJMVx@V)oGG1nK*gUcG~09`|d zA&O7Xdfx&eIJi1<^vL*F1`+$<;^{23>e^~_uzGU&Y~0eED@A@;jZJ>Y;#?cJ^Vv^7 zNXG6HpxwrlY6`{DEzwui3>#wk>If~t0IRxx5;)&Mj&&F_+P3OAD ze}=>eAI+Y9`H6~o45Lk^zr0_(1@>RL{K3C2Uiv&2oU>|V97cSU?gA}MMQbgzm?mrj*I=+ea=h7Z{|_WZ zVK~(t{UJl4-xinJ9gwGajWplP&FVI}_BKlKW)tLZB3nYHHUw*N&4?S*7l z>$JhU%Rby1Y4vSqcLI$ALy})DEWJQN z&+mS!K%;Yr)NrZ)zL%vXkfKm!V)B4Bszb(r1l2pwst81VJ-l~Y-`_z=_4N5HFIGdt zEIK6qX>*-V8SV#v@XEi)$U9E0nEJis@a2<{4oA6ZvGhJDzHp%uo}dEBFJA=R7&d~uJ>4x6h--k-G z#=T-DHs9{~55cIV;$MX|U~4Jtl`~RSwh|PzO`gH-um1i1t$+ScvKg-OjT}}))VVup z4x?%8=S0gu{gsRZu8!_5!LL6^3?V+ZB$Od`FF!JFBD-K43*BqM)zixqjX1Zs*^M?G z!)3~jrE0^Y@?184!Vwby`0!8v5-cvFXIH=c_1hQp!U>PKV%2U%)P~F#{6{Pqe5%P3MIbHcW zgmgMbR~BfJ%}9;|gdxAc4sknigPdog8G?oYC=I*zkr_ep-nAVoEr(&Cb)Ls~X^K#` z?+;8UAJN$fSP*HRUv_)L3{oWLb7lZzK%Bpqc1?sLC zS;$HeRGOetpkpd^0%OwgC5)n`r*f87SA;x`mZRQ`XX^n7zywI384fRkAd2BESK?SU z2LOQQnpiXolqw;PbuHuCFdWsx;hC;NjZUPO`yClfN;cHI9JoQCg0$b%-Hz&=S}_bC zHB1c4OP3nOT zMkGKd6(ys-9}G+#000P45K|o}4PB3g;;~F~1ZIOM0qaM)dLGf_t1xsy7|K6LAOuV% zaDJAi5TvfFBU3#;=pP*qJk!@P|4F~wF*Ph2^p6h-qyoy5!;6Q?Q#0?uX4jH#!>42L z<+v>kc0ET`Ci~spi^LcWHDBPVlg~abFf6q|xom1_ZbhaIX!@Em>f?(Foh2gdgHmc6 zo^b<0x8=YDz+$}B>pd4zcVfkx2)s%)LhCvMI&89h3tn7oj73my!Ze(?4Mi7;zzhAt zNlTavI`X9|a{n)1@9}GEo?VCizMQ|4bGRqmobSu;RlN$V>grJJE+&yQDTB6P0iGDp zK=5CnnMJ^fnozPN+iFrIyQwC-SzXm#`Q>nP4(Fbn&-rpr9yB390^vQ~z@98%VPUNe ztP<1P-&Grk-o=Cq6^9E`0@2O6a5bd*j_>%Mj(XUky#E;v*?8bi`!C$gC7u?N4=oQ8 z{l3$K!wTib*F(fSc{-e&oDH>4B}a9iOuD*k3$T4__5=6$AU3ni73pYU&1#vmt9PfQ z!{(MCy@lIlBuZw;a(QhGay4eT3lr3=eBh=rrMRhpTew93ce4xjMou&2>-+!g2T;LFn7=>g`N2CKlef z;o9=UcW=G%aBd@+q~|HAAy`J&qmN^Kw48~=zI3TDzU+oNJ^Aw4V0p+Al9P)w@dT-v z4u6yM92bLNHH;sh!)RZO>X-rBw&c&3hB%8B#-!+);aH%!IulK}f$erUNYQm=cqO#l zz}I>KGedVBZ?lw?YW{lp_E4?ah{aTc=+R|jWx3LjPP?Kz*JWi7{Ym2E6 zLtshO(uA(!l1Vrg3R9|4ch$(!Ez}dgxp>xpIZZu`TbAJ9N!tUkvioSzQCz!86hhHC z5h6o#MNaENSZ)9MLT%WA@5m>oa0rjDdg#KZb9Ug*tH(fUD)py^ zGN8g7m$HqC?gs#wBP~0zj*MY}PjdyPkVgwR?1u*9!vJqf+n

fPzyDQvz5V%N?fLL)QLvFkGNhz5n%S6n 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