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