1 | #include <iostream> |
2 | #include <sstream> |
3 | #include <fstream> |
4 | |
5 | #include "sdl_painter_demo.hpp" |
6 | #include "simple_time.hpp" |
7 | #include "PanZoomTracker.hpp" |
8 | #include "read_path.hpp" |
9 | #include "ImageLoader.hpp" |
10 | #include "colorstop_command_line.hpp" |
11 | #include "cycle_value.hpp" |
12 | |
13 | using namespace fastuidraw; |
14 | |
15 | class rounded_corner_radii |
16 | { |
17 | public: |
18 | rounded_corner_radii(const std::string &name, |
19 | command_line_register &parent): |
20 | m_x(10.0f, "rect_" + name + "_x" , "Rounded rectangle " + name + "-radii-x" , parent), |
21 | m_y(5.0f, "rect_" + name + "_y" , "Rounded rectangle " + name + "-radii-y" , parent) |
22 | {} |
23 | |
24 | vec2 |
25 | value(void) const |
26 | { |
27 | return vec2(m_x.value(), m_y.value()); |
28 | } |
29 | |
30 | command_line_argument_value<float> m_x, m_y; |
31 | }; |
32 | |
33 | #ifndef FASTUIDRAW_GL_USE_GLES |
34 | |
35 | class EnableWireFrameAction:public PainterDrawBreakAction |
36 | { |
37 | public: |
38 | explicit |
39 | EnableWireFrameAction(bool b): |
40 | m_lines(b) |
41 | {} |
42 | |
43 | virtual |
44 | fastuidraw::gpu_dirty_state |
45 | execute(PainterBackend*) const |
46 | { |
47 | if (m_lines) |
48 | { |
49 | fastuidraw_glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
50 | fastuidraw_glLineWidth(4.0); |
51 | } |
52 | else |
53 | { |
54 | fastuidraw_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
55 | } |
56 | return 0u; |
57 | } |
58 | |
59 | private: |
60 | bool m_lines; |
61 | }; |
62 | |
63 | #endif |
64 | |
65 | class painter_clip_test:public sdl_painter_demo |
66 | { |
67 | public: |
68 | painter_clip_test(void); |
69 | |
70 | protected: |
71 | void |
72 | derived_init(int, int); |
73 | |
74 | void |
75 | draw_frame(void); |
76 | |
77 | void |
78 | handle_event(const SDL_Event &ev); |
79 | |
80 | private: |
81 | |
82 | enum |
83 | { |
84 | clip_in, |
85 | clip_out, |
86 | no_clip, |
87 | |
88 | number_clip_modes |
89 | }; |
90 | |
91 | enum |
92 | { |
93 | view_transformer, |
94 | path1_transformer, |
95 | path2_transformer, |
96 | rect_transformer, |
97 | |
98 | number_transformers |
99 | }; |
100 | |
101 | enum |
102 | { |
103 | separate_clipping, |
104 | path1_then_path2, |
105 | path2_then_path1, |
106 | |
107 | number_combine_clip_modes |
108 | }; |
109 | |
110 | class Transformer |
111 | { |
112 | public: |
113 | Transformer(void): |
114 | m_shear(1.0f, 1.0f), |
115 | m_angle(0.0f) |
116 | {} |
117 | |
118 | void |
119 | concat_to_painter(const reference_counted_ptr<Painter> &ref) const |
120 | { |
121 | const float conv(FASTUIDRAW_PI / 180.0f); |
122 | m_zoomer.transformation().concat_to_painter(ref); |
123 | ref->shear(m_shear.x(), m_shear.y()); |
124 | ref->rotate(m_angle * conv); |
125 | } |
126 | |
127 | PanZoomTrackerSDLEvent m_zoomer; |
128 | vec2 m_shear; |
129 | float m_angle; |
130 | }; |
131 | |
132 | void |
133 | draw_element(const Path &path, unsigned int clip_mode, const vec4 &color, |
134 | const Transformer &matrix); |
135 | |
136 | void |
137 | draw_combined(const Path &path1, unsigned int clip_mode1, const Transformer &matrix1, |
138 | const Path &path2, unsigned int clip_mode2, const Transformer &matrix2, |
139 | const vec4 &color); |
140 | |
141 | enum return_code |
142 | load_path(Path &out_path, const std::string &file); |
143 | |
144 | void |
145 | make_paths(void); |
146 | |
147 | void |
148 | update_cts_params(void); |
149 | |
150 | command_line_argument_value<std::string> m_path1_file; |
151 | command_line_argument_value<std::string> m_path2_file; |
152 | command_line_argument_value<std::string> m_image_file; |
153 | command_line_argument_value<float> m_rect_width; |
154 | command_line_argument_value<float> m_rect_height; |
155 | rounded_corner_radii m_rect_minx_miny_radii; |
156 | rounded_corner_radii m_rect_minx_maxy_radii; |
157 | rounded_corner_radii m_rect_maxx_miny_radii; |
158 | rounded_corner_radii m_rect_maxx_maxy_radii; |
159 | |
160 | Path m_path1, m_path2; |
161 | RoundedRect m_rect; |
162 | reference_counted_ptr<const Image> m_image; |
163 | |
164 | unsigned int m_path1_clip_mode, m_path2_clip_mode; |
165 | unsigned int m_combine_clip_mode, m_rounded_rect_mode; |
166 | unsigned int m_active_transformer; |
167 | bool m_aa_mode; |
168 | bool m_show_wire_frame; |
169 | vecN<Transformer, number_transformers> m_transformers; |
170 | vecN<std::string, number_clip_modes> m_clip_labels; |
171 | vecN<std::string, number_transformers> m_transformer_labels; |
172 | vecN<std::string, number_combine_clip_modes> m_combine_clip_labels; |
173 | simple_time m_draw_timer; |
174 | int m_show_surface, m_last_shown_surface; |
175 | }; |
176 | |
177 | painter_clip_test:: |
178 | painter_clip_test(): |
179 | m_path1_file("" , "path1_file" , |
180 | "if non-empty read the geometry of the path1 from the specified file, " |
181 | "otherwise use a default path" , |
182 | *this), |
183 | m_path2_file("" , "path2_file" , |
184 | "if non-empty read the geometry of the path1 from the specified file, " |
185 | "otherwise use a default path" , |
186 | *this), |
187 | m_image_file("" , "image" , "if a valid file name, apply an image to drawing the rounded rect" , *this), |
188 | m_rect_width(100.0f, "rect_width" , "Rounded rectangle width" , *this), |
189 | m_rect_height(50.0f, "rect_height" , "Rounded rectangle height" , *this), |
190 | m_rect_minx_miny_radii("minx-miny" , *this), |
191 | m_rect_minx_maxy_radii("minx-maxy" , *this), |
192 | m_rect_maxx_miny_radii("maxx-miny" , *this), |
193 | m_rect_maxx_maxy_radii("maxx-maxy" , *this), |
194 | m_path1_clip_mode(no_clip), |
195 | m_path2_clip_mode(no_clip), |
196 | m_combine_clip_mode(separate_clipping), |
197 | m_rounded_rect_mode(no_clip), |
198 | m_active_transformer(view_transformer), |
199 | m_aa_mode(true), |
200 | m_show_wire_frame(false), |
201 | m_show_surface(0), |
202 | m_last_shown_surface(0) |
203 | { |
204 | std::cout << "Controls:\n" |
205 | << "\t1: cycle through clip modes for path1\n" |
206 | << "\t2: cycle through clip modes for path2\n" |
207 | << "\ts: cycle through active transformer controls\n" |
208 | << "\tc: change combine clip mode\n" |
209 | << "\tr: change rounded rect mode\n" |
210 | << "\tu: change anti-alias mode\n" |
211 | << "\t6: x-shear (hold ctrl to decrease)\n" |
212 | << "\t7: y-shear (hold ctrl to decrease)\n" |
213 | << "\t0: Rotate left\n" |
214 | << "\t9: Rotate right\n" ; |
215 | |
216 | #ifndef FASTUIDRAW_GL_USE_GLES |
217 | { |
218 | std::cout << "\tspace: toggle wire frame on rounded rect\n" ; |
219 | } |
220 | #endif |
221 | |
222 | m_clip_labels[clip_in] = "clip_in" ; |
223 | m_clip_labels[clip_out] = "clip_out" ; |
224 | m_clip_labels[no_clip] = "no_clip" ; |
225 | |
226 | m_transformer_labels[view_transformer] = "view_transformer" ; |
227 | m_transformer_labels[path1_transformer] = "path1_transformer" ; |
228 | m_transformer_labels[path2_transformer] = "path2_transformer" ; |
229 | m_transformer_labels[rect_transformer] = "rect_transformer" ; |
230 | |
231 | m_combine_clip_labels[separate_clipping] = "separate_clipping" ; |
232 | m_combine_clip_labels[path1_then_path2] = "path1_then_path2" ; |
233 | m_combine_clip_labels[path2_then_path1] = "path2_then_path1" ; |
234 | } |
235 | |
236 | void |
237 | painter_clip_test:: |
238 | handle_event(const SDL_Event &ev) |
239 | { |
240 | if (m_active_transformer != view_transformer) |
241 | { |
242 | /* invert y-direction for the other transformers */ |
243 | ScaleTranslate<float> inv; |
244 | |
245 | inv = m_transformers[view_transformer].m_zoomer.transformation().inverse(); |
246 | m_transformers[m_active_transformer].m_zoomer.m_scale_event = vec2(inv.scale(), inv.scale()); |
247 | m_transformers[m_active_transformer].m_zoomer.m_scale_zooming = inv.scale(); |
248 | m_transformers[m_active_transformer].m_zoomer.m_translate_event = inv.translation(); |
249 | } |
250 | |
251 | m_transformers[m_active_transformer].m_zoomer.handle_event(ev); |
252 | switch(ev.type) |
253 | { |
254 | case SDL_WINDOWEVENT: |
255 | if (ev.window.event == SDL_WINDOWEVENT_RESIZED) |
256 | { |
257 | on_resize(ev.window.data1, ev.window.data2); |
258 | } |
259 | break; |
260 | |
261 | case SDL_QUIT: |
262 | end_demo(0); |
263 | break; |
264 | |
265 | case SDL_KEYUP: |
266 | switch(ev.key.keysym.sym) |
267 | { |
268 | case SDLK_ESCAPE: |
269 | end_demo(0); |
270 | break; |
271 | case SDLK_1: |
272 | cycle_value(m_path1_clip_mode, ev.key.keysym.mod & (KMOD_SHIFT|KMOD_CTRL|KMOD_ALT), number_clip_modes); |
273 | std::cout << "Path1 clip mode set to: " << m_clip_labels[m_path1_clip_mode] << "\n" ; |
274 | break; |
275 | case SDLK_2: |
276 | cycle_value(m_path2_clip_mode, ev.key.keysym.mod & (KMOD_SHIFT|KMOD_CTRL|KMOD_ALT), number_clip_modes); |
277 | std::cout << "Path2 clip mode set to: " << m_clip_labels[m_path2_clip_mode] << "\n" ; |
278 | break; |
279 | case SDLK_s: |
280 | cycle_value(m_active_transformer, ev.key.keysym.mod & (KMOD_SHIFT|KMOD_CTRL|KMOD_ALT), number_transformers); |
281 | std::cout << "Active zoomer set to: " << m_transformer_labels[m_active_transformer] << "\n" ; |
282 | break; |
283 | case SDLK_c: |
284 | cycle_value(m_combine_clip_mode, ev.key.keysym.mod & (KMOD_SHIFT|KMOD_CTRL|KMOD_ALT), number_combine_clip_modes); |
285 | std::cout << "Combine clip mode set to: " << m_combine_clip_labels[m_combine_clip_mode] << "\n" ; |
286 | break; |
287 | case SDLK_r: |
288 | cycle_value(m_rounded_rect_mode, ev.key.keysym.mod & (KMOD_SHIFT|KMOD_CTRL|KMOD_ALT), number_clip_modes); |
289 | std::cout << "Rounded rect mode set to: " << m_clip_labels[m_rounded_rect_mode] << "\n" ; |
290 | break; |
291 | case SDLK_u: |
292 | m_aa_mode = !m_aa_mode; |
293 | std::cout << "RoundedRect drawing anti-alias mode set to: " << m_aa_mode << "\n" ; |
294 | break; |
295 | case SDLK_o: |
296 | if (ev.key.keysym.mod & (KMOD_SHIFT | KMOD_ALT)) |
297 | { |
298 | if (m_show_surface > 0) |
299 | { |
300 | --m_show_surface; |
301 | } |
302 | } |
303 | else |
304 | { |
305 | ++m_show_surface; |
306 | } |
307 | break; |
308 | case SDLK_SPACE: |
309 | m_show_wire_frame = !m_show_wire_frame; |
310 | break; |
311 | } |
312 | break; |
313 | }; |
314 | } |
315 | |
316 | void |
317 | painter_clip_test:: |
318 | update_cts_params(void) |
319 | { |
320 | const Uint8 *keyboard_state = SDL_GetKeyboardState(nullptr); |
321 | FASTUIDRAWassert(keyboard_state != nullptr); |
322 | |
323 | float speed = static_cast<float>(m_draw_timer.restart_us()), speed_shear; |
324 | if (m_active_transformer == view_transformer) |
325 | { |
326 | return; |
327 | } |
328 | |
329 | speed /= 1000.0f; |
330 | if (keyboard_state[SDL_SCANCODE_LSHIFT]) |
331 | { |
332 | speed *= 0.1f; |
333 | } |
334 | if (keyboard_state[SDL_SCANCODE_RSHIFT]) |
335 | { |
336 | speed *= 10.0f; |
337 | } |
338 | |
339 | speed_shear = 0.01f * speed; |
340 | if (keyboard_state[SDL_SCANCODE_LCTRL] || keyboard_state[SDL_SCANCODE_RCTRL]) |
341 | { |
342 | speed_shear = -speed_shear; |
343 | } |
344 | |
345 | speed_shear = 0.01f * speed; |
346 | if (keyboard_state[SDL_SCANCODE_LCTRL] || keyboard_state[SDL_SCANCODE_RCTRL]) |
347 | { |
348 | speed_shear = -speed_shear; |
349 | } |
350 | |
351 | vec2 *pshear(&m_transformers[m_active_transformer].m_shear); |
352 | float *pangle(&m_transformers[m_active_transformer].m_angle); |
353 | |
354 | if (keyboard_state[SDL_SCANCODE_6]) |
355 | { |
356 | pshear->x() += speed_shear; |
357 | std::cout << "Shear set to: " << *pshear << "\n" ; |
358 | } |
359 | if (keyboard_state[SDL_SCANCODE_7]) |
360 | { |
361 | pshear->y() += speed_shear; |
362 | std::cout << "Shear set to: " << *pshear << "\n" ; |
363 | } |
364 | |
365 | if (keyboard_state[SDL_SCANCODE_9]) |
366 | { |
367 | *pangle += speed * 0.1f; |
368 | std::cout << "Angle set to: " << *pangle << "\n" ; |
369 | } |
370 | if (keyboard_state[SDL_SCANCODE_0]) |
371 | { |
372 | *pangle -= speed * 0.1f; |
373 | std::cout << "Angle set to: " << *pangle << "\n" ; |
374 | } |
375 | } |
376 | |
377 | enum return_code |
378 | painter_clip_test:: |
379 | load_path(Path &out_path, const std::string &filename) |
380 | { |
381 | if (!filename.empty()) |
382 | { |
383 | std::ifstream path_file(filename.c_str()); |
384 | if (path_file) |
385 | { |
386 | std::stringstream buffer; |
387 | buffer << path_file.rdbuf(); |
388 | read_path(out_path, buffer.str()); |
389 | return routine_success; |
390 | } |
391 | } |
392 | return routine_fail; |
393 | } |
394 | |
395 | |
396 | void |
397 | painter_clip_test:: |
398 | make_paths(void) |
399 | { |
400 | if (routine_fail == load_path(m_path1, m_path1_file.value())) |
401 | { |
402 | m_path1 << vec2(100.0f, 100.0f) |
403 | << vec2(0.0f, 0.0f) |
404 | << vec2(100.0f, 0.0f) |
405 | << Path::contour_close(); |
406 | } |
407 | |
408 | if (routine_fail == load_path(m_path2, m_path2_file.value())) |
409 | { |
410 | m_path2 << vec2(100.0f, 0.0f) |
411 | << vec2(0.0f, 100.0f) |
412 | << vec2(100.0f, 100.0f) |
413 | << Path::contour_close(); |
414 | } |
415 | } |
416 | |
417 | void |
418 | painter_clip_test:: |
419 | derived_init(int, int) |
420 | { |
421 | make_paths(); |
422 | |
423 | if (!m_image_file.value().empty()) |
424 | { |
425 | ImageLoader image_data(m_image_file.value()); |
426 | m_image = m_painter->image_atlas().create(image_data.width(), |
427 | image_data.height(), |
428 | image_data, |
429 | Image::bindless_texture2d); |
430 | if (m_image) |
431 | { |
432 | std::cout << "Loaded image \"" << m_image_file.value() |
433 | << "\", dimensions = " << m_image->dimensions() |
434 | << "\n" ; |
435 | } |
436 | } |
437 | |
438 | m_rect.m_min_point = vec2(0.0f, 0.0f); |
439 | m_rect.m_max_point = vec2(m_rect_width.value(), m_rect_height.value()); |
440 | m_rect.m_corner_radii[Rect::minx_miny_corner] = m_rect_minx_miny_radii.value(); |
441 | m_rect.m_corner_radii[Rect::minx_maxy_corner] = m_rect_minx_maxy_radii.value(); |
442 | m_rect.m_corner_radii[Rect::maxx_miny_corner] = m_rect_maxx_miny_radii.value(); |
443 | m_rect.m_corner_radii[Rect::maxx_maxy_corner] = m_rect_maxx_maxy_radii.value(); |
444 | m_draw_timer.restart(); |
445 | } |
446 | |
447 | void |
448 | painter_clip_test:: |
449 | draw_element(const Path &path, unsigned int clip_mode, const vec4 &color, |
450 | const Transformer &matrix) |
451 | { |
452 | PainterBrush brush; |
453 | |
454 | m_painter->save(); |
455 | matrix.concat_to_painter(m_painter); |
456 | brush.color(color); |
457 | switch(clip_mode) |
458 | { |
459 | default: |
460 | break; |
461 | |
462 | case clip_in: |
463 | m_painter->clip_in_path(path, Painter::nonzero_fill_rule); |
464 | break; |
465 | case clip_out: |
466 | m_painter->clip_out_path(path, Painter::nonzero_fill_rule); |
467 | break; |
468 | } |
469 | |
470 | m_painter->fill_rect(PainterData(&brush), path.tessellation().bounding_box()); |
471 | m_painter->restore(); |
472 | } |
473 | |
474 | void |
475 | painter_clip_test:: |
476 | draw_combined(const Path &path1, unsigned int clip_mode1, const Transformer &matrix1, |
477 | const Path &path2, unsigned int clip_mode2, const Transformer &matrix2, |
478 | const vec4 &color) |
479 | { |
480 | float3x3 M(m_painter->transformation()); |
481 | PainterBrush brush; |
482 | |
483 | brush.color(color); |
484 | m_painter->save(); |
485 | matrix1.concat_to_painter(m_painter); |
486 | switch (clip_mode1) |
487 | { |
488 | default: |
489 | break; |
490 | case clip_in: |
491 | m_painter->clip_in_path(path1, Painter::nonzero_fill_rule); |
492 | break; |
493 | case clip_out: |
494 | m_painter->clip_out_path(path1, Painter::nonzero_fill_rule); |
495 | break; |
496 | } |
497 | |
498 | m_painter->transformation(M); |
499 | matrix2.concat_to_painter(m_painter); |
500 | switch (clip_mode2) |
501 | { |
502 | default: |
503 | break; |
504 | case clip_in: |
505 | m_painter->clip_in_path(path2, Painter::nonzero_fill_rule); |
506 | break; |
507 | case clip_out: |
508 | m_painter->clip_out_path(path2, Painter::nonzero_fill_rule); |
509 | break; |
510 | } |
511 | |
512 | m_painter->transformation(M); |
513 | matrix1.concat_to_painter(m_painter); |
514 | |
515 | m_painter->fill_rect(PainterData(&brush), path1.tessellation().bounding_box()); |
516 | m_painter->restore(); |
517 | } |
518 | |
519 | void |
520 | painter_clip_test:: |
521 | draw_frame(void) |
522 | { |
523 | update_cts_params(); |
524 | m_painter->begin(m_surface, Painter::y_increases_downwards); |
525 | m_transformers[view_transformer].concat_to_painter(m_painter); |
526 | |
527 | float3x3 M(m_painter->transformation()); |
528 | m_transformers[rect_transformer].concat_to_painter(m_painter); |
529 | switch(m_rounded_rect_mode) |
530 | { |
531 | case no_clip: |
532 | { |
533 | PainterBrush brush; |
534 | |
535 | if (m_image) |
536 | { |
537 | brush.image(m_image); |
538 | } |
539 | else |
540 | { |
541 | brush.color(vec4(1.0f, 1.0f, 0.0f, 1.0f)); |
542 | } |
543 | m_painter->fill_rounded_rect(m_painter->default_shaders().fill_shader(), |
544 | PainterData(&brush), m_rect, m_aa_mode); |
545 | |
546 | #ifndef FASTUIDRAW_GL_USE_GLES |
547 | { |
548 | if (m_show_wire_frame) |
549 | { |
550 | PainterBrush red; |
551 | |
552 | red.color(1.0f, 0.0f, 0.0f, 0.25f); |
553 | m_painter->queue_action(FASTUIDRAWnew EnableWireFrameAction(true)); |
554 | m_painter->fill_rounded_rect(m_painter->default_shaders().fill_shader(), |
555 | PainterData(&red), m_rect, false); |
556 | m_painter->queue_action(FASTUIDRAWnew EnableWireFrameAction(false)); |
557 | } |
558 | } |
559 | #endif |
560 | } |
561 | break; |
562 | |
563 | case clip_in: |
564 | m_painter->clip_in_rounded_rect(m_rect); |
565 | break; |
566 | |
567 | case clip_out: |
568 | m_painter->clip_out_rounded_rect(m_rect); |
569 | break; |
570 | |
571 | } |
572 | m_painter->transformation(M); |
573 | |
574 | switch(m_combine_clip_mode) |
575 | { |
576 | case separate_clipping: |
577 | draw_element(m_path1, m_path1_clip_mode, vec4(1.0f, 0.0f, 0.0f, 0.5f), |
578 | m_transformers[path1_transformer]); |
579 | draw_element(m_path2, m_path2_clip_mode, vec4(0.0f, 1.0f, 0.0f, 0.5f), |
580 | m_transformers[path2_transformer]); |
581 | break; |
582 | |
583 | case path1_then_path2: |
584 | draw_combined(m_path1, m_path1_clip_mode, m_transformers[path1_transformer], |
585 | m_path2, m_path2_clip_mode, m_transformers[path2_transformer], |
586 | vec4(0.0f, 1.0f, 1.0f, 0.5f)); |
587 | break; |
588 | |
589 | case path2_then_path1: |
590 | draw_combined(m_path2, m_path2_clip_mode, m_transformers[path2_transformer], |
591 | m_path1, m_path1_clip_mode, m_transformers[path1_transformer], |
592 | vec4(1.0f, 0.0f, 1.0f, 0.5f)); |
593 | break; |
594 | } |
595 | |
596 | c_array<const PainterSurface* const> surfaces; |
597 | |
598 | surfaces = m_painter->end(); |
599 | fastuidraw_glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |
600 | fastuidraw_glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
601 | |
602 | m_show_surface = t_min(m_show_surface, (int)surfaces.size()); |
603 | if (m_show_surface <= 0 || m_show_surface > surfaces.size()) |
604 | { |
605 | m_surface->blit_surface(GL_NEAREST); |
606 | } |
607 | else |
608 | { |
609 | const gl::PainterSurfaceGL *S; |
610 | PainterSurface::Viewport src, dest; |
611 | |
612 | src = m_surface->viewport(); |
613 | S = dynamic_cast<const gl::PainterSurfaceGL*>(surfaces[m_show_surface - 1]); |
614 | |
615 | dest.m_origin = src.m_origin; |
616 | dest.m_dimensions = ivec2(src.m_dimensions.x(), src.m_dimensions.y() / 2); |
617 | m_surface->blit_surface(src, dest, GL_LINEAR); |
618 | |
619 | dest.m_origin.y() += dest.m_dimensions.y(); |
620 | S->blit_surface(src, dest, GL_LINEAR); |
621 | } |
622 | |
623 | if (m_last_shown_surface != m_show_surface) |
624 | { |
625 | if (m_show_surface > 0) |
626 | { |
627 | std::cout << "Show offscreen surface: " << m_show_surface - 1 << "\n" ; |
628 | } |
629 | else |
630 | { |
631 | std::cout << "Don't show offscreen surface\n" ; |
632 | } |
633 | m_last_shown_surface = m_show_surface; |
634 | } |
635 | } |
636 | |
637 | int |
638 | main(int argc, char **argv) |
639 | { |
640 | painter_clip_test P; |
641 | return P.main(argc, argv); |
642 | } |
643 | |