NetSurf
plotters.c
Go to the documentation of this file.
1/*
2 * Copyright 2006 Rob Kendrick <rjek@rjek.com>
3 * Copyright 2005 James Bursa <bursa@users.sourceforge.net>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * GTK and Cairo plotter implementations.
23 *
24 * Uses Cairo drawing primitives to render browser output.
25 * \todo remove the use of the gdk structure for clipping
26 */
27
28#include <math.h>
29#include <assert.h>
30#include <gdk/gdk.h>
31#include <gtk/gtk.h>
32
33#include "utils/log.h"
34#include "netsurf/plotters.h"
35#include "utils/nsoption.h"
36
37#include "gtk/layout_pango.h"
38#include "gtk/plotters.h"
39#include "gtk/scaffolding.h"
40#include "gtk/bitmap.h"
41
42cairo_t *current_cr;
43
44static GdkRectangle cliprect;
45
46/**
47 * Set cairo context colour to nsgtk colour.
48 *
49 * \param c the netsurf colour to set in cairo
50 */
52{
53 cairo_set_source_rgba(current_cr,
54 (c & 0xff) / 255.0,
55 ((c & 0xff00) >> 8) / 255.0,
56 ((c & 0xff0000) >> 16) / 255.0,
57 1.0);
58}
59
60
61/**
62 * Set cairo context to solid plot operation.
63 */
64static inline void nsgtk_set_solid(void)
65{
66 double dashes = 0;
67 cairo_set_dash(current_cr, &dashes, 0, 0);
68}
69
70
71/**
72 * Set cairo context to dotted plot operation.
73 */
74static inline void nsgtk_set_dotted(void)
75{
76 double cdashes[] = { 1.0, 2.0 };
77 cairo_set_dash(current_cr, cdashes, 2, 0);
78}
79
80
81/**
82 * Set cairo context to dashed plot operation.
83 */
84static inline void nsgtk_set_dashed(void)
85{
86 double cdashes[] = { 8.0, 2.0 };
87 cairo_set_dash(current_cr, cdashes, 2, 0);
88}
89
90
91/**
92 * Set cairo context line width.
93 */
95{
96 if (width == 0) {
97 cairo_set_line_width(current_cr, 1);
98 } else {
99 cairo_set_line_width(current_cr,
101 }
102}
103
104
105/**
106 * \brief Sets a clip rectangle for subsequent plot operations.
107 *
108 * \param ctx The current redraw context.
109 * \param clip The rectangle to limit all subsequent plot
110 * operations within.
111 * \return NSERROR_OK on success else error code.
112 */
113static nserror
114nsgtk_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
115{
116 cairo_reset_clip(current_cr);
117 cairo_rectangle(current_cr, clip->x0, clip->y0,
118 clip->x1 - clip->x0, clip->y1 - clip->y0);
119 cairo_clip(current_cr);
120
121 cliprect.x = clip->x0;
122 cliprect.y = clip->y0;
123 cliprect.width = clip->x1 - clip->x0;
124 cliprect.height = clip->y1 - clip->y0;
125
126 return NSERROR_OK;
127}
128
129
130/**
131 * Plots an arc
132 *
133 * plot an arc segment around (x,y), anticlockwise from angle1
134 * to angle2. Angles are measured anticlockwise from
135 * horizontal, in degrees.
136 *
137 * \param ctx The current redraw context.
138 * \param style Style controlling the arc plot.
139 * \param x The x coordinate of the arc.
140 * \param y The y coordinate of the arc.
141 * \param radius The radius of the arc.
142 * \param angle1 The start angle of the arc.
143 * \param angle2 The finish angle of the arc.
144 * \return NSERROR_OK on success else error code.
145 */
146static nserror
148 const plot_style_t *style,
149 int x, int y, int radius, int angle1, int angle2)
150{
153
154 cairo_set_line_width(current_cr, 1);
155 cairo_arc(current_cr, x, y, radius,
156 (angle1 + 90) * (M_PI / 180),
157 (angle2 + 90) * (M_PI / 180));
158 cairo_stroke(current_cr);
159
160 return NSERROR_OK;
161}
162
163
164/**
165 * Plots a circle
166 *
167 * Plot a circle centered on (x,y), which is optionally filled.
168 *
169 * \param ctx The current redraw context.
170 * \param style Style controlling the circle plot.
171 * \param x x coordinate of circle centre.
172 * \param y y coordinate of circle centre.
173 * \param radius circle radius.
174 * \return NSERROR_OK on success else error code.
175 */
176static nserror
178 const plot_style_t *style,
179 int x, int y, int radius)
180{
181 if (style->fill_type != PLOT_OP_TYPE_NONE) {
184 cairo_set_line_width(current_cr, 0);
185 cairo_arc(current_cr, x, y, radius, 0, M_PI * 2);
186 cairo_fill(current_cr);
187 cairo_stroke(current_cr);
188 }
189
190 if (style->stroke_type != PLOT_OP_TYPE_NONE) {
192
193 switch (style->stroke_type) {
194 case PLOT_OP_TYPE_SOLID: /* Solid colour */
195 default:
197 break;
198
199 case PLOT_OP_TYPE_DOT: /* Doted plot */
201 break;
202
203 case PLOT_OP_TYPE_DASH: /* dashed plot */
205 break;
206 }
207
209
210 cairo_arc(current_cr, x, y, radius, 0, M_PI * 2);
211
212 cairo_stroke(current_cr);
213 }
214
215 return NSERROR_OK;
216}
217
218
219/**
220 * Plots a line
221 *
222 * plot a line from (x0,y0) to (x1,y1). Coordinates are at
223 * centre of line width/thickness.
224 *
225 * \param ctx The current redraw context.
226 * \param style Style controlling the line plot.
227 * \param line A rectangle defining the line to be drawn
228 * \return NSERROR_OK on success else error code.
229 */
230static nserror
232 const plot_style_t *style,
233 const struct rect *line)
234{
236
237 switch (style->stroke_type) {
238 case PLOT_OP_TYPE_SOLID: /* Solid colour */
239 default:
241 break;
242
243 case PLOT_OP_TYPE_DOT: /* Doted plot */
245 break;
246
247 case PLOT_OP_TYPE_DASH: /* dashed plot */
249 break;
250 }
251
252 if (style->stroke_type != PLOT_OP_TYPE_NONE) {
254 }
255
257
258 /* core expects horizontal and vertical lines to be on pixels, not
259 * between pixels
260 */
261 cairo_move_to(current_cr,
262 (line->x0 == line->x1) ? line->x0 + 0.5 : line->x0,
263 (line->y0 == line->y1) ? line->y0 + 0.5 : line->y0);
264 cairo_line_to(current_cr,
265 (line->x0 == line->x1) ? line->x1 + 0.5 : line->x1,
266 (line->y0 == line->y1) ? line->y1 + 0.5 : line->y1);
267 cairo_stroke(current_cr);
268
269 return NSERROR_OK;
270}
271
272
273/**
274 * Plot a caret.
275 *
276 * @note It is assumed that the plotters have been set up.
277 */
278void nsgtk_plot_caret(int x, int y, int h)
279{
280 nsgtk_set_solid(); /* solid line */
281 nsgtk_set_colour(0); /* black */
282 cairo_set_line_width(current_cr, 1); /* thin line */
283
284 /* core expects horizontal and vertical lines to be on pixels, not
285 * between pixels */
286 cairo_move_to(current_cr, x + 0.5, y);
287 cairo_line_to(current_cr, x + 0.5, y + h - 1);
288 cairo_stroke(current_cr);
289}
290
291
292/**
293 * Plots a rectangle.
294 *
295 * The rectangle can be filled an outline or both controlled
296 * by the plot style The line can be solid, dotted or
297 * dashed. Top left corner at (x0,y0) and rectangle has given
298 * width and height.
299 *
300 * \param ctx The current redraw context.
301 * \param style Style controlling the rectangle plot.
302 * \param rect A rectangle defining the line to be drawn
303 * \return NSERROR_OK on success else error code.
304 */
305static nserror
307 const plot_style_t *style,
308 const struct rect *rect)
309{
310 if (style->fill_type != PLOT_OP_TYPE_NONE) {
313
314 cairo_set_line_width(current_cr, 0);
315 cairo_rectangle(current_cr,
316 rect->x0,
317 rect->y0,
318 rect->x1 - rect->x0,
319 rect->y1 - rect->y0);
320 cairo_fill(current_cr);
321 cairo_stroke(current_cr);
322 }
323
324 if (style->stroke_type != PLOT_OP_TYPE_NONE) {
326
327 switch (style->stroke_type) {
328 case PLOT_OP_TYPE_SOLID: /* Solid colour */
329 default:
331 break;
332
333 case PLOT_OP_TYPE_DOT: /* Doted plot */
335 break;
336
337 case PLOT_OP_TYPE_DASH: /* dashed plot */
339 break;
340 }
341
343
344 cairo_rectangle(current_cr,
345 rect->x0 + 0.5,
346 rect->y0 + 0.5,
347 rect->x1 - rect->x0,
348 rect->y1 - rect->y0);
349 cairo_stroke(current_cr);
350 }
351 return NSERROR_OK;
352}
353
354
355/**
356 * Plot a polygon
357 *
358 * Plots a filled polygon with straight lines between
359 * points. The lines around the edge of the ploygon are not
360 * plotted. The polygon is filled with the non-zero winding
361 * rule.
362 *
363 * \param ctx The current redraw context.
364 * \param style Style controlling the polygon plot.
365 * \param p verticies of polygon
366 * \param n number of verticies.
367 * \return NSERROR_OK on success else error code.
368 */
369static nserror
371 const plot_style_t *style,
372 const int *p,
373 unsigned int n)
374{
375 unsigned int i;
376
379
380 cairo_set_line_width(current_cr, 0);
381 cairo_move_to(current_cr, p[0], p[1]);
382 for (i = 1; i != n; i++) {
383 cairo_line_to(current_cr, p[i * 2], p[i * 2 + 1]);
384 }
385 cairo_fill(current_cr);
386 cairo_stroke(current_cr);
387
388 return NSERROR_OK;
389}
390
391
392/**
393 * Plots a path.
394 *
395 * Path plot consisting of cubic Bezier curves. Line and fill colour is
396 * controlled by the plot style.
397 *
398 * The transform to apply is affine (meaning it omits the three
399 * projection factor parameters from the standard 3x3 matrix assumining
400 * default values)
401 *
402 * +--------------+--------------+--------------+
403 * | transform[0] | transform[1] | 0.0 |
404 * +--------------+--------------+--------------+
405 * | transform[2] | transform[3] | 0.0 |
406 * +--------------+--------------+--------------+
407 * | transform[4] | transform[5] | 1.0 |
408 * +--------------+--------------+--------------+
409 *
410 * \param ctx The current redraw context.
411 * \param pstyle Style controlling the path plot.
412 * \param p elements of path
413 * \param n nunber of elements on path
414 * \param transform A transform to apply to the path.
415 * \return NSERROR_OK on success else error code.
416 */
417static nserror
419 const plot_style_t *pstyle,
420 const float *p,
421 unsigned int n,
422 const float transform[6])
423{
424 unsigned int i;
425 cairo_matrix_t old_ctm, n_ctm;
426
427 if (n == 0)
428 return NSERROR_OK;
429
430 if (p[0] != PLOTTER_PATH_MOVE) {
431 NSLOG(netsurf, INFO, "Path does not start with move");
432 return NSERROR_INVALID;
433 }
434
435 /* Save CTM */
436 cairo_get_matrix(current_cr, &old_ctm);
437
438 /* Set up line style and width */
441
442 /* Load new CTM */
443 n_ctm.xx = transform[0];
444 n_ctm.yx = transform[1];
445 n_ctm.xy = transform[2];
446 n_ctm.yy = transform[3];
447 n_ctm.x0 = transform[4] + old_ctm.x0;
448 n_ctm.y0 = transform[5] + old_ctm.y0;
449
450 cairo_set_matrix(current_cr, &n_ctm);
451
452 /* Construct path */
453 for (i = 0; i < n; ) {
454 if (p[i] == PLOTTER_PATH_MOVE) {
455 cairo_move_to(current_cr, p[i+1], p[i+2]);
456 i += 3;
457 } else if (p[i] == PLOTTER_PATH_CLOSE) {
458 cairo_close_path(current_cr);
459 i++;
460 } else if (p[i] == PLOTTER_PATH_LINE) {
461 cairo_line_to(current_cr, p[i+1], p[i+2]);
462 i += 3;
463 } else if (p[i] == PLOTTER_PATH_BEZIER) {
464 cairo_curve_to(current_cr, p[i+1], p[i+2],
465 p[i+3], p[i+4],
466 p[i+5], p[i+6]);
467 i += 7;
468 } else {
469 NSLOG(netsurf, INFO, "bad path command %f", p[i]);
470 /* Reset matrix for safety */
471 cairo_set_matrix(current_cr, &old_ctm);
472 return NSERROR_INVALID;
473 }
474 }
475
476 /* Restore original CTM */
477 cairo_set_matrix(current_cr, &old_ctm);
478
479 /* Now draw path */
480 if (pstyle->fill_colour != NS_TRANSPARENT) {
482
483 if (pstyle->stroke_colour != NS_TRANSPARENT) {
484 /* Fill & Stroke */
485 cairo_fill_preserve(current_cr);
487 cairo_stroke(current_cr);
488 } else {
489 /* Fill only */
490 cairo_fill(current_cr);
491 }
492 } else if (pstyle->stroke_colour != NS_TRANSPARENT) {
493 /* Stroke only */
495 cairo_stroke(current_cr);
496 }
497
498 return NSERROR_OK;
499}
500
501
502/**
503 * Plot a bitmap
504 *
505 * Tiled plot of a bitmap image. (x,y) gives the top left
506 * coordinate of an explicitly placed tile. From this tile the
507 * image can repeat in all four directions -- up, down, left
508 * and right -- to the extents given by the current clip
509 * rectangle.
510 *
511 * The bitmap_flags say whether to tile in the x and y
512 * directions. If not tiling in x or y directions, the single
513 * image is plotted. The width and height give the dimensions
514 * the image is to be scaled to.
515 *
516 * \param ctx The current redraw context.
517 * \param bitmap The bitmap to plot
518 * \param x The x coordinate to plot the bitmap
519 * \param y The y coordiante to plot the bitmap
520 * \param width The width of area to plot the bitmap into
521 * \param height The height of area to plot the bitmap into
522 * \param bg the background colour to alpha blend into
523 * \param flags the flags controlling the type of plot operation
524 * \return NSERROR_OK on success else error code.
525 */
526static nserror
528 struct bitmap *bitmap,
529 int x, int y,
530 int width,
531 int height,
532 colour bg,
533 bitmap_flags_t flags)
534{
535 bool repeat_x = (flags & BITMAPF_REPEAT_X);
536 bool repeat_y = (flags & BITMAPF_REPEAT_Y);
537 GdkRectangle cliprect_bitmap;
538 cairo_surface_t *img_surface;
539 int img_width, img_height;
540
541 /* Bail early if we can */
542 if (width <= 0 || height <= 0) {
543 /* Nothing to plot */
544 return NSERROR_OK;
545 }
546
547 /* Copy the clip rectangle into bitmap plot clip rectangle */
548 cliprect_bitmap = cliprect;
549
550 /* Constrain bitmap plot rectangle for any lack of tiling */
551 if (!repeat_x) {
552 if (cliprect_bitmap.width > width) {
553 cliprect_bitmap.width = width;
554 }
555 if (cliprect_bitmap.x < x) {
556 cliprect_bitmap.x = x;
557 cliprect_bitmap.width -= x - cliprect_bitmap.x;
558 }
559 }
560 if (!repeat_y) {
561 if (cliprect_bitmap.height > height) {
562 cliprect_bitmap.height = height;
563 }
564 if (cliprect_bitmap.y < y) {
565 cliprect_bitmap.y = y;
566 cliprect_bitmap.height -= y - cliprect_bitmap.y;
567 }
568 }
569
570 /* Bail early if we can */
571 if (cliprect_bitmap.width <= 0 || cliprect_bitmap.height <= 0) {
572 /* Nothing to plot */
573 return NSERROR_OK;
574 }
575
576 /* Get the image's surface and intrinsic dimensions */
577 img_surface = bitmap->surface;
578 img_width = cairo_image_surface_get_width(img_surface);
579 img_height = cairo_image_surface_get_height(img_surface);
580
581 /* Set the source surface */
582 if ((img_width == width) && (img_height == height)) {
583 /* Non-scaled rendering */
584 cairo_set_source_surface(current_cr, img_surface, x, y);
585
586 /* Enable tiling if we're repeating */
587 if (repeat_x || repeat_y) {
588 cairo_pattern_set_extend(
589 cairo_get_source(current_cr),
590 CAIRO_EXTEND_REPEAT);
591 }
592
593 /* Render the bitmap */
594 cairo_rectangle(current_cr,
595 cliprect_bitmap.x,
596 cliprect_bitmap.y,
597 cliprect_bitmap.width,
598 cliprect_bitmap.height);
599 cairo_fill(current_cr);
600 } else {
601 /* Scaled rendering */
602 double scale_x = (double)width / img_width;
603 double scale_y = (double)height / img_height;
604
605 /* Save cairo rendering context state before scaling */
606 cairo_save(current_cr);
607 cairo_scale(current_cr, scale_x, scale_y);
608
609 cairo_set_source_surface(current_cr, img_surface,
610 x / scale_x, y / scale_y);
611
612 /* Enable tiling if we're repeating */
613 if (repeat_x || repeat_y) {
614 cairo_pattern_set_extend(
615 cairo_get_source(current_cr),
616 CAIRO_EXTEND_REPEAT);
617 }
618
619 /* Render the bitmap */
620 cairo_rectangle(current_cr,
621 cliprect_bitmap.x / scale_x,
622 cliprect_bitmap.y / scale_y,
623 cliprect_bitmap.width / scale_x,
624 cliprect_bitmap.height / scale_y);
625 cairo_fill(current_cr);
626
627 /* Restore pre-scaling cairo rendering state */
628 cairo_restore(current_cr);
629 }
630
631 return NSERROR_OK;
632}
633
634
635/**
636 * Text plotting.
637 *
638 * \param ctx The current redraw context.
639 * \param fstyle plot style for this text
640 * \param x x coordinate
641 * \param y y coordinate
642 * \param text UTF-8 string to plot
643 * \param length length of string, in bytes
644 * \return NSERROR_OK on success else error code.
645 */
646static nserror
648 const struct plot_font_style *fstyle,
649 int x,
650 int y,
651 const char *text,
652 size_t length)
653{
654 return nsfont_paint(x, y, text, length, fstyle);
655}
656
657
658/** GTK plotter table */
661 .arc = nsgtk_plot_arc,
662 .disc = nsgtk_plot_disc,
663 .line = nsgtk_plot_line,
664 .rectangle = nsgtk_plot_rectangle,
665 .polygon = nsgtk_plot_polygon,
666 .path = nsgtk_plot_path,
667 .bitmap = nsgtk_plot_bitmap,
668 .text = nsgtk_plot_text,
669 .option_knockout = true
670};
#define M_PI
Definition: plotters.c:97
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_INVALID
Invalid data.
Definition: errors.h:49
@ NSERROR_OK
No error.
Definition: errors.h:30
bool nsfont_paint(const plot_font_style_t *fstyle, const char *string, size_t length, int x, int y)
Render a string.
Definition: font.cpp:315
Target independent plotting GTK+ interface.
static GdkRectangle cliprect
Definition: plotters.c:44
static nserror nsgtk_plot_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: plotters.c:647
const struct plotter_table nsgtk_plotters
GTK plotter table.
Definition: plotters.c:659
void nsgtk_plot_caret(int x, int y, int h)
Plot a caret.
Definition: plotters.c:278
static nserror nsgtk_plot_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.c:418
void nsgtk_set_colour(colour c)
Set cairo context colour to nsgtk colour.
Definition: plotters.c:51
static nserror nsgtk_plot_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.c:527
static nserror nsgtk_plot_arc(const struct redraw_context *ctx, const plot_style_t *style, int x, int y, int radius, int angle1, int angle2)
Plots an arc.
Definition: plotters.c:147
static void nsgtk_set_dotted(void)
Set cairo context to dotted plot operation.
Definition: plotters.c:74
static nserror nsgtk_plot_line(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *line)
Plots a line.
Definition: plotters.c:231
static nserror nsgtk_plot_polygon(const struct redraw_context *ctx, const plot_style_t *style, const int *p, unsigned int n)
Plot a polygon.
Definition: plotters.c:370
static nserror nsgtk_plot_disc(const struct redraw_context *ctx, const plot_style_t *style, int x, int y, int radius)
Plots a circle.
Definition: plotters.c:177
static nserror nsgtk_plot_rectangle(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *rect)
Plots a rectangle.
Definition: plotters.c:306
static void nsgtk_set_solid(void)
Set cairo context to solid plot operation.
Definition: plotters.c:64
cairo_t * current_cr
Definition: plotters.c:42
static nserror nsgtk_plot_clip(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plotters.c:114
static void nsgtk_set_dashed(void)
Set cairo context to dashed plot operation.
Definition: plotters.c:84
static void nsgtk_set_line_width(plot_style_fixed width)
Set cairo context line width.
Definition: plotters.c:94
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
@ PLOTTER_PATH_MOVE
Definition: plotters.h:42
@ PLOTTER_PATH_CLOSE
Definition: plotters.h:43
@ PLOTTER_PATH_LINE
Definition: plotters.h:44
@ PLOTTER_PATH_BEZIER
Definition: plotters.h:45
Interface to GTK layout handling using pango.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
#define plot_style_fixed_to_double(v)
Definition: plot_style.h:60
int32_t plot_style_fixed
Definition: plot_style.h:48
@ PLOT_OP_TYPE_NONE
No operation.
Definition: plot_style.h:66
@ PLOT_OP_TYPE_DASH
Dashed plot.
Definition: plot_style.h:69
@ PLOT_OP_TYPE_DOT
Dotted plot.
Definition: plot_style.h:68
@ PLOT_OP_TYPE_SOLID
Solid colour.
Definition: plot_style.h:67
#define NS_TRANSPARENT
Transparent colour value.
Definition: plot_style.h:39
int width
Definition: gui.c:161
int height
Definition: gui.c:162
RISC OS wimp toolkit bitmap.
Definition: bitmap.c:68
cairo_surface_t * surface
Definition: bitmap.h:27
Font style for plotting.
Definition: plot_style.h:111
Plot style for stroke/fill plotters.
Definition: plot_style.h:76
colour fill_colour
Colour of fill.
Definition: plot_style.h:81
plot_style_fixed stroke_width
Width of stroke, in pixels.
Definition: plot_style.h:78
plot_operation_type_t fill_type
Fill plot type.
Definition: plot_style.h:80
colour stroke_colour
Colour of stroke.
Definition: plot_style.h:79
plot_operation_type_t stroke_type
Stroke plot type.
Definition: plot_style.h:77
Plotter operations table.
Definition: plotters.h:102
nserror(* clip)(const struct redraw_context *ctx, const struct rect *clip)
Sets a clip rectangle for subsequent plot operations.
Definition: plotters.h:111
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
uint32_t colour
Colour type: XBGR.
Definition: types.h:35
Option reading and saving interface.
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