From 565c02a37e2d140a20867081eea9bb5de9999b1c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Oct 2008 11:06:42 +0100 Subject: [PATCH] [svg] Use finer-grained fallbacks for SVG 1.2 The use of fine-grained fallbacks requires the native support of the SOURCE operator applied to an image on the target surface. SVG 1.2 introduces the "comp-op:src" mode fulfilling this criteria - so we can enable fine-grained fallbacks for 1.2+. Update test/fine-grained-fallbacks to exercise this pathway in SVG 1.2 - as SVG natively supported all the current operations within that test. This reveals yet another librsvg bug in handling SVG 1.2. --- src/cairo-paginated-private.h | 9 +- src/cairo-paginated-surface.c | 47 ++++------- src/cairo-pdf-surface.c | 14 +++- src/cairo-ps-surface.c | 8 ++ src/cairo-svg-surface.c | 34 ++++++-- test/Makefile.am | 4 +- ...finer-grained-fallbacks-ps2-argb32-ref.png | Bin 1047 -> 0 bytes test/finer-grained-fallbacks-ps2-ref.png | Bin 0 -> 1356 bytes .../finer-grained-fallbacks-ps2-rgb24-ref.png | Bin 819 -> 1096 bytes ...finer-grained-fallbacks-ps3-argb32-ref.png | Bin 1047 -> 0 bytes test/finer-grained-fallbacks-ps3-ref.png | Bin 0 -> 1356 bytes .../finer-grained-fallbacks-ps3-rgb24-ref.png | Bin 819 -> 1096 bytes test/finer-grained-fallbacks-ref.png | Bin 796 -> 1111 bytes test/finer-grained-fallbacks-rgb24-ref.png | Bin 590 -> 1114 bytes test/finer-grained-fallbacks.c | 79 +++++++++++++++++- 15 files changed, 147 insertions(+), 48 deletions(-) delete mode 100644 test/finer-grained-fallbacks-ps2-argb32-ref.png create mode 100644 test/finer-grained-fallbacks-ps2-ref.png delete mode 100644 test/finer-grained-fallbacks-ps3-argb32-ref.png create mode 100644 test/finer-grained-fallbacks-ps3-ref.png diff --git a/src/cairo-paginated-private.h b/src/cairo-paginated-private.h index 0c042746d..5cb2e48b6 100644 --- a/src/cairo-paginated-private.h +++ b/src/cairo-paginated-private.h @@ -65,7 +65,7 @@ struct _cairo_paginated_surface_backend { * before the mode is changed to RENDER. */ cairo_warn cairo_int_status_t - (*set_bounding_box) (void *surface, + (*set_bounding_box) (void *surface, cairo_box_t *bbox); /* Optional. Indicates whether the page requires fallback images. @@ -73,8 +73,11 @@ struct _cairo_paginated_surface_backend { * mode is changed to RENDER. */ cairo_warn cairo_int_status_t - (*set_fallback_images_required)(void *surface, - cairo_bool_t fallbacks_required); + (*set_fallback_images_required) (void *surface, + cairo_bool_t fallbacks_required); + + cairo_bool_t + (*supports_fine_grained_fallbacks) (void *surface); }; /* A #cairo_paginated_surface_t provides a very convenient wrapper that diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index e4e84d502..131d289b1 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -329,36 +329,23 @@ _paint_page (cairo_paginated_surface_t *surface) /* Finer grained fallbacks are currently only supported for some * surface types */ - switch (surface->target->type) { - case CAIRO_SURFACE_TYPE_PDF: - case CAIRO_SURFACE_TYPE_PS: - case CAIRO_SURFACE_TYPE_WIN32_PRINTING: - has_supported = _cairo_analysis_surface_has_supported (analysis); - has_page_fallback = FALSE; - has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis); - break; - - case CAIRO_SURFACE_TYPE_IMAGE: - case CAIRO_SURFACE_TYPE_XLIB: - case CAIRO_SURFACE_TYPE_XCB: - case CAIRO_SURFACE_TYPE_GLITZ: - case CAIRO_SURFACE_TYPE_QUARTZ: - case CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: - case CAIRO_SURFACE_TYPE_WIN32: - case CAIRO_SURFACE_TYPE_BEOS: - case CAIRO_SURFACE_TYPE_DIRECTFB: - case CAIRO_SURFACE_TYPE_SVG: - case CAIRO_SURFACE_TYPE_OS2: - default: - if (_cairo_analysis_surface_has_unsupported (analysis)) { - has_supported = FALSE; - has_page_fallback = TRUE; - } else { - has_supported = TRUE; - has_page_fallback = FALSE; - } - has_finegrained_fallback = FALSE; - break; + if (surface->backend->supports_fine_grained_fallbacks != NULL && + surface->backend->supports_fine_grained_fallbacks (surface->target)) + { + has_supported = _cairo_analysis_surface_has_supported (analysis); + has_page_fallback = FALSE; + has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis); + } + else + { + if (_cairo_analysis_surface_has_unsupported (analysis)) { + has_supported = FALSE; + has_page_fallback = TRUE; + } else { + has_supported = TRUE; + has_page_fallback = FALSE; + } + has_finegrained_fallback = FALSE; } if (has_supported) { diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 16abab336..e073eb454 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1277,8 +1277,8 @@ _cairo_pdf_surface_start_page (void *abstract_surface) } static cairo_int_status_t -_cairo_pdf_surface_has_fallback_images (void *abstract_surface, - cairo_bool_t has_fallbacks) +_cairo_pdf_surface_has_fallback_images (void *abstract_surface, + cairo_bool_t has_fallbacks) { cairo_status_t status; cairo_pdf_surface_t *surface = abstract_surface; @@ -1291,6 +1291,12 @@ _cairo_pdf_surface_has_fallback_images (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } +static cairo_bool_t +_cairo_pdf_surface_supports_fine_grained_fallbacks (void *abstract_surface) +{ + return TRUE; +} + /* Emit alpha channel from the image into the given data, providing * an id that can be used to reference the resulting SMask object. * @@ -4981,9 +4987,11 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = { _cairo_pdf_surface_show_text_glyphs, }; -static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend = { +static const cairo_paginated_surface_backend_t +cairo_pdf_surface_paginated_backend = { _cairo_pdf_surface_start_page, _cairo_pdf_surface_set_paginated_mode, NULL, /* set_bounding_box */ _cairo_pdf_surface_has_fallback_images, + _cairo_pdf_surface_supports_fine_grained_fallbacks, }; diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index bef876c7a..b107a54d5 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -3284,6 +3284,12 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface, return _cairo_output_stream_get_status (surface->stream); } +static cairo_bool_t +_cairo_ps_surface_supports_fine_grained_fallbacks (void *abstract_surface) +{ + return TRUE; +} + static const cairo_surface_backend_t cairo_ps_surface_backend = { CAIRO_SURFACE_TYPE_PS, _cairo_ps_surface_create_similar, @@ -3322,4 +3328,6 @@ static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backen _cairo_ps_surface_start_page, _cairo_ps_surface_set_paginated_mode, _cairo_ps_surface_set_bounding_box, + NULL, /* _cairo_ps_surface_has_fallback_images, */ + _cairo_ps_surface_supports_fine_grained_fallbacks, }; diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index 8095aa48f..19af8737b 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -2022,11 +2022,8 @@ _cairo_svg_surface_paint (void *abstract_surface, * 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 optimiszation in meta surface. */ - if (surface->clip_level == 0 && - (op == CAIRO_OPERATOR_CLEAR || - op == CAIRO_OPERATOR_SOURCE)) - { + * and an optimization in meta surface. */ + if (surface->clip_level == 0 && op == CAIRO_OPERATOR_CLEAR) { status = _cairo_output_stream_destroy (surface->xml_node); if (status) { surface->xml_node = NULL; @@ -2054,7 +2051,8 @@ _cairo_svg_surface_paint (void *abstract_surface, } } - return _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, 0, NULL); + return _cairo_svg_surface_emit_paint (surface->xml_node, + surface, op, source, 0, NULL); } static cairo_int_status_t @@ -2551,15 +2549,33 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) } static void -_cairo_svg_surface_set_paginated_mode (void *abstract_surface, - cairo_paginated_mode_t paginated_mode) +_cairo_svg_surface_set_paginated_mode (void *abstract_surface, + cairo_paginated_mode_t paginated_mode) { cairo_svg_surface_t *surface = abstract_surface; surface->paginated_mode = paginated_mode; } +static cairo_bool_t +_cairo_svg_surface_supports_fine_grained_fallbacks (void *abstract_surface) +{ + cairo_svg_surface_t *surface = abstract_surface; + cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; + + if (surface->document->svg_version >= CAIRO_SVG_VERSION_1_2) { + status = _cairo_svg_surface_analyze_operator (surface, + CAIRO_OPERATOR_SOURCE); + } + + return status == CAIRO_STATUS_SUCCESS; +} + static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend = { NULL /*_cairo_svg_surface_start_page*/, - _cairo_svg_surface_set_paginated_mode + _cairo_svg_surface_set_paginated_mode, + NULL, /* _cairo_svg_surface_set_bounding_box */ + NULL, /* _cairo_svg_surface_set_fallback_images_required */ + _cairo_svg_surface_supports_fine_grained_fallbacks, + }; diff --git a/test/Makefile.am b/test/Makefile.am index a33ca4131..eb961accb 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -478,9 +478,9 @@ REFERENCE_IMAGES = \ filter-nearest-offset-svg12-ref.png \ finer-grained-fallbacks-ref.png \ finer-grained-fallbacks-rgb24-ref.png \ - finer-grained-fallbacks-ps2-argb32-ref.png \ - finer-grained-fallbacks-ps3-argb32-ref.png \ + finer-grained-fallbacks-ps2-ref.png \ finer-grained-fallbacks-ps2-rgb24-ref.png \ + finer-grained-fallbacks-ps3-ref.png \ finer-grained-fallbacks-ps3-rgb24-ref.png \ font-matrix-translation-ps2-argb32-ref.png \ font-matrix-translation-ps3-argb32-ref.png \ diff --git a/test/finer-grained-fallbacks-ps2-argb32-ref.png b/test/finer-grained-fallbacks-ps2-argb32-ref.png deleted file mode 100644 index 402f01b85e6f6eb4d8bbc7942f7817b4c7d768be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1047 zcmV+y1nB#TP)4M`&+z zbaP{JX>fEPI4(9Z8YEeD000AyNkl1w$@9*{sATG$wP${!5*tt>QSMHcruyS!)EQ8%x-3r zOxBjZW!Plrn>XLQoqXT7ON3Gi|KUJJ?Z9ns}zzUhx`KYP*EM#!l$T&iJgwm=FZp*X@3{MYa5Q3;x>r^ z01s;93o~b#tu-+e)f?S}6_5<*vo40UY!Xlx1RaOBDz$2yuc@f<@U9t%u~vn+bt}4V zWD_Z57XImJQ&A0t*oHSCg-im-!3mT)1ZI;);5ueVA!kt{#C-r6056>L;QOC1DTKIg zVJ0drasq&Eu}1(Vq7(w~)EVAg5d*LQV6ynxMd1q&`}7=GSO8)%kTlBar6?9yZsz!^ zs6JP_fO^6!#`T?k3*ec~`Vzn$0F#rz;$qce+*Xu{kp%D^J~`JFLrUP_0Bmpnr^N8C zc@qF0BcS;BRy->OY;9R|D;kuEaWBYv$@BT_%!WUa;#v&1V)R|&M*tr@-& z{2~<9(4*s5DD1$A50?OT06YQk6o4CIV=-Vb_-Wajf`eN9msA5vD>9Pg^fU?hx0xA| zWKd;SG$2=2$lhMEsmW=*z0NhIDsq(Z8K4$Ey-_|-PEC>V_)QVwap!tIUs;TNo*WtR z7j$%#%;&>7UvF_s_<|KXIU(P@Bj@Lx^T~n*N^ucn8uz{&dh zDvJS->+9szRYig8F0O{po*0RQnHT_>Op?31!D5(*+t+6ZkQXOv9%{g zIt`>!;l`Yv`uCZLJ3ekcmyXX`0Cn^D>MGgaZx%?~+WZ5kQe-OSKQ@&jl`;>Y8a``c zlue#aR~93k_7|g6+(g1@{r%3hYKtxppS5gK3UPc)^z=A^QilrJq!DP`pH(_KfNU1% z>@4r=>~#7%IvVDV4vpIx?h|UE0Bmmq`}7Qpegm@@Z0^7c R^D_Vd002ovPDHLkV1gP)*7yJb diff --git a/test/finer-grained-fallbacks-ps2-ref.png b/test/finer-grained-fallbacks-ps2-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..1744100c983e197a524a6a868bf61474704aaa85 GIT binary patch literal 1356 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 X;MPn5Kmm;a00004M`&+z zbaP{JX>fEPI4(9Z8YEeD000AyNkl1w$@9*{sATG$wP${!5*tt>QSMHcruyS!)EQ8%x-3r zOxBjZW!Plrn>XLQoqXT7ON3Gi|KUJJ?Z9ns}zzUhx`KYP*EM#!l$T&iJgwm=FZp*X@3{MYa5Q3;x>r^ z01s;93o~b#tu-+e)f?S}6_5<*vo40UY!Xlx1RaOBDz$2yuc@f<@U9t%u~vn+bt}4V zWD_Z57XImJQ&A0t*oHSCg-im-!3mT)1ZI;);5ueVA!kt{#C-r6056>L;QOC1DTKIg zVJ0drasq&Eu}1(Vq7(w~)EVAg5d*LQV6ynxMd1q&`}7=GSO8)%kTlBar6?9yZsz!^ zs6JP_fO^6!#`T?k3*ec~`Vzn$0F#rz;$qce+*Xu{kp%D^J~`JFLrUP_0Bmpnr^N8C zc@qF0BcS;BRy->OY;9R|D;kuEaWBYv$@BT_%!WUa;#v&1V)R|&M*tr@-& z{2~<9(4*s5DD1$A50?OT06YQk6o4CIV=-Vb_-Wajf`eN9msA5vD>9Pg^fU?hx0xA| zWKd;SG$2=2$lhMEsmW=*z0NhIDsq(Z8K4$Ey-_|-PEC>V_)QVwap!tIUs;TNo*WtR z7j$%#%;&>7UvF_s_<|KXIU(P@Bj@Lx^T~n*N^ucn8uz{&dh zDvJS->+9szRYig8F0O{po*0RQnHT_>Op?31!D5(*+t+6ZkQXOv9%{g zIt`>!;l`Yv`uCZLJ3ekcmyXX`0Cn^D>MGgaZx%?~+WZ5kQe-OSKQ@&jl`;>Y8a``c zlue#aR~93k_7|g6+(g1@{r%3hYKtxppS5gK3UPc)^z=A^QilrJq!DP`pH(_KfNU1% z>@4r=>~#7%IvVDV4vpIx?h|UE0Bmmq`}7Qpegm@@Z0^7c R^D_Vd002ovPDHLkV1gP)*7yJb diff --git a/test/finer-grained-fallbacks-ps3-ref.png b/test/finer-grained-fallbacks-ps3-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..1744100c983e197a524a6a868bf61474704aaa85 GIT binary patch literal 1356 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 FV1gh(4Zi>Y delta 769 zcmV+c1OEKi2%H9x7YZc^1^@s68D~^9ks%a+00(qQO+^RT0~i4aBo(YRtN;K4zDYzu zRA_&L#`F|WMuPAGbfKdF6y+-{ONqq~(4>Hd9#ABxNF+DOXQaS|U6aa1 z3d9ejSVcl{xD*~I8+&*5jdyk(BHz_$j=>bw+R!jtGBl?KHhGc%1aQVdT5#lxS_;Lnx zsKYUeLxUKHh6JYKrmpo}-=e1LhA;C)e8+fu;SDAyM$zRzO&Udx33(#)R%p-NU;f}@ z#Wgk&qZ}bdh|NfuL_o%bw1oDB#zM-p@c;?-MWr{Sh1f#8b8V~A8&?Z5Cgj_Hj0o2) zMFI)FE<4lEM(9w&BVQ`X$jdxdP?2LO+Jqrcz!^f-Pv zcLmObbc?n~4=K6cCK7a)9df-8$*U7SjQj5QAw}vVwdaHw3!W}J+(sbyoJl;deKPVS zf{tJ)xNvRg`u>j^sGueIBDkD?5#iGHm-+(7aqJQFDAcdS7I&7fZ1B2ZN3iGa>j4XO zOWrOCdzmh_xOsfmxxo+&3}Q&IEy`=4HHbUMS1n`zVyRIK3C@JS25J=7Tm#MHtDbf7 zVj*Hka4wIlHS(Ejpm}_&8fXTq8fX)6$5tQG diff --git a/test/finer-grained-fallbacks-rgb24-ref.png b/test/finer-grained-fallbacks-rgb24-ref.png index 73284820214ed4c87ae3eee8536668ac9b08ef10..3b8e9c38d8892a1c84d4a99dd7f4a0fac6542262 100644 GIT binary patch delta 1090 zcmV-I1ikyt1lkCY7YaxS1^@s6tqn-9ks%a+1P@6>K~#90?VGV~6H63^zs2+vP+cKG zsNqUnL>>TyLWx9eS&F0k0yGr7!o62WP(i>Hq=Yx1abb%l5>zQtph#2{6jr2&g#Q*E z#~XWgJmdB3dYwJiFWa-@v&Wx3-jm%w2_WhK;6m92EK|gVkpL~A4;&ix%~%q3&vS== zqNst`L7BJrW==@X1kpnD5r;;7GnULz<7B>QFt!{ZMz?l}aBcab!RUFw_=ea(Tr2^u zEnhSk1CQcIw|&I=0^s%n>a*or3K&BCM6Bh^H^^6Cyraq2!1)=or&lV|c{Ky3IP86eIJ%(u7`Mz;cV5FLVke3q> zPBlORy(quvVqn}5I++3E1hiIu;S1Ne=`u~oeH@*bnRCI+TeTR!Z__becFle@et0EH zIpxL}#v9-r{K%U54tP6$nmMoHFg+Rxk>r1f4BWQZ? zU&e3Trhhz>C!iLn4>~mJo3W&S{5S3gqXGI4^lJjbFEj4bXEZ=N4xsNn^TdQZna>Ji zq^qD!&{K1NHDE_u4iF=?1M)2zt}UMvMjrJ%Uy2STfS&82A(hk+6S#K0B$em zhqV+i1p0})tM$n@$XQ>s(|#2^1sd-hXhlzf##tr_s1vwUjvV>g93F9CK+zw&AhAm%I7-?;Lz}OCeJ22{+v3Z-WbiTr1tT8-dWPzAb)HWsyklMy%QEg*Nsj4=nM5ray7dkZR3$@xgFAG-9 z#?%nn5q7gmZ@$ZdXH+E{(^eJ;aq8R&xpGw{P4yY=$pK4jdCaL|Oxc)jxn}#!sc=l$ zn4Ixy_LQo}aLt$|q?h%3(c#p+6LNvKVoE(pP`k;{y5z7igTxKg`&7;4`pWWFZ+*+n7@EKWTsiAy|fDYybcN07*qo IM6N<$f;!y<#{d8T delta 562 zcmV-20?qx}2+jnM7YZc^0ssI2mIcFOks%a+00(qQO+^RT0~i4aBo(YRtN;K3@JU2L zR9J=Wm$6R5P!xv0T6YH>NkkvOO&>r)cnU&-gcope@D-Gh=p-av^f6o*aF)rz!T16W z4T%vv4z>uTx9z2umIz;NLIU^ap8s&u!w(z&DHhb=35GC)C#ZpycU9Wh@BlKm?!iuf zAWzeUX{`YoVK#o(S)4Xa7Xn%X^wmz@paR=!ZJI6wv<7h1)%>nkI8kULy3mh1x1YTe zfe$#))Vg}-ZW(YgNU&!IE)5(Nfe9y_WZNoXZ$@+>wn0fcsD}kkf(!N;rae>dug9Gm z&>AySg&usXD|=T6ov_VLf{_x?&U~c3ocY%6bD+cscq-qsoybUe* zn)2`kt;mtE(lNdOb+~{!6ym;aEn>WEV!W(zj5m>fS0l!oaI%TPx#07*qoM6N<$f*ket A^8f$< diff --git a/test/finer-grained-fallbacks.c b/test/finer-grained-fallbacks.c index f7cd5f366..65bceb46c 100644 --- a/test/finer-grained-fallbacks.c +++ b/test/finer-grained-fallbacks.c @@ -31,7 +31,7 @@ static cairo_test_draw_function_t draw; #define CIRCLE_SIZE 10 #define PAD 2 #define WIDTH (CIRCLE_SIZE*6.5 + PAD) -#define HEIGHT (CIRCLE_SIZE*3.5 + PAD) +#define HEIGHT (CIRCLE_SIZE*7.0 + PAD) static const cairo_test_t test = { "finer-grained-fallbacks", @@ -50,6 +50,19 @@ draw_circle (cairo_t *cr, double x, double y) cairo_restore (cr); } +static void +draw_image_circle (cairo_t *cr, cairo_surface_t *source, double x, double y) +{ + cairo_save (cr); + + cairo_set_source_surface (cr, source, x, y); + cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REFLECT); + cairo_rectangle (cr, x, y, CIRCLE_SIZE, CIRCLE_SIZE); + cairo_fill (cr); + + cairo_restore (cr); +} + static void draw_circles (cairo_t *cr) { @@ -61,6 +74,17 @@ draw_circles (cairo_t *cr) draw_circle (cr, CIRCLE_SIZE*6, 0); } +static void +draw_image_circles (cairo_t *cr, cairo_surface_t *source) +{ + draw_image_circle (cr, source, 0, -CIRCLE_SIZE*0.1); + draw_image_circle (cr, source, CIRCLE_SIZE*0.4, CIRCLE_SIZE*0.25); + + draw_image_circle (cr, source, CIRCLE_SIZE*2, 0); + draw_image_circle (cr, source, CIRCLE_SIZE*4, 0); + draw_image_circle (cr, source, CIRCLE_SIZE*6, 0); +} + /* For each of circle and fallback_circle we draw: * - two overlapping * - one isolated @@ -74,12 +98,40 @@ draw_circles (cairo_t *cr) * * Fallback circles are drawn in red. CAIRO_OPERATOR_ADD is used to * ensure they will be emitted as a fallback image in PS/PDF. + * + * In order to trigger a fallback for SVG, we need to use a surface with + * REFLECT. */ +static cairo_surface_t * +surface_create (cairo_t *target) +{ + cairo_surface_t *surface; + cairo_t *cr; + + surface = cairo_surface_create_similar (cairo_get_target (target), + CAIRO_CONTENT_COLOR_ALPHA, + CIRCLE_SIZE, CIRCLE_SIZE); + cr = cairo_create (surface); + cairo_surface_destroy (surface); + + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); + draw_circle (cr, CIRCLE_SIZE/2, CIRCLE_SIZE/2); + + surface = cairo_surface_reference (cairo_get_target (cr)); + cairo_destroy (cr); + + return surface; +} + static cairo_test_status_t draw (cairo_t *cr, int width, int height) { + cairo_surface_t *surface; + cairo_translate (cr, PAD, PAD); + cairo_save (cr); + /* Draw overlapping circle and fallback circle */ cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); @@ -101,6 +153,31 @@ draw (cairo_t *cr, int width, int height) cairo_translate (cr, 0, CIRCLE_SIZE*2); draw_circles (cr); + cairo_restore (cr); + cairo_translate (cr, 0, CIRCLE_SIZE * 3.5); + + /* Draw using fallback surface */ + surface = surface_create (cr); + + cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + draw_circle (cr, CIRCLE_SIZE*0.5, CIRCLE_SIZE*1.5); + + cairo_set_operator (cr, CAIRO_OPERATOR_ADD); + draw_image_circle (cr, surface, CIRCLE_SIZE/4, CIRCLE_SIZE + CIRCLE_SIZE/4); + + /* Draw circles */ + cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_translate (cr, CIRCLE_SIZE*2.5, CIRCLE_SIZE*0.6); + draw_circles (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_ADD); + cairo_translate (cr, -CIRCLE_SIZE/2, CIRCLE_SIZE*1.5); + draw_image_circles (cr, surface); + + cairo_surface_destroy (surface); + return CAIRO_TEST_SUCCESS; }