1 /* $Id: plotctx.c,v 1.6 2015/07/06 08:05:44 kristaps Exp $ */
2 /*
3 * Copyright (c) 2014 Kristaps Dzonsons <kristaps@bsd.lv>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 #include "compat.h"
18
19 #include <assert.h>
20 #include <cairo.h>
21 #include <float.h>
22 #include <math.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #include "kplot.h"
27 #include "extern.h"
28
29 static void
kplotctx_ccfg_init(struct kplotctx * ctx,struct kplotccfg * cfg)30 kplotctx_ccfg_init(struct kplotctx *ctx, struct kplotccfg *cfg)
31 {
32
33 switch (cfg->type) {
34 case (KPLOTCTYPE_PALETTE):
35 cairo_set_source_rgba(ctx->cr,
36 ctx->cfg.clrs[cfg->palette % ctx->cfg.clrsz].rgba[0],
37 ctx->cfg.clrs[cfg->palette % ctx->cfg.clrsz].rgba[1],
38 ctx->cfg.clrs[cfg->palette % ctx->cfg.clrsz].rgba[2],
39 ctx->cfg.clrs[cfg->palette % ctx->cfg.clrsz].rgba[3]);
40 break;
41 case (KPLOTCTYPE_PATTERN):
42 cairo_set_source(ctx->cr, cfg->pattern);
43 break;
44 case (KPLOTCTYPE_RGBA):
45 cairo_set_source_rgba(ctx->cr, cfg->rgba[0],
46 cfg->rgba[1], cfg->rgba[2], cfg->rgba[3]);
47 break;
48 default:
49 abort();
50 }
51 }
52
53 void
kplotctx_ticln_init(struct kplotctx * ctx,struct kplotticln * line)54 kplotctx_ticln_init(struct kplotctx *ctx, struct kplotticln *line)
55 {
56
57 kplotctx_ccfg_init(ctx, &line->clr);
58 cairo_set_line_width(ctx->cr, line->sz);
59 cairo_set_dash(ctx->cr, line->dashes,
60 line->dashesz, line->dashoff);
61 }
62
63 void
kplotctx_font_init(struct kplotctx * ctx,struct kplotfont * font)64 kplotctx_font_init(struct kplotctx *ctx, struct kplotfont *font)
65 {
66
67 kplotctx_ccfg_init(ctx, &font->clr);
68 cairo_select_font_face
69 (ctx->cr, font->family,
70 font->slant,
71 font->weight);
72 cairo_set_font_size(ctx->cr, font->sz);
73 }
74
75 void
kplotctx_point_init(struct kplotctx * ctx,struct kplotpoint * pnt)76 kplotctx_point_init(struct kplotctx *ctx, struct kplotpoint *pnt)
77 {
78
79 kplotctx_ccfg_init(ctx, &pnt->clr);
80 cairo_set_line_width(ctx->cr, pnt->sz);
81 cairo_set_dash(ctx->cr, pnt->dashes,
82 pnt->dashesz, pnt->dashoff);
83 }
84
85 void
kplotctx_line_init(struct kplotctx * ctx,struct kplotline * line)86 kplotctx_line_init(struct kplotctx *ctx, struct kplotline *line)
87 {
88
89 kplotctx_ccfg_init(ctx, &line->clr);
90 cairo_set_line_width(ctx->cr, line->sz);
91 cairo_set_dash(ctx->cr, line->dashes,
92 line->dashesz, line->dashoff);
93 cairo_set_line_join(ctx->cr, line->join);
94 }
95
96 /*
97 * Given a plotting context and a position for drawing a line, determine
98 * whether we want to "fix" the line so that it's fine.
99 * This is a foible of Cairo and drawing with doubles.
100 */
101 double
kplotctx_line_fix(const struct kplotctx * ctx,double sz,double pos)102 kplotctx_line_fix(const struct kplotctx *ctx, double sz, double pos)
103 {
104 double v;
105
106 if (0 == (int)sz % 2)
107 return(pos);
108 v = pos - floor(pos);
109 return(v < DBL_EPSILON ? pos + 0.5 : pos - v + 0.5);
110 }
111