NetSurf
knockout.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 Richard Wilson <info@tinct.net>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * Knockout rendering implementation.
22 *
23 * Knockout rendering is an optimisation which is particularly for
24 * unaccelerated screen redraw. It tries to avoid plotting the same area more
25 * than once.
26 *
27 * If the object is to plot two overlapping rectangles (one large, one small),
28 * such as:
29 *
30 * +-----------------+
31 * |#################|
32 * |####+-------+####|
33 * |####|:::::::|####|
34 * |####|:::::::|####|
35 * |####|:::::::|####|
36 * |####+-------+####|
37 * |#################|
38 * +-----------------+
39 *
40 * Without knockout rendering we plot the bottom rectangle and then the top one:
41 *
42 * +-----------------+ +-----------------+
43 * |#################| |#################|
44 * |#################| |####+-------+####|
45 * |#################| |####|:::::::|####|
46 * |#################| and then, |####|:::::::|####|
47 * |#################| |####|:::::::|####|
48 * |#################| |####+-------+####|
49 * |#################| |#################|
50 * +-----------------+ +-----------------+
51 *
52 * With knockout rendering, the bottom rectangle is split up into smaller
53 * ones and each pixel is just plotted once:
54 *
55 * +-----------------+
56 * |#################|
57 * +----+-------+----+
58 * |####|:::::::|####|
59 * |####|:::::::|####|
60 * |####|:::::::|####|
61 * +----+-------+----+
62 * |#################|
63 * +-----------------+
64 */
65
66#include <assert.h>
67#include <string.h>
68#include <stdio.h>
69
70#include "utils/utils.h"
71#include "utils/log.h"
72#include "utils/errors.h"
73#include "netsurf/bitmap.h"
74#include "content/content.h"
75#include "netsurf/plotters.h"
76
78#include "desktop/knockout.h"
79
80/* Define to enable knockout debug */
81#undef KNOCKOUT_DEBUG
82
83#define KNOCKOUT_ENTRIES 3072 /* 40 bytes each */
84#define KNOCKOUT_BOXES 768 /* 28 bytes each */
85#define KNOCKOUT_POLYGONS 3072 /* 4 bytes each */
86
87struct knockout_box;
88struct knockout_entry;
89
90typedef enum {
94 KNOCKOUT_PLOT_FILL, /* knockout, knocked out */
99 KNOCKOUT_PLOT_BITMAP, /* knockout, knocked out */
103
104
106 struct rect bbox;
107 bool deleted; /* box has been deleted, ignore */
110};
111
112
115 struct knockout_box *box; /* relating series of knockout clips */
116 union {
117 struct {
118 struct rect r;
121 struct {
122 struct rect l;
125 struct {
126 int *p;
127 unsigned int n;
130 struct {
131 struct rect r;
134 struct rect clip;
135 struct {
136 int x;
137 int y;
138 const char *text;
139 size_t length;
142 struct {
143 int x;
144 int y;
148 struct {
149 int x;
150 int y;
151 int radius;
156 struct {
157 int x;
158 int y;
159 int width;
161 struct bitmap *bitmap;
165 struct {
166 const char *name;
169};
170
171
175static int knockout_entry_cur = 0;
176static int knockout_box_cur = 0;
177static int knockout_polygon_cur = 0;
178static struct knockout_box *knockout_list = NULL;
179
181
182static struct rect clip_cur;
183static int nested_depth = 0;
184
185
186/**
187 * fill an area recursively
188 */
189static nserror
191 struct knockout_box *box,
192 plot_style_t *plot_style)
193{
194 struct knockout_box *parent;
195 nserror res;
196 nserror ffres = NSERROR_OK; /* first failing result */
197
198 for (parent = box; parent; parent = parent->next) {
199 if (parent->deleted)
200 continue;
201 if (parent->child) {
203 parent->child,
204 plot_style);
205 } else {
206 res = real_plot.rectangle(ctx, plot_style, &parent->bbox);
207 }
208 /* remember the first error */
209 if ((res != NSERROR_OK) && (ffres == NSERROR_OK)) {
210 ffres = res;
211 }
212 }
213 return ffres;
214}
215
216
217/**
218 * bitmap plot recusivley
219 */
220static nserror
222 struct knockout_box *box,
223 struct knockout_entry *entry)
224{
225 nserror res;
226 nserror ffres = NSERROR_OK; /* first failing result */
227 struct knockout_box *parent;
228
229 for (parent = box; parent; parent = parent->next) {
230 if (parent->deleted)
231 continue;
232 if (parent->child) {
234 parent->child,
235 entry);
236 } else {
237 real_plot.clip(ctx, &parent->bbox);
238 res = real_plot.bitmap(ctx,
239 entry->data.bitmap.bitmap,
240 entry->data.bitmap.x,
241 entry->data.bitmap.y,
242 entry->data.bitmap.width,
243 entry->data.bitmap.height,
244 entry->data.bitmap.bg,
245 entry->data.bitmap.flags);
246 }
247 /* remember the first error */
248 if ((res != NSERROR_OK) && (ffres == NSERROR_OK)) {
249 ffres = res;
250 }
251
252 }
253 return ffres;
254}
255
256/**
257 * Flush the current knockout session to empty the buffers
258 *
259 * \return true on success, false otherwise
260 */
262{
263 int i;
264 struct knockout_box *box;
265 nserror res = NSERROR_OK; /* operation result */
266 nserror ffres = NSERROR_OK; /* first failing result */
267
268 /* debugging information */
269#ifdef KNOCKOUT_DEBUG
270 NSLOG(netsurf, INFO, "Entries are %i/%i, %i/%i, %i/%i",
273#endif
274
275 for (i = 0; i < knockout_entry_cur; i++) {
276 switch (knockout_entries[i].type) {
278 res = real_plot.rectangle(ctx,
281 break;
282
284 res = real_plot.line(ctx,
287 break;
288
290 res = real_plot.polygon(ctx,
294 break;
295
298 if (box) {
300 box,
302 } else if (!knockout_entries[i].box->deleted) {
303 res = real_plot.rectangle(ctx,
306 }
307 break;
308
310 res = real_plot.clip(ctx, &knockout_entries[i].data.clip);
311 break;
312
314 res = real_plot.text(ctx,
315 &knockout_entries[i].data.text.font_style,
318 knockout_entries[i].data.text.text,
319 knockout_entries[i].data.text.length);
320 break;
321
323 res = real_plot.disc(ctx,
328 break;
329
331 res = real_plot.arc(ctx,
338 break;
339
342 if (box) {
344 box,
345 &knockout_entries[i]);
346 } else if (!knockout_entries[i].box->deleted) {
347 res = real_plot.bitmap(ctx,
348 knockout_entries[i].data.bitmap.bitmap,
354 knockout_entries[i].data.bitmap.flags);
355 }
356 break;
357
359 res = real_plot.group_start(ctx,
361 break;
362
364 res = real_plot.group_end(ctx);
365 break;
366 }
367
368 /* remember the first error */
369 if ((res != NSERROR_OK) && (ffres == NSERROR_OK)) {
370 ffres = res;
371 }
372 }
373
377 knockout_list = NULL;
378
379 return ffres;
380}
381
382
383/**
384 * Knockout a section of previous rendering
385 *
386 * \param ctx The current redraw context.
387 * \param x0 The left edge of the removal box
388 * \param y0 The bottom edge of the removal box
389 * \param x1 The right edge of the removal box
390 * \param y1 The top edge of the removal box
391 * \param owner The parent box set to consider, or NULL for top level
392 */
393static void
395 int x0, int y0, int x1, int y1,
396 struct knockout_box *owner)
397{
398 struct knockout_box *box;
399 struct knockout_box *parent;
400 struct knockout_box *prev = NULL;
401 int nx0, ny0, nx1, ny1;
402
403 if (owner == NULL)
405 else
406 box = owner->child;
407
408 for (parent = box; parent; parent = parent->next) {
409 /* permanently delink deleted nodes */
410 if (parent->deleted) {
411 if (prev) {
412 /* not the first valid element: just skip future */
413 prev->next = parent->next;
414 } else {
415 if (owner) {
416 /* first valid element: update child reference */
417 owner->child = parent->next;
418 /* have we deleted all child nodes? */
419 if (!owner->child)
420 owner->deleted = true;
421 } else {
422 /* we are the head of the list */
423 knockout_list = parent->next;
424 }
425 }
426 continue;
427 } else {
428 prev = parent;
429 }
430
431 /* get the parent dimensions */
432 nx0 = parent->bbox.x0;
433 ny0 = parent->bbox.y0;
434 nx1 = parent->bbox.x1;
435 ny1 = parent->bbox.y1;
436
437 /* reject non-overlapping boxes */
438 if ((nx0 >= x1) || (nx1 <= x0) || (ny0 >= y1) || (ny1 <= y0))
439 continue;
440
441 /* check for a total knockout */
442 if ((x0 <= nx0) && (x1 >= nx1) && (y0 <= ny0) && (y1 >= ny1)) {
443 parent->deleted = true;
444 continue;
445 }
446
447 /* has the box been replaced by children? */
448 if (parent->child) {
449 knockout_calculate(ctx, x0, y0, x1, y1, parent);
450 } else {
451 /* we need a maximum of 4 child boxes */
452 if (knockout_box_cur + 4 >= KNOCKOUT_BOXES) {
454 return;
455 }
456
457 /* clip top */
458 if (y1 < ny1) {
467 ny1 = y1;
468 }
469 /* clip bottom */
470 if (y0 > ny0) {
479 ny0 = y0;
480 }
481 /* clip right */
482 if (x1 < nx1) {
491 /* nx1 isn't used again, but if it was it would
492 * need to be updated to x1 here. */
493 }
494 /* clip left */
495 if (x0 > nx0) {
504 /* nx0 isn't used again, but if it was it would
505 * need to be updated to x0 here. */
506 }
507 }
508 }
509}
510
511
512/**
513 * knockout rectangle plotting.
514 *
515 * The rectangle can be filled an outline or both controlled
516 * by the plot style The line can be solid, dotted or
517 * dashed. Top left corner at (x0,y0) and rectangle has given
518 * width and height.
519 *
520 * \param ctx The current redraw context.
521 * \param pstyle Style controlling the rectangle plot.
522 * \param rect A rectangle defining the line to be drawn
523 * \return NSERROR_OK on success else error code.
524 */
525static nserror
527 const plot_style_t *pstyle,
528 const struct rect *rect)
529{
530 int kx0, ky0, kx1, ky1;
531 nserror res = NSERROR_OK;
532
533 if (pstyle->fill_type != PLOT_OP_TYPE_NONE) {
534 /* filled draw */
535
536 /* get our bounds */
537 kx0 = (rect->x0 > clip_cur.x0) ? rect->x0 : clip_cur.x0;
538 ky0 = (rect->y0 > clip_cur.y0) ? rect->y0 : clip_cur.y0;
539 kx1 = (rect->x1 < clip_cur.x1) ? rect->x1 : clip_cur.x1;
540 ky1 = (rect->y1 < clip_cur.y1) ? rect->y1 : clip_cur.y1;
541 if ((kx0 > clip_cur.x1) || (kx1 < clip_cur.x0) ||
542 (ky0 > clip_cur.y1) || (ky1 < clip_cur.y0)) {
543 return NSERROR_OK;
544 }
545
546 /* fills both knock out and get knocked out */
547 knockout_calculate(ctx, kx0, ky0, kx1, ky1, NULL);
560 res = knockout_plot_flush(ctx);
561 }
562 }
563
564 if (pstyle->stroke_type != PLOT_OP_TYPE_NONE) {
565 /* draw outline */
566
569 knockout_entries[knockout_entry_cur].data.fill.plot_style.fill_type = PLOT_OP_TYPE_NONE; /* ensure we only plot the outline */
572 res = knockout_plot_flush(ctx);
573 }
574 }
575 return res;
576}
577
578
579/**
580 * Knockout line plotting.
581 *
582 * plot a line from (x0,y0) to (x1,y1). Coordinates are at
583 * centre of line width/thickness.
584 *
585 * \param ctx The current redraw context.
586 * \param pstyle Style controlling the line plot.
587 * \param line A rectangle defining the line to be drawn
588 * \return NSERROR_OK on success else error code.
589 */
590static nserror
592 const plot_style_t *pstyle,
593 const struct rect *line)
594{
599 return knockout_plot_flush(ctx);
600 }
601 return NSERROR_OK;
602}
603
604
605/**
606 * Knockout polygon plotting.
607 *
608 * Plots a filled polygon with straight lines between
609 * points. The lines around the edge of the ploygon are not
610 * plotted. The polygon is filled with the non-zero winding
611 * rule.
612 *
613 * \param ctx The current redraw context.
614 * \param pstyle Style controlling the polygon plot.
615 * \param p verticies of polygon
616 * \param n number of verticies.
617 * \return NSERROR_OK on success else error code.
618 */
619static nserror
621 const plot_style_t *pstyle,
622 const int *p,
623 unsigned int n)
624{
625 int *dest;
626 nserror res = NSERROR_OK;
627 nserror ffres = NSERROR_OK;
628
629 /* ensure we have sufficient room even when flushed */
630 if (n * 2 >= KNOCKOUT_POLYGONS) {
631 ffres = knockout_plot_flush(ctx);
632 res = real_plot.polygon(ctx, pstyle, p, n);
633 /* return the first error */
634 if ((res != NSERROR_OK) && (ffres == NSERROR_OK)) {
635 ffres = res;
636 }
637 return ffres;
638 }
639
640 /* ensure we have enough room right now */
642 ffres = knockout_plot_flush(ctx);
643 }
644
645 /* copy our data */
647 memcpy(dest, p, n * 2 * sizeof(int));
648 knockout_polygon_cur += n * 2;
654 res = knockout_plot_flush(ctx);
655 }
656 /* return the first error */
657 if ((res != NSERROR_OK) && (ffres == NSERROR_OK)) {
658 ffres = res;
659 }
660 return ffres;
661}
662
663
664/**
665 * knockout path plotting.
666 *
667 * The knockout implementation simply flushes the queue and plots the path
668 * directly using real plotter.
669 *
670 * \param ctx The current redraw context.
671 * \param pstyle Style controlling the path plot.
672 * \param p elements of path
673 * \param n nunber of elements on path
674 * \param transform A transform to apply to the path.
675 * \return NSERROR_OK on success else error code.
676 */
677static nserror
679 const plot_style_t *pstyle,
680 const float *p,
681 unsigned int n,
682 const float transform[6])
683{
684 nserror res;
685 nserror ffres;
686
687 ffres = knockout_plot_flush(ctx);
688 res = real_plot.path(ctx, pstyle, p, n, transform);
689
690 /* return the first error */
691 if ((res != NSERROR_OK) && (ffres == NSERROR_OK)) {
692 ffres = res;
693 }
694 return ffres;
695}
696
697
698static nserror
699knockout_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
700{
701 nserror res = NSERROR_OK;
702
703 if (clip->x1 < clip->x0 || clip->y0 > clip->y1) {
704#ifdef KNOCKOUT_DEBUG
705 NSLOG(netsurf, INFO, "bad clip rectangle %i %i %i %i",
706 clip->x0, clip->y0, clip->x1, clip->y1);
707#endif
708 return NSERROR_BAD_SIZE;
709 }
710
711 /* memorise clip for bitmap tiling */
712 clip_cur = *clip;
713
717 res = knockout_plot_flush(ctx);
718 }
719 return res;
720}
721
722
723/**
724 * Text plotting.
725 *
726 * \param ctx The current redraw context.
727 * \param fstyle plot style for this text
728 * \param x x coordinate
729 * \param y y coordinate
730 * \param text UTF-8 string to plot
731 * \param length length of string, in bytes
732 * \return NSERROR_OK on success else error code.
733 */
734static nserror
736 const plot_font_style_t *fstyle,
737 int x,
738 int y,
739 const char *text,
740 size_t length)
741{
742 nserror res = NSERROR_OK;
743
748 knockout_entries[knockout_entry_cur].data.text.font_style = *fstyle;
751 res = knockout_plot_flush(ctx);
752 }
753 return res;
754}
755
756
757/**
758 * knockout circle plotting
759 *
760 * Plot a circle centered on (x,y), which is optionally filled.
761 *
762 * \param ctx The current redraw context.
763 * \param pstyle Style controlling the circle plot.
764 * \param x x coordinate of circle centre.
765 * \param y y coordinate of circle centre.
766 * \param radius circle radius.
767 * \return NSERROR_OK on success else error code.
768 */
769static nserror
771 const plot_style_t *pstyle,
772 int x,
773 int y,
774 int radius)
775{
776 nserror res = NSERROR_OK;
777
784 res = knockout_plot_flush(ctx);
785 }
786 return res;
787}
788
789
790/**
791 * Plots an arc
792 *
793 * plot an arc segment around (x,y), anticlockwise from angle1
794 * to angle2. Angles are measured anticlockwise from
795 * horizontal, in degrees.
796 *
797 * \param ctx The current redraw context.
798 * \param pstyle Style controlling the arc plot.
799 * \param x The x coordinate of the arc.
800 * \param y The y coordinate of the arc.
801 * \param radius The radius of the arc.
802 * \param angle1 The start angle of the arc.
803 * \param angle2 The finish angle of the arc.
804 * \return NSERROR_OK on success else error code.
805 */
806static nserror
808 const plot_style_t *pstyle,
809 int x,
810 int y,
811 int radius,
812 int angle1,
813 int angle2)
814{
815 nserror res = NSERROR_OK;
816
825 res = knockout_plot_flush(ctx);
826 }
827 return res;
828}
829
830
831/**
832 * knockout bitmap plotting.
833 *
834 * Tiled plot of a bitmap image. (x,y) gives the top left
835 * coordinate of an explicitly placed tile. From this tile the
836 * image can repeat in all four directions -- up, down, left
837 * and right -- to the extents given by the current clip
838 * rectangle.
839 *
840 * The bitmap_flags say whether to tile in the x and y
841 * directions. If not tiling in x or y directions, the single
842 * image is plotted. The width and height give the dimensions
843 * the image is to be scaled to.
844 *
845 * \param ctx The current redraw context.
846 * \param bitmap The bitmap to plot
847 * \param x The x coordinate to plot the bitmap
848 * \param y The y coordiante to plot the bitmap
849 * \param width The width of area to plot the bitmap into
850 * \param height The height of area to plot the bitmap into
851 * \param bg the background colour to alpha blend into
852 * \param flags the flags controlling the type of plot operation
853 * \return NSERROR_OK on success else error code.
854 */
855static nserror
857 struct bitmap *bitmap,
858 int x, int y,
859 int width, int height,
860 colour bg,
861 bitmap_flags_t flags)
862{
863 int kx0, ky0, kx1, ky1;
864 nserror res;
865 nserror ffres = NSERROR_OK;
866
867 /* get our bounds */
868 kx0 = clip_cur.x0;
869 ky0 = clip_cur.y0;
870 kx1 = clip_cur.x1;
871 ky1 = clip_cur.y1;
872 if (!(flags & BITMAPF_REPEAT_X)) {
873 if (x > kx0)
874 kx0 = x;
875 if (x + width < kx1)
876 kx1 = x + width;
877 if ((kx0 > clip_cur.x1) || (kx1 < clip_cur.x0))
878 return NSERROR_OK;
879 }
880 if (!(flags & BITMAPF_REPEAT_Y)) {
881 if (y > ky0)
882 ky0 = y;
883 if (y + height < ky1)
884 ky1 = y + height;
885 if ((ky0 > clip_cur.y1) || (ky1 < clip_cur.y0))
886 return NSERROR_OK;
887 }
888
889 /* tiled bitmaps both knock out and get knocked out */
890 if (guit->bitmap->get_opaque(bitmap)) {
891 knockout_calculate(ctx, kx0, ky0, kx1, ky1, NULL);
892 }
910
913 ffres = knockout_plot_flush(ctx);
914 }
915 res = knockout_plot_clip(ctx, &clip_cur);
916 /* return the first error */
917 if ((res != NSERROR_OK) && (ffres == NSERROR_OK)) {
918 ffres = res;
919 }
920 return ffres;
921}
922
923
924/**
925 * Start of a group of objects.
926 *
927 * Used when plotter implements export to a vector graphics file format.
928 *
929 * \param ctx The current redraw context.
930 * \param name The name of the group being started.
931 * \return NSERROR_OK on success else error code.
932 */
933static nserror
934knockout_plot_group_start(const struct redraw_context *ctx, const char *name)
935{
936 if (real_plot.group_start == NULL) {
937 return NSERROR_OK;
938 }
939
943 return knockout_plot_flush(ctx);
944 }
945 return NSERROR_OK;
946}
947
948
949/**
950 * End a group of objects.
951 *
952 * Used when plotter implements export to a vector graphics file format.
953 *
954 * \param ctx The current redraw context.
955 * \return NSERROR_OK on success else error code.
956 */
958{
959 if (real_plot.group_end == NULL) {
960 return NSERROR_OK;
961 }
962
965 return knockout_plot_flush(ctx);
966 }
967 return NSERROR_OK;
968}
969
970/* exported functions documented in desktop/knockout.h */
971bool knockout_plot_start(const struct redraw_context *ctx,
972 struct redraw_context *knk_ctx)
973{
974 /* check if we're recursing */
975 if (nested_depth++ > 0) {
976 /* we should already have the knockout renderer as default */
977 assert(ctx->plot->rectangle == knockout_plotters.rectangle);
978 *knk_ctx = *ctx;
979 return true;
980 }
981
982 /* end any previous sessions */
983 if (knockout_entry_cur > 0)
985
986 /* get copy of real plotter table */
987 real_plot = *(ctx->plot);
988
989 /* set up knockout rendering context */
990 *knk_ctx = *ctx;
991 knk_ctx->plot = &knockout_plotters;
992 return true;
993}
994
995
996/* exported functions documented in desktop/knockout.h */
997bool knockout_plot_end(const struct redraw_context *ctx)
998{
999 /* only output when we've finished any nesting */
1000 if (--nested_depth == 0) {
1001 return knockout_plot_flush(ctx);
1002 }
1003
1004 assert(nested_depth > 0);
1005 return true;
1006}
1007
1008
1009/**
1010 * knockout plotter operation table
1011 */
1014 .line = knockout_plot_line,
1015 .polygon = knockout_plot_polygon,
1016 .clip = knockout_plot_clip,
1017 .text = knockout_plot_text,
1018 .disc = knockout_plot_disc,
1019 .arc = knockout_plot_arc,
1020 .bitmap = knockout_plot_bitmap,
1021 .group_start = knockout_plot_group_start,
1022 .group_end = knockout_plot_group_end,
1023 .flush = knockout_plot_flush,
1024 .path = knockout_plot_path,
1025 .option_knockout = true,
1026};
Content handling interface.
wimp_w parent
Definition: dialog.c:88
Error codes.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_BAD_SIZE
Bad size.
Definition: errors.h:60
@ NSERROR_OK
No error.
Definition: errors.h:30
const char * type
Definition: filetype.cpp:44
struct netsurf_table * guit
The global interface table.
Definition: gui_factory.c:49
Interface to core interface table.
Generic bitmap handling interface.
Target independent plotting interface.
#define BITMAPF_REPEAT_X
Definition: plotters.h:38
#define BITMAPF_REPEAT_Y
Definition: plotters.h:39
unsigned long bitmap_flags_t
Definition: plotters.h:36
const struct plotter_table knockout_plotters
knockout plotter operation table
Definition: knockout.c:1012
static struct knockout_box knockout_boxes[KNOCKOUT_BOXES]
Definition: knockout.c:173
static nserror knockout_plot_arc(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius, int angle1, int angle2)
Plots an arc.
Definition: knockout.c:807
static nserror knockout_plot_disc(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius)
knockout circle plotting
Definition: knockout.c:770
static void knockout_calculate(const struct redraw_context *ctx, int x0, int y0, int x1, int y1, struct knockout_box *owner)
Knockout a section of previous rendering.
Definition: knockout.c:394
static struct rect clip_cur
Definition: knockout.c:182
static int knockout_polygon_cur
Definition: knockout.c:177
#define KNOCKOUT_BOXES
Definition: knockout.c:84
static nserror knockout_plot_flush(const struct redraw_context *ctx)
Flush the current knockout session to empty the buffers.
Definition: knockout.c:261
static nserror knockout_plot_path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
knockout path plotting.
Definition: knockout.c:678
static int nested_depth
Definition: knockout.c:183
static nserror knockout_plot_group_start(const struct redraw_context *ctx, const char *name)
Start of a group of objects.
Definition: knockout.c:934
static int knockout_box_cur
Definition: knockout.c:176
knockout_type
Definition: knockout.c:90
@ KNOCKOUT_PLOT_CLIP
Definition: knockout.c:95
@ KNOCKOUT_PLOT_DISC
Definition: knockout.c:97
@ KNOCKOUT_PLOT_FILL
Definition: knockout.c:94
@ KNOCKOUT_PLOT_TEXT
Definition: knockout.c:96
@ KNOCKOUT_PLOT_ARC
Definition: knockout.c:98
@ KNOCKOUT_PLOT_GROUP_START
Definition: knockout.c:100
@ KNOCKOUT_PLOT_GROUP_END
Definition: knockout.c:101
@ KNOCKOUT_PLOT_BITMAP
Definition: knockout.c:99
@ KNOCKOUT_PLOT_RECTANGLE
Definition: knockout.c:91
@ KNOCKOUT_PLOT_LINE
Definition: knockout.c:92
@ KNOCKOUT_PLOT_POLYGON
Definition: knockout.c:93
bool knockout_plot_end(const struct redraw_context *ctx)
End a knockout plotting session.
Definition: knockout.c:997
static nserror knockout_plot_fill_recursive(const struct redraw_context *ctx, struct knockout_box *box, plot_style_t *plot_style)
fill an area recursively
Definition: knockout.c:190
static nserror knockout_plot_group_end(const struct redraw_context *ctx)
End a group of objects.
Definition: knockout.c:957
static nserror knockout_plot_line(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *line)
Knockout line plotting.
Definition: knockout.c:591
#define KNOCKOUT_ENTRIES
Definition: knockout.c:83
static int knockout_polygons[KNOCKOUT_POLYGONS]
Definition: knockout.c:174
static nserror knockout_plot_bitmap_recursive(const struct redraw_context *ctx, struct knockout_box *box, struct knockout_entry *entry)
bitmap plot recusivley
Definition: knockout.c:221
static nserror knockout_plot_text(const struct redraw_context *ctx, const plot_font_style_t *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: knockout.c:735
static nserror knockout_plot_polygon(const struct redraw_context *ctx, const plot_style_t *pstyle, const int *p, unsigned int n)
Knockout polygon plotting.
Definition: knockout.c:620
static nserror knockout_plot_rectangle(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *rect)
knockout rectangle plotting.
Definition: knockout.c:526
static struct plotter_table real_plot
Definition: knockout.c:180
static int knockout_entry_cur
Definition: knockout.c:175
bool knockout_plot_start(const struct redraw_context *ctx, struct redraw_context *knk_ctx)
Start a knockout plotting session.
Definition: knockout.c:971
static nserror knockout_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
Definition: knockout.c:699
#define KNOCKOUT_POLYGONS
Definition: knockout.c:85
static nserror knockout_plot_bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
knockout bitmap plotting.
Definition: knockout.c:856
static struct knockout_entry knockout_entries[KNOCKOUT_ENTRIES]
Definition: knockout.c:172
static struct knockout_box * knockout_list
Definition: knockout.c:178
Knockout rendering (interface).
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
@ PLOT_OP_TYPE_NONE
No operation.
Definition: plot_style.h:66
int width
Definition: gui.c:159
int height
Definition: gui.c:160
Interface to utility string handling.
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
int width
width of bitmap
Definition: bitmap.c:69
int height
height of bitmap
Definition: bitmap.c:70
Node in box tree.
Definition: box.h:177
bool(* get_opaque)(void *bitmap)
Get the opacity of a bitmap.
Definition: bitmap.h:159
struct knockout_box * child
Definition: knockout.c:108
struct rect bbox
Definition: knockout.c:106
bool deleted
Definition: knockout.c:107
struct knockout_box * next
Definition: knockout.c:109
Definition: knockout.c:113
struct bitmap * bitmap
Definition: knockout.c:161
int * p
Definition: knockout.c:126
int angle2
Definition: knockout.c:153
size_t length
Definition: knockout.c:139
struct rect r
Definition: knockout.c:118
int radius
Definition: knockout.c:145
struct rect l
Definition: knockout.c:122
int y
Definition: knockout.c:137
struct knockout_entry::@64::@68 fill
colour bg
Definition: knockout.c:162
plot_font_style_t font_style
Definition: knockout.c:140
struct knockout_entry::@64::@73 group_start
struct knockout_entry::@64::@71 arc
struct knockout_entry::@64::@66 line
int width
Definition: knockout.c:159
bitmap_flags_t flags
Definition: knockout.c:163
int height
Definition: knockout.c:160
const char * name
Definition: knockout.c:166
struct knockout_entry::@64::@70 disc
struct rect clip
Definition: knockout.c:134
int angle1
Definition: knockout.c:152
const char * text
Definition: knockout.c:138
struct knockout_box * box
Definition: knockout.c:115
union knockout_entry::@64 data
knockout_type type
Definition: knockout.c:114
int x
Definition: knockout.c:136
unsigned int n
Definition: knockout.c:127
plot_style_t plot_style
Definition: knockout.c:119
struct knockout_entry::@64::@67 polygon
struct knockout_entry::@64::@65 rectangle
struct gui_bitmap_table * bitmap
Bitmap table.
Definition: gui_table.h:144
Font style for plotting.
Definition: plot_style.h:111
Plot style for stroke/fill plotters.
Definition: plot_style.h:76
plot_operation_type_t fill_type
Fill plot type.
Definition: plot_style.h:80
plot_operation_type_t stroke_type
Stroke plot type.
Definition: plot_style.h:77
Plotter operations table.
Definition: plotters.h:102
nserror(* group_start)(const struct redraw_context *ctx, const char *name)
Start of a group of objects.
Definition: plotters.h:295
nserror(* line)(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *line)
Plots a line.
Definition: plotters.h:170
nserror(* polygon)(const struct redraw_context *ctx, const plot_style_t *pstyle, const int *p, unsigned int n)
Plot a polygon.
Definition: plotters.h:207
nserror(* group_end)(const struct redraw_context *ctx)
End of the most recently started group.
Definition: plotters.h:307
nserror(* arc)(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius, int angle1, int angle2)
Plots an arc.
Definition: plotters.h:131
nserror(* text)(const struct redraw_context *ctx, const plot_font_style_t *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plotters.h:278
nserror(* rectangle)(const struct redraw_context *ctx, const plot_style_t *pstyle, const struct rect *rectangle)
Plots a rectangle.
Definition: plotters.h:188
nserror(* clip)(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plotters.h:111
nserror(* path)(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
Definition: plotters.h:226
nserror(* bitmap)(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plotters.h:257
nserror(* disc)(const struct redraw_context *ctx, const plot_style_t *pstyle, int x, int y, int radius)
Plots a circle.
Definition: plotters.h:152
Rectangle coordinates.
Definition: types.h:40
int x0
Definition: types.h:41
int y0
Top left.
Definition: types.h:41
int x1
Definition: types.h:42
int y1
Bottom right.
Definition: types.h:42
Redraw context.
Definition: plotters.h:51
const struct plotter_table * plot
Current plot operation table.
Definition: plotters.h:73
uint32_t colour
Colour type: XBGR.
Definition: types.h:35
struct rect rect
Rectangle coordinates.
Interface to a number of general purpose functionality.
static nserror bitmap(const struct redraw_context *ctx, struct bitmap *bitmap, int x, int y, int width, int height, colour bg, bitmap_flags_t flags)
Plot a bitmap.
Definition: plot.c:857
static nserror line(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *line)
Plots a line.
Definition: plot.c:579
static nserror text(const struct redraw_context *ctx, const struct plot_font_style *fstyle, int x, int y, const char *text, size_t length)
Text plotting.
Definition: plot.c:978
static nserror clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plot.c:357