• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can
5  * be found in the LICENSE file.
6  *
7  */
8 
9 //
10 //
11 //
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 
16 #include "color/color.h"
17 #include "ts/transform_stack.h"
18 
19 #include "groups.h"
20 
21 /*
22 Group {
23     children: [
24         Layer {
25             rasters: [
26                 SkcRaster {
27                     private: 2147745810
28                 }
29             ],
30             cmds: [
31                 CoverNonzero,
32                 CoverWipMoveToMask
33             ]
34         },
35         Layer {
36             rasters: [
37                 SkcRaster {
38                     private: 2147745805
39                 }
40             ],
41             cmds: [
42                 CoverNonzero,
43                 CoverMask,
44                 FillColor(
45                     [
46                         1.0,
47                         1.0,
48                         1.0,
49                         1.0
50                     ]
51                 ),
52                 BlendOver
53             ]
54         }
55     ],
56     enter_cmds: [
57         CoverMaskZero
58     ],
59     leave_cmds: []
60 }
61 */
62 
63 static bool is_mask_invertible = false;
64 
65 void
groups_toggle()66 groups_toggle()
67 {
68   is_mask_invertible = !is_mask_invertible;
69 }
70 
71 //
72 //
73 //
74 
75 skc_path_t *
groups_paths_decode(skc_path_builder_t pb)76 groups_paths_decode(skc_path_builder_t pb)
77 {
78   skc_path_t * paths = malloc(sizeof(*paths) * 6);
79 
80   for (uint32_t ii=0; ii<3; ii++)
81     {
82       float const xy = (float)ii * 2.0f + 2.0f;
83 
84       skc_path_begin(pb);
85       skc_path_ellipse(pb,xy,xy,0.5f,1.5f);
86       skc_path_end(pb,paths+ii*2);
87 
88       skc_path_begin(pb);
89       skc_path_ellipse(pb,xy,xy,1.0f,1.0f);
90       skc_path_end(pb,paths+ii*2+1);
91     }
92 
93   return paths;
94 }
95 
96 void
groups_paths_release(skc_context_t context,skc_path_t * const paths)97 groups_paths_release(skc_context_t      context,
98                      skc_path_t * const paths)
99 {
100   skc_path_release(context,paths,6);
101 
102   free(paths);
103 }
104 
105 //
106 //
107 //
108 
109 skc_raster_t *
groups_rasters_decode(struct ts_transform_stack * const ts,skc_path_t const * const paths,skc_raster_builder_t rb)110 groups_rasters_decode(struct ts_transform_stack * const ts,
111                       skc_path_t const          * const paths,
112                       skc_raster_builder_t              rb)
113 {
114   static float const raster_clip[] = { 0.0f, 0.0f, 0.0f, 0.0f };
115 
116   skc_raster_t * rasters = malloc(sizeof(*rasters) * 6);
117 
118   uint32_t const ts_restore = ts_transform_stack_save(ts);
119 
120   ts_transform_stack_push_translate(ts,800,800);
121   ts_transform_stack_concat(ts);
122 
123   for (uint32_t ii=0; ii<6; ii++)
124     {
125       skc_raster_begin(rb);
126       skc_raster_add_filled(rb,
127                             paths[ii],
128                             ts_transform_stack_top_weakref(ts),
129                             ts_transform_stack_top_transform(ts),
130                             NULL,
131                             raster_clip);
132       skc_raster_end(rb,rasters+ii);
133     }
134 
135   // restore stack depth
136   ts_transform_stack_restore(ts,ts_restore);
137 
138   return rasters;
139 }
140 
141 void
groups_rasters_release(skc_context_t context,skc_raster_t * const rasters)142 groups_rasters_release(skc_context_t        context,
143                        skc_raster_t * const rasters)
144 {
145   skc_raster_release(context,rasters,6);
146 
147   free(rasters);
148 }
149 
150 //
151 //
152 //
153 
154 void
groups_rewind()155 groups_rewind()
156 {
157   ;
158 }
159 
160 //
161 //
162 //
163 
164 uint32_t
groups_layer_count()165 groups_layer_count()
166 {
167   return 6;
168 }
169 
170 void
groups_layers_decode(skc_raster_t const * const rasters,skc_composition_t composition,skc_styling_t styling,bool const is_srgb)171 groups_layers_decode(skc_raster_t const * const rasters,
172                      skc_composition_t          composition,
173                      skc_styling_t              styling,
174                      bool const                 is_srgb)
175 {
176   skc_group_id group_ids[2];
177 
178   {
179     skc_styling_group_alloc(styling,group_ids+0);
180 
181     // this is the root group
182     skc_styling_group_parents(styling,group_ids[0],0,NULL);
183 
184     // the range of the root group is maximal
185     skc_styling_group_range_lo(styling,group_ids[0],0);
186     skc_styling_group_range_hi(styling,group_ids[0],5);
187 
188     skc_styling_group_enter(styling,
189                             group_ids[0],
190                             1,
191                             (skc_styling_cmd_t[])
192                             { SKC_STYLING_OPCODE_COLOR_ACC_ZERO |
193                               SKC_STYLING_OPCODE_IS_FINAL });
194 
195     skc_styling_cmd_t cmds[3 + 1];
196 
197     float background[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
198 
199     skc_styling_background_over_encoder(cmds,background);
200 
201     cmds[3] = SKC_STYLING_OPCODE_SURFACE_COMPOSITE | SKC_STYLING_OPCODE_IS_FINAL;
202 
203     skc_styling_group_leave(styling,
204                             group_ids[0],
205                             SKC_STYLING_CMDS(cmds));
206   }
207 
208   //
209   // for all layers...
210   //
211   for (uint32_t ii=0; ii<3; ii++)
212     {
213       skc_styling_group_alloc(styling,group_ids+1);
214 
215       // this is the root group
216       skc_styling_group_parents(styling,group_ids[1],1,group_ids);
217 
218       // the range of the root group is maximal
219       skc_styling_group_range_lo(styling,group_ids[1],ii*2);
220       skc_styling_group_range_hi(styling,group_ids[1],ii*2+1);
221 
222       skc_styling_group_enter(styling,
223                               group_ids[1],
224                               1,
225                               (skc_styling_cmd_t[])
226                               { is_mask_invertible
227                                   ? (SKC_STYLING_OPCODE_COVER_MASK_ONE  | SKC_STYLING_OPCODE_IS_FINAL)
228                                   : (SKC_STYLING_OPCODE_COVER_MASK_ZERO | SKC_STYLING_OPCODE_IS_FINAL) });
229 
230       skc_styling_group_leave(styling,
231                               group_ids[1],
232                               1,
233                               (skc_styling_cmd_t[])
234                               { SKC_STYLING_OPCODE_NOOP |
235                                 SKC_STYLING_OPCODE_IS_FINAL });
236 
237       //
238       //
239       //
240 
241       {
242         float const rgba[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
243 
244         skc_styling_cmd_t cmds[1 + 1 + 1];
245 
246         cmds[0] = SKC_STYLING_OPCODE_COVER_NONZERO;
247 
248         if (is_mask_invertible)
249           {
250             cmds[1] = SKC_STYLING_OPCODE_COVER_WIP_MOVE_TO_MASK;
251             cmds[2] = SKC_STYLING_OPCODE_COVER_MASK_INVERT | SKC_STYLING_OPCODE_IS_FINAL;
252           }
253         else
254           {
255             cmds[1] = SKC_STYLING_OPCODE_COVER_WIP_MOVE_TO_MASK | SKC_STYLING_OPCODE_IS_FINAL;
256           }
257 
258         skc_styling_group_layer(styling,
259                                 group_ids[1],
260                                 ii*2,
261                                 _countof(cmds),cmds);
262       }
263       {
264         float rgba[4];
265 
266         color_rgb32_to_rgba_f32(rgba,0xFF<<ii*8,1.0f);
267 
268         skc_styling_cmd_t cmds[1 + 1 + 3 + 1];
269 
270         cmds[0]                = SKC_STYLING_OPCODE_COVER_NONZERO;
271         cmds[1]                = SKC_STYLING_OPCODE_COVER_MASK;
272 
273         skc_styling_layer_fill_rgba_encoder(cmds+2,rgba);
274 
275         cmds[_countof(cmds)-1] = SKC_STYLING_OPCODE_BLEND_OVER | SKC_STYLING_OPCODE_IS_FINAL;
276 
277         skc_styling_group_layer(styling,
278                                 group_ids[1],
279                                 ii*2+1,
280                                 _countof(cmds),cmds);
281       }
282     }
283 
284   //
285   // for all rasters...
286   //
287   for (uint32_t ii=0; ii<6; ii++)
288     {
289       skc_composition_place(composition,
290                             rasters+ii,
291                             &ii,
292                             NULL, // &cmd->place.tx,
293                             NULL, // &cmd->place.ty,
294                             1);
295     }
296 }
297 
298 //
299 //
300 //
301