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 * \param ctx The current redraw context.
399 * \param pstyle Style controlling the path plot.
400 * \param p elements of path
401 * \param n nunber of elements on path
402 * \param transform A transform to apply to the path.
403 * \return NSERROR_OK on success else error code.
404 */
405static nserror
407 const plot_style_t *pstyle,
408 const float *p,
409 unsigned int n,
410 const float transform[6])
411{
412 unsigned int i;
413 cairo_matrix_t old_ctm, n_ctm;
414
415 if (n == 0)
416 return NSERROR_OK;
417
418 if (p[0] != PLOTTER_PATH_MOVE) {
419 NSLOG(netsurf, INFO, "Path does not start with move");
420 return NSERROR_INVALID;
421 }
422
423 /* Save CTM */
424 cairo_get_matrix(current_cr, &old_ctm);
425
426 /* Set up line style and width */
429
430 /* Load new CTM */
431 n_ctm.xx = transform[0];
432 n_ctm.yx = transform[1];
433 n_ctm.xy = transform[2];
434 n_ctm.yy = transform[3];
435 n_ctm.x0 = transform[4] + old_ctm.x0;
436 n_ctm.y0 = transform[5] + old_ctm.y0;
437
438 cairo_set_matrix(current_cr, &n_ctm);
439
440 /* Construct path */
441 for (i = 0; i < n; ) {
442 if (p[i] == PLOTTER_PATH_MOVE) {
443 cairo_move_to(current_cr, p[i+1], p[i+2]);
444 i += 3;
445 } else if (p[i] == PLOTTER_PATH_CLOSE) {
446 cairo_close_path(current_cr);
447 i++;
448 } else if (p[i] == PLOTTER_PATH_LINE) {
449 cairo_line_to(current_cr, p[i+1], p[i+2]);
450 i += 3;
451 } else if (p[i] == PLOTTER_PATH_BEZIER) {
452 cairo_curve_to(current_cr, p[i+1], p[i+2],
453 p[i+3], p[i+4],
454 p[i+5], p[i+6]);
455 i += 7;
456 } else {
457 NSLOG(netsurf, INFO, "bad path command %f", p[i]);
458 /* Reset matrix for safety */
459 cairo_set_matrix(current_cr, &old_ctm);
460 return NSERROR_INVALID;
461 }
462 }
463
464 /* Restore original CTM */
465 cairo_set_matrix(current_cr, &old_ctm);
466
467 /* Now draw path */
468 if (pstyle->fill_colour != NS_TRANSPARENT) {
470
471 if (pstyle->stroke_colour != NS_TRANSPARENT) {
472 /* Fill & Stroke */
473 cairo_fill_preserve(current_cr);
475 cairo_stroke(current_cr);
476 } else {
477 /* Fill only */
478 cairo_fill(current_cr);
479 }
480 } else if (pstyle->stroke_colour != NS_TRANSPARENT) {
481 /* Stroke only */
483 cairo_stroke(current_cr);
484 }
485
486 return NSERROR_OK;
487}
488
489
490/**
491 * Plot a bitmap
492 *
493 * Tiled plot of a bitmap image. (x,y) gives the top left
494 * coordinate of an explicitly placed tile. From this tile the
495 * image can repeat in all four directions -- up, down, left
496 * and right -- to the extents given by the current clip
497 * rectangle.
498 *
499 * The bitmap_flags say whether to tile in the x and y
500 * directions. If not tiling in x or y directions, the single
501 * image is plotted. The width and height give the dimensions
502 * the image is to be scaled to.
503 *
504 * \param ctx The current redraw context.
505 * \param bitmap The bitmap to plot
506 * \param x The x coordinate to plot the bitmap
507 * \param y The y coordiante to plot the bitmap
508 * \param width The width of area to plot the bitmap into
509 * \param height The height of area to plot the bitmap into
510 * \param bg the background colour to alpha blend into
511 * \param flags the flags controlling the type of plot operation
512 * \return NSERROR_OK on success else error code.
513 */
514static nserror
516 struct bitmap *bitmap,
517 int x, int y,
518 int width,
519 int height,
520 colour bg,
521 bitmap_flags_t flags)
522{
523 bool repeat_x = (flags & BITMAPF_REPEAT_X);
524 bool repeat_y = (flags & BITMAPF_REPEAT_Y);
525 GdkRectangle cliprect_bitmap;
526 cairo_surface_t *img_surface;
527 int img_width, img_height;
528
529 /* Bail early if we can */
530 if (width <= 0 || height <= 0) {
531 /* Nothing to plot */
532 return NSERROR_OK;
533 }
534
535 /* Copy the clip rectangle into bitmap plot clip rectangle */
536 cliprect_bitmap = cliprect;
537
538 /* Constrain bitmap plot rectangle for any lack of tiling */
539 if (!repeat_x) {
540 if (cliprect_bitmap.width > width) {
541 cliprect_bitmap.width = width;
542 }
543 if (cliprect_bitmap.x < x) {
544 cliprect_bitmap.x = x;
545 cliprect_bitmap.width -= x - cliprect_bitmap.x;
546 }
547 }
548 if (!repeat_y) {
549 if (cliprect_bitmap.height > height) {
550 cliprect_bitmap.height = height;
551 }
552 if (cliprect_bitmap.y < y) {
553 cliprect_bitmap.y = y;
554 cliprect_bitmap.height -= y - cliprect_bitmap.y;
555 }
556 }
557
558 /* Bail early if we can */
559 if (cliprect_bitmap.width <= 0 || cliprect_bitmap.height <= 0) {
560 /* Nothing to plot */
561 return NSERROR_OK;
562 }
563
564 /* Get the image's surface and intrinsic dimensions */
565 img_surface = bitmap->surface;
566 img_width = cairo_image_surface_get_width(img_surface);
567 img_height = cairo_image_surface_get_height(img_surface);
568
569 /* Set the source surface */
570 if ((img_width == width) && (img_height == height)) {
571 /* Non-scaled rendering */
572 cairo_set_source_surface(current_cr, img_surface, x, y);
573
574 /* Enable tiling if we're repeating */
575 if (repeat_x || repeat_y) {
576 cairo_pattern_set_extend(
577 cairo_get_source(current_cr),
578 CAIRO_EXTEND_REPEAT);
579 }
580
581 /* Render the bitmap */
582 cairo_rectangle(current_cr,
583 cliprect_bitmap.x,
584 cliprect_bitmap.y,
585 cliprect_bitmap.width,
586 cliprect_bitmap.height);
587 cairo_fill(current_cr);
588 } else {
589 /* Scaled rendering */
590 double scale_x = (double)width / img_width;
591 double scale_y = (double)height / img_height;
592
593 /* Save cairo rendering context state before scaling */
594 cairo_save(current_cr);
595 cairo_scale(current_cr, scale_x, scale_y);
596
597 cairo_set_source_surface(current_cr, img_surface,
598 x / scale_x, y / scale_y);
599
600 /* Enable tiling if we're repeating */
601 if (repeat_x || repeat_y) {
602 cairo_pattern_set_extend(
603 cairo_get_source(current_cr),
604 CAIRO_EXTEND_REPEAT);
605 }
606
607 /* Render the bitmap */
608 cairo_rectangle(current_cr,
609 cliprect_bitmap.x / scale_x,
610 cliprect_bitmap.y / scale_y,
611 cliprect_bitmap.width / scale_x,
612 cliprect_bitmap.height / scale_y);
613 cairo_fill(current_cr);
614
615 /* Restore pre-scaling cairo rendering state */
616 cairo_restore(current_cr);
617 }
618
619 return NSERROR_OK;
620}
621
622
623/**
624 * Text plotting.
625 *
626 * \param ctx The current redraw context.
627 * \param fstyle plot style for this text
628 * \param x x coordinate
629 * \param y y coordinate
630 * \param text UTF-8 string to plot
631 * \param length length of string, in bytes
632 * \return NSERROR_OK on success else error code.
633 */
634static nserror
636 const struct plot_font_style *fstyle,
637 int x,
638 int y,
639 const char *text,
640 size_t length)
641{
642 return nsfont_paint(x, y, text, length, fstyle);
643}
644
645
646/** GTK plotter table */
649 .arc = nsgtk_plot_arc,
650 .disc = nsgtk_plot_disc,
651 .line = nsgtk_plot_line,
652 .rectangle = nsgtk_plot_rectangle,
653 .polygon = nsgtk_plot_polygon,
654 .path = nsgtk_plot_path,
655 .bitmap = nsgtk_plot_bitmap,
656 .text = nsgtk_plot_text,
657 .option_knockout = true
658};
#define M_PI
Definition: plotters.c:101
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:312
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:635
const struct plotter_table nsgtk_plotters
GTK plotter table.
Definition: plotters.c:647
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:406
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:515
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:160
int height
Definition: gui.c:161
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