all: Trailing spaces removed 05/289805/1
authorMira Grudzinska <veleveta@gmail.com>
Fri, 6 Jan 2023 23:47:59 +0000 (00:47 +0100)
committerMichal Szczecinski <mihashco89@gmail.com>
Tue, 14 Mar 2023 09:39:55 +0000 (10:39 +0100)
Change-Id: I09f10f1b342b352c39cce734a2fce5d93091a9d0

17 files changed:
CONTRIBUTING.md
inc/thorvg.h
src/bin/svg2tvg/svg2tvg.cpp
src/examples/all.sh [new file with mode: 0755]
src/lib/gl_engine/tvgGlGeometry.h
src/lib/sw_engine/tvgSwImage.cpp
src/lib/sw_engine/tvgSwRasterNeon.h
src/lib/sw_engine/tvgSwRasterTexmap.h
src/lib/tvgBezier.cpp
src/lib/tvgBinaryDesc.h
src/lib/tvgLzw.cpp
src/lib/tvgMath.h
src/lib/tvgPictureImpl.h
src/loaders/jpg/tvgJpgd.cpp
src/loaders/png/tvgLodePng.cpp
test/capi/capiFill.cpp
test/testAccessor.cpp [new file with mode: 0644]

index 8205ff5..b06e3cb 100644 (file)
@@ -42,7 +42,7 @@ If your change don't belonged to any sub modules, you can replace with proper na
 The name must be written in all lower alphabet characters.
   - ex) build / doc / infra / common / sw_engine / gl_engine / svg_loader / examples / wasm / svg2png  ...
 
-- [Feature] is what major function/feature you changed. Normally this indicates a representive file name. 
+- [Feature] is what major function/feature you changed. Normally this indicates a representive file name.
 You can keep the file name, but don't please contain any prefix(tvg) nor suffix(Impl) here.
   - ex) Canvas / TaskScehduler / SvgLoader / SvgBuilder / SwRle / GlRenderer / ...
 
@@ -51,51 +51,51 @@ You can keep the file name, but don't please contain any prefix(tvg) nor suffix(
   - ex) "Fixed compile warnings"
   - ex) "Code refactoring"
   - ex) "Fixed a rendering bug that overlapped shapes inproper way."
-  
+
 - [Description] There is no any strict formats, but it must describe what you did in this patch as far as possible you can describe in detail.
 
   If you fixed any bugs, it must contain below:
-  - what type of bug  
+  - what type of bug
   - conditions to reproduce it
   - root cause
-  - solution 
-  
+  - solution
+
   Or if you add a new feature or function, it must contain below:
   - what sort of features
   - api full specification (if any api additions)
   - any necessity
-  - condition / restriction  
+  - condition / restriction
   - reference or sample
-  
+
   Lastly, please append any issue ticket numbers in this section if any.
-  
-  
+
+
 - Here is a overall commit message what we expect to review:
-  
+
   - common composite: newly added path clipping feature
 
     We introduced new method Paint::composite() to support composite behaviors. </br>
     This allows paints to composite with other paints instances. </br>
     Composite behaviors depend on its composite method type. </br>
-    Here we firstly introduced "ClipPath" method to support clipping by path unit of paint.</br>    
-    
+    Here we firstly introduced "ClipPath" method to support clipping by path unit of paint.</br>
+
     tagetPaint->composite(srcPaint, CompositeMethod::ClipPath);</br>
-    
+
     Beaware if the source paint doesn't contain any path info, clipping won't be applied as you expected.
-    
+
     @API Additions:</br>
     enum CompositeMethod {None = 0, ClipPath}; </br>
     Result Paint::composite(std::unique_ptr<Paint> target, CompositeMethod method) const noexcept;</br>
 
     @Examples: added ClipPath</br>
-    
+
     @References: any links to the references such as screenshot images.
 
     @Issues: 49
 <br />
 
 ## Pull Request
-  
+
 Once you submitted a pull request(PR), please make it sure below check list.
 -  Reviewers: Check Reviewers List
 -  Assignees: You
index 1429839..594fe9b 100644 (file)
@@ -186,10 +186,10 @@ struct Matrix
 
 /**
  * @brief A data structure representing a texture mesh vertex
- * 
+ *
  * @param pt The vertex coordinate
  * @param uv The normalized texture coordinate in the range (0.0..1.0, 0.0..1.0)
- * 
+ *
  * @BETA_API
  */
 struct Vertex
@@ -201,9 +201,9 @@ struct Vertex
 
 /**
  * @brief A data structure representing a triange in a texture mesh
- * 
+ *
  * @param vertex The three vertices that make up the polygon
- * 
+ *
  * @BETA_API
  */
 struct Polygon
@@ -1197,38 +1197,38 @@ public:
 
     /**
      * @brief Sets or removes the triangle mesh to deform the image.
-     * 
+     *
      * If a mesh is provided, the transform property of the Picture will apply to the triangle mesh, and the
      * image data will be used as the texture.
-     * 
+     *
      * If @p triangles is @c nullptr, or @p triangleCnt is 0, the mesh will be removed.
-     * 
+     *
      * Only raster image types are supported at this time (png, jpg). Vector types like svg and tvg do not support.
      * mesh deformation. However, if required you should be able to render a vector image to a raster image and then apply a mesh.
-     * 
+     *
      * @param[in] triangles An array of Polygons(triangles) that make up the mesh, or null to remove the mesh.
      * @param[in] triangleCnt The number of Polygons(triangles) provided, or 0 to remove the mesh.
-     * 
+     *
      * @retval Result::Success When succeed.
      * @retval Result::Unknown If fails
-     * 
+     *
      * @note The Polygons are copied internally, so modifying them after calling Mesh::mesh has no affect.
      * @warning Please do not use it, this API is not official one. It could be modified in the next version.
-     * 
+     *
      * @BETA_API
      */
     Result mesh(const Polygon* triangles, const uint32_t triangleCnt) noexcept;
 
     /**
      * @brief Return the number of triangles in the mesh, and optionally get a pointer to the array of triangles in the mesh.
-     * 
+     *
      * @param[out] triangles Optional. A pointer to the array of Polygons used by this mesh.
-     * 
+     *
      * @return uint32_t The number of polygons in the array.
-     * 
+     *
      * @note Modifying the triangles returned by this method will modify them directly within the mesh.
      * @warning Please do not use it, this API is not official one. It could be modified in the next version.
-     * 
+     *
      * @BETA_API
      */
     uint32_t mesh(const Polygon** triangles) const noexcept;
index c2788f3..fad70a4 100644 (file)
@@ -38,7 +38,7 @@ void helpMsg()
 bool convert(string& in, string& out)
 {
     if (Initializer::init(CanvasEngine::Sw, 0) != Result::Success) return false;
-        
+
     auto picture = Picture::gen();
     if (picture->load(in) != Result::Success) return false;
 
diff --git a/src/examples/all.sh b/src/examples/all.sh
new file mode 100755 (executable)
index 0000000..992752b
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+RED='\033[31m'
+GREEN='\033[32m'
+NC='\033[0m'
+
+INTERVAL=${1:-1}
+EXAMPLES=`find . -executable -type f | sort | uniq`
+for EXAMPLE in $EXAMPLES
+do
+       if [[ $EXAMPLE == *.sh ]]; then
+               continue
+       fi
+
+       echo -e "Execute: "${GREEN}$EXAMPLE${NC}" for "$INTERVAL" second(s)"
+       $EXAMPLE &
+       EXAMPLE_PID=$!
+       sleep $INTERVAL
+       kill -s SIGTERM $EXAMPLE_PID
+       if [ $? -ne 0 ]; then
+               echo -e "Something wrong with: "${RED}$EXAMPLE${NC}
+       fi
+done
index 7c9dbe4..79ffeb9 100644 (file)
@@ -96,7 +96,7 @@ public:
 
     bool operator== (const GlPoint& rhs)
     {
-        if (&rhs == this) return true; 
+        if (&rhs == this) return true;
         if (rhs.x == this->x && rhs.y == this->y) return true;
         return false;
     }
index a1b8960..2b139a7 100644 (file)
@@ -53,9 +53,9 @@ static bool _genOutline(SwImage* image, Polygon* triangles, uint32_t triangleCou
 
     Point to[4];
     if (triangleCount > 0) {
-        // TODO: Optimise me. We appear to calculate this exact min/max bounding area in multiple 
+        // TODO: Optimise me. We appear to calculate this exact min/max bounding area in multiple
         // places. We should be able to re-use one we have already done? Also see:
-        //   tvgPictureImpl.h --> bounds 
+        //   tvgPictureImpl.h --> bounds
         //   tvgSwRasterTexmap.h --> _rasterTexmapPolygonMesh
         //
         // TODO: Should we calculate the exact path(s) of the triangle mesh instead?
index a4b3cda..4ce60c5 100644 (file)
@@ -116,7 +116,7 @@ static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region,
 
         for (uint32_t x = 0; x <  (w - align) / 2; ++x)
             vDst[x] = vadd_u8((uint8x8_t)vColor, ALPHA_BLEND(vDst[x], vIalpha));
-        
+
         auto leftovers = (w - align) % 2;
         if (leftovers > 0) dst[w - 1] = color + ALPHA_BLEND(dst[w - 1], ialpha);
     }
index 32a772e..9aebaaf 100644 (file)
@@ -517,7 +517,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans)
             dst = surface->buffer + (offset + line->x[1] - 1);
             if (line->x[1] < (int32_t)(surface->w - 1)) pixel = *(dst + 1);
             else pixel = *dst;
-            
+
             pos = width;
             while ((int32_t)(width - line->length[1]) < pos) {
                 *dst = INTERPOLATE(255 - (line->coverage[1] * (line->length[1] - (width - pos))), *dst, pixel);
@@ -543,7 +543,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans)
     0 -- 1
     |  / |
     | /  |
-    3 -- 2 
+    3 -- 2
 */
 static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
 {
index 95e2055..f26f74f 100644 (file)
@@ -114,7 +114,7 @@ float bezAt(const Bezier& bz, float at)
     auto t = 0.5f;
 
     //just in case to prevent an infinite loop
-    if (at <= 0) return 0.0f; 
+    if (at <= 0) return 0.0f;
 
     if (at >= len) return 1.0f;
 
index bab6b79..a6a70a4 100644 (file)
@@ -42,7 +42,7 @@ using TvgBinFlag = TvgBinByte;
 #define TVG_HEADER_VERSION_LENGTH 6
 #define TVG_HEADER_RESERVED_LENGTH 1      //Storing flags for extensions
 #define TVG_HEADER_COMPRESS_SIZE 12       //TVG_HEADER_UNCOMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE + TVG_HEADER_COMPRESSED_SIZE_BITS
-//Compress Size 
+//Compress Size
 #define TVG_HEADER_UNCOMPRESSED_SIZE 4     //SIZE (TvgBinCounter)
 #define TVG_HEADER_COMPRESSED_SIZE 4       //SIZE (TvgBinCounter)
 #define TVG_HEADER_COMPRESSED_SIZE_BITS 4  //SIZE (TvgBinCounter)
index 1aaf378..964af08 100644 (file)
@@ -258,8 +258,8 @@ struct Dictionary
 
     Dictionary()
     {
-        /* First 256 dictionary entries are reserved to the byte/ASCII range. 
-           Additional entries follow for the character sequences found in the input. 
+        /* First 256 dictionary entries are reserved to the byte/ASCII range.
+           Additional entries follow for the character sequences found in the input.
            Up to 4096 - 256 (MaxDictEntries - FirstCode). */
         size = FirstCode;
 
index 74f34fb..2cce318 100644 (file)
@@ -118,7 +118,7 @@ static inline void mathScale(Matrix* m, float scale)
 static inline void mathTranslate(Matrix* m, float x, float y)
 {
     m->e13 = x;
-    m->e23 = y;   
+    m->e23 = y;
 }
 
 
index 8bbb745..172c6f6 100644 (file)
@@ -173,7 +173,6 @@ struct Picture::Impl
     bool bounds(float* x, float* y, float* w, float* h)
     {
         if (triangleCnt > 0) {
-            
             Point min = { triangles[0].vertex[0].pt.x, triangles[0].vertex[0].pt.y };
             Point max = { triangles[0].vertex[0].pt.x, triangles[0].vertex[0].pt.y };
 
index 56b40ac..f4b1d13 100644 (file)
@@ -80,7 +80,7 @@ enum jpgd_status
 enum
 {
     JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4,
-    JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384 
+    JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384
 };
 
 // Input stream interface.
@@ -151,7 +151,7 @@ public:
     // If JPGD_SUCCESS is returned you may then call decode() on each scanline.
     int begin_decoding();
     // Returns the next scan line.
-    // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1). 
+    // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
     // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4).
     // Returns JPGD_SUCCESS if a scan line has been returned.
     // Returns JPGD_DONE if all scan lines have been returned.
@@ -1246,7 +1246,7 @@ void jpeg_decoder::read_sof_marker()
     uint32_t num_left = get_bits(16);
 
     if (get_bits(8) != 8) stop_decoding(JPGD_BAD_PRECISION);   /* precision: sorry, only 8-bit precision is supported right now */
-       
+
     m_image_y_size = get_bits(16);
     if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) stop_decoding(JPGD_BAD_HEIGHT);
 
@@ -1326,7 +1326,7 @@ void jpeg_decoder::read_sos_marker()
     }
     num_left -= 3;
 
-    while (num_left) {    /* read past whatever is num_left */    
+    while (num_left) {    /* read past whatever is num_left */
         get_bits(8);
         num_left--;
     }
@@ -1411,7 +1411,7 @@ int jpeg_decoder::process_markers()
                 stop_decoding(JPGD_UNEXPECTED_MARKER);
                 break;
             }
-            default: {   /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */            
+            default: {   /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */
                 skip_variable_marker();
                 break;
             }
@@ -1441,7 +1441,7 @@ void jpeg_decoder::locate_soi_marker()
 
         if (lastchar == 0xFF) {
           if (thischar == M_SOI) break;
-          else if (thischar == M_EOI) stop_decoding(JPGD_NOT_JPEG); // get_bits will keep returning M_EOI if we read past the end    
+          else if (thischar == M_EOI) stop_decoding(JPGD_NOT_JPEG); // get_bits will keep returning M_EOI if we read past the end
         }
     }
 
@@ -1460,7 +1460,7 @@ void jpeg_decoder::locate_sof_marker()
     switch (c) {
         case M_SOF2: m_progressive_flag = true;
         case M_SOF0:  /* baseline DCT */
-        case M_SOF1: { /* extended sequential DCT */        
+        case M_SOF1: { /* extended sequential DCT */
           read_sof_marker();
           break;
         }
@@ -1671,7 +1671,7 @@ void jpeg_decoder::transform_mcu_expand(int mcu_row)
         JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1);
         JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64);
 
-        int max_zag = m_mcu_block_max_zag[mcu_block++] - 1; 
+        int max_zag = m_mcu_block_max_zag[mcu_block++] - 1;
         if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis
 
         switch (s_max_rc[max_zag]) {
@@ -1789,7 +1789,7 @@ void jpeg_decoder::load_next_row()
             p[0] = pDC[0];
             memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t));
 
-            for (i = 63; i > 0; i--) { 
+            for (i = 63; i > 0; i--) {
                 if (p[g_ZAG[i]]) break;
             }
 
@@ -1809,7 +1809,7 @@ void jpeg_decoder::load_next_row()
                 if (++block_y_mcu_ofs == m_comp_v_samp[component_id]) {
                     block_y_mcu_ofs = 0;
                     block_x_mcu[component_id] += m_comp_h_samp[component_id];
-                }            
+                }
             }
         }
         if (m_freq_domain_chroma_upsample) transform_mcu_expand(mcu_row);
@@ -1865,7 +1865,7 @@ void jpeg_decoder::process_restart()
 
 
 static inline int dequantize_ac(int c, int q)
-{ 
+{
     c *= q;
     return c;
 }
@@ -1910,7 +1910,7 @@ void jpeg_decoder::decode_next_row()
                             while (n--) p[g_ZAG[kt++]] = 0;
                         }
                         k += r;
-                    }                
+                    }
                     s = JPGD_HUFF_EXTEND(extra_bits, s);
                     JPGD_ASSERT(k < 64);
                     p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k];
@@ -2204,7 +2204,7 @@ int jpeg_decoder::decode(const void** pScan_line, uint32_t* pScan_line_len)
                 }
               else *pScan_line = m_pScan_line_1;
               break;
-            } 
+            }
             case JPGD_YH2V1: {
                 H2V1Convert();
                 *pScan_line = m_pScan_line_0;
@@ -2609,11 +2609,11 @@ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, in
     int p1 = 1 << pD->m_successive_low;
     int m1 = static_cast<unsigned int>(-1) << pD->m_successive_low;
     jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
-    
+
     JPGD_ASSERT(pD->m_spectral_end <= 63);
-    
+
     k = pD->m_spectral_start;
-    
+
     if (pD->m_eob_run == 0) {
         for ( ; k <= pD->m_spectral_end; k++) {
             s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_ac_tab[component_id]]);
index eaed025..509ccd1 100644 (file)
@@ -1167,7 +1167,7 @@ static unsigned lodepng_crc32_table[256] = {
 };
 
 
-/* Calculate CRC32 of buffer 
+/* Calculate CRC32 of buffer
    Return the CRC of the bytes buf[0..len-1]. */
 static unsigned lodepng_crc32(const unsigned char* data, size_t length)
 {
@@ -1571,7 +1571,7 @@ static unsigned color_tree_add(ColorTree* tree, unsigned char r, unsigned char g
 
 /* put a pixel, given its RGBA color, into image of any color type */
 static unsigned rgba8ToPixel(unsigned char* out, size_t i, const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
-{  
+{
     if (mode->colortype == LCT_GREY) {
         unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/
         if (mode->bitdepth == 8) out[i] = gray;
index a023c96..2439857 100644 (file)
@@ -25,7 +25,7 @@
 
 
 TEST_CASE("Set/Get fill color", "[capiShapeFill]")
-{   
+{
     Tvg_Paint *paint = tvg_shape_new();
     REQUIRE(paint);
 
@@ -43,7 +43,7 @@ TEST_CASE("Set/Get fill color", "[capiShapeFill]")
 }
 
 TEST_CASE("Set/Get fill color on invalid shape", "[capiShapeFill]")
-{   
+{
     REQUIRE(tvg_shape_set_fill_color(NULL, 120, 154, 180, 100) == TVG_RESULT_INVALID_ARGUMENT);
 
     uint8_t r, g, b, a;
@@ -51,7 +51,7 @@ TEST_CASE("Set/Get fill color on invalid shape", "[capiShapeFill]")
 }
 
 TEST_CASE("Set/Get shape fill rule", "[capiShapeFill]")
-{   
+{
     Tvg_Paint *paint = tvg_shape_new();
     REQUIRE(paint);
 
@@ -65,7 +65,7 @@ TEST_CASE("Set/Get shape fill rule", "[capiShapeFill]")
 }
 
 TEST_CASE("Set/Get shape fill rule on invalid object", "[capiShapeFill]")
-{   
+{
     REQUIRE(tvg_shape_set_fill_rule(NULL, TVG_FILL_RULE_EVEN_ODD) == TVG_RESULT_INVALID_ARGUMENT);
 
     Tvg_Fill_Rule rule;
diff --git a/test/testAccessor.cpp b/test/testAccessor.cpp
new file mode 100644 (file)
index 0000000..f5bf052
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2022 ThorVG Project. All rights reserved.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <thorvg.h>
+#include "catch.hpp"
+
+using namespace tvg;
+#include <stdio.h>
+
+TEST_CASE("Accessor Creation", "[tvgAccessor]")
+{
+    auto accessor = tvg::Accessor::gen();
+    REQUIRE(accessor);
+
+    auto accessor2 = tvg::Accessor::gen();
+    REQUIRE(accessor2);
+}
+
+
+TEST_CASE("Set", "[tvgAccessor]")
+{
+    REQUIRE(Initializer::init(CanvasEngine::Sw, 0) == Result::Success);
+
+    auto canvas = SwCanvas::gen();
+    REQUIRE(canvas);
+
+    uint32_t buffer[100*100];
+    REQUIRE(canvas->target(buffer, 100, 100, 100, SwCanvas::Colorspace::ABGR8888) == Result::Success);
+
+    auto picture = Picture::gen();
+    REQUIRE(picture);
+    REQUIRE(picture->load(TEST_DIR"/logo.svg") == Result::Success);
+
+    auto accessor = tvg::Accessor::gen();
+    REQUIRE(accessor);
+
+    //Case 1
+    picture = accessor->set(move(picture), nullptr);
+    REQUIRE(picture);
+
+    //Case 2
+    auto f = [](const tvg::Paint* paint) -> bool
+    {
+        if (paint->identifier() == tvg::Shape::identifier()) {
+            auto shape = (tvg::Shape*) paint;
+            uint8_t r, g, b, a;
+            shape->fillColor(&r, &g, &b, &a);
+            if (r == 37 && g == 47 && b == 53)
+                shape->fill(0, 0, 255, a);
+        }
+        return true;
+    };
+
+    picture = accessor->set(move(picture), f);
+    REQUIRE(picture);
+
+    REQUIRE(Initializer::term(CanvasEngine::Sw) == Result::Success);
+}