2 * A few useful drawing funcitons
3 * Copyright (C) 2007-2015 Krzysztof Foltman, Torben Hohn, Markus Schmidt
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program 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 GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
22 #include "calf/drawingutils.h"
27 void display_background(GtkWidget
*widget
, cairo_t
* c
, int x
, int y
, int sx
, int sy
, int ox
, int oy
, float brightness
, int shadow
, float lights
, float dull
)
29 float br
= brightness
* 0.5 + 0.5;
32 GdkWindow
*window
= widget
->window
;
33 c
= gdk_cairo_create(GDK_DRAWABLE(window
));
36 // outer frame (black)
40 //c, pad + x, pad + y, sx + ox * 2 - pad * 2, sy + oy * 2 - pad * 2);
41 //cairo_set_source_rgb(c, 0, 0, 0);
46 get_bg_color(widget
, NULL
, &r
, &g
, &b
);
50 c
, pad
+ x
, pad
+ y
, sx
+ ox
* 2 - pad
* 2, sy
+ oy
* 2 - pad
* 2, 0);
51 cairo_pattern_t
*pat2
= cairo_pattern_create_linear (
52 x
, y
, x
, y
+ sy
+ oy
* 2 - pad
* 2);
53 cairo_pattern_add_color_stop_rgba (pat2
, 0, r
*1.111, g
*1.111, b
*1.111, 1);
54 cairo_pattern_add_color_stop_rgba (pat2
, 1, r
*0.82, g
*0.82, b
*0.82, 1);
55 //cairo_pattern_add_color_stop_rgba (pat2, 0.33, 0.05, 0.05, 0.05, 1);
56 //cairo_pattern_add_color_stop_rgba (pat2, 0.5, 0, 0, 0, 1);
57 cairo_set_source (c
, pat2
);
59 cairo_pattern_destroy(pat2
);
61 //cairo_rectangle(c, x + ox - 1, y + oy - 1, sx + 2, sy + 2);
62 //cairo_set_source_rgb (c, 0, 0, 0);
65 // inner yellowish screen
66 get_base_color(widget
, NULL
, &r
, &g
, &b
);
67 cairo_pattern_t
*pt
= cairo_pattern_create_linear(x
+ ox
, y
+ oy
, x
+ ox
, y
+ sy
);
68 cairo_pattern_add_color_stop_rgb(pt
, 0.0, br
* r
* 0.75, br
* g
* 0.75, br
* b
* 0.75);
69 cairo_pattern_add_color_stop_rgb(pt
, 1.0, br
* r
, br
* g
, br
* b
);
70 cairo_set_source (c
, pt
);
71 cairo_rectangle(c
, x
+ ox
, y
+ oy
, sx
, sy
);
73 cairo_pattern_destroy(pt
);
77 pt
= cairo_pattern_create_linear(x
+ ox
, y
+ oy
, x
+ ox
, y
+ oy
+ shadow
);
78 cairo_pattern_add_color_stop_rgba(pt
, 0.0, 0,0,0,0.6);
79 cairo_pattern_add_color_stop_rgba(pt
, 1.0, 0,0,0,0);
80 cairo_set_source (c
, pt
);
81 cairo_rectangle(c
, x
+ ox
, y
+ oy
, sx
, shadow
);
83 cairo_pattern_destroy(pt
);
86 pt
= cairo_pattern_create_linear(x
+ ox
, y
+ oy
, x
+ ox
+ (float)shadow
* 0.7, y
+ oy
);
87 cairo_pattern_add_color_stop_rgba(pt
, 0.0, 0,0,0,0.3);
88 cairo_pattern_add_color_stop_rgba(pt
, 1.0, 0,0,0,0);
89 cairo_set_source (c
, pt
);
90 cairo_rectangle(c
, x
+ ox
, y
+ oy
, (float)shadow
* 0.7, sy
);
92 cairo_pattern_destroy(pt
);
95 pt
= cairo_pattern_create_linear(x
+ ox
+ sx
- (float)shadow
* 0.7, y
+ oy
, x
+ ox
+ sx
, y
+ oy
);
96 cairo_pattern_add_color_stop_rgba(pt
, 0.0, 0,0,0,0);
97 cairo_pattern_add_color_stop_rgba(pt
, 1.0, 0,0,0,0.3);
98 cairo_set_source (c
, pt
);
99 cairo_rectangle(c
, x
+ ox
+ sx
- (float)shadow
* 0.7, y
+ oy
, (float)shadow
* 0.7, sy
);
101 cairo_pattern_destroy(pt
);
106 pt
= cairo_pattern_create_linear(x
+ ox
, y
+ oy
, x
+ ox
+ sx
/ 2, y
+ oy
);
107 cairo_pattern_add_color_stop_rgba(pt
, 0.0, 0,0,0,dull
);
108 cairo_pattern_add_color_stop_rgba(pt
, 1.0, 0,0,0,0);
109 cairo_set_source (c
, pt
);
110 cairo_rectangle(c
, x
+ ox
, y
+ oy
, sx
/ 2, sy
);
112 cairo_pattern_destroy(pt
);
115 pt
= cairo_pattern_create_linear(x
+ ox
+ sx
/ 2, y
+ oy
, x
+ ox
+ sx
, y
+ oy
);
116 cairo_pattern_add_color_stop_rgba(pt
, 0.0, 0,0,0,0);
117 cairo_pattern_add_color_stop_rgba(pt
, 1.0, 0,0,0,dull
);
118 cairo_set_source (c
, pt
);
119 cairo_rectangle(c
, x
+ ox
+ sx
/ 2, y
+ oy
, sx
/ 2, sy
);
121 cairo_pattern_destroy(pt
);
127 while(sx
/ div
> 300)
129 float w
= float(sx
) / float(div
);
130 cairo_rectangle(c
, x
+ ox
, y
+ oy
, sx
, sy
);
131 for(int i
= 0; i
< div
; i
++) {
132 cairo_pattern_t
*pt
= cairo_pattern_create_radial(
133 x
+ ox
+ w
* i
+ w
/ 2.f
, y
+ oy
, 1,
134 x
+ ox
+ w
* i
+ w
/ 2.f
, std::min(w
/ 2.0 + y
+ oy
, y
+ oy
+ sy
* 0.25) - 1, w
/ 2.f
);
135 cairo_pattern_add_color_stop_rgba (pt
, 0, r
* 1.8, g
* 1.8, b
* 1.8, lights
);
136 cairo_pattern_add_color_stop_rgba (pt
, 1, r
, g
, b
, 0);
137 cairo_set_source (c
, pt
);
138 cairo_fill_preserve(c
);
139 pt
= cairo_pattern_create_radial(
140 x
+ ox
+ w
* i
+ w
/ 2.f
, y
+ oy
+ sy
, 1,
141 x
+ ox
+ w
* i
+ w
/ 2.f
, std::max(sy
- w
/ 2.0 + y
+ oy
, y
+ oy
+ sy
* 0.75) + 1, w
/ 2.f
);
142 cairo_pattern_add_color_stop_rgba (pt
, 0, r
* 1.8, g
* 1.8, b
* 1.8, lights
);
143 cairo_pattern_add_color_stop_rgba (pt
, 1, r
, g
, b
, 0);
144 cairo_set_source (c
, pt
);
145 cairo_fill_preserve(c
);
146 cairo_pattern_destroy(pt
);
151 void draw_rect (GtkWidget
* widget
, const gchar
* type
, GtkStateType
* state
, gint x
, gint y
, gint width
, gint height
, gint rad
, float bevel
) {
152 cairo_t
* cr
= gdk_cairo_create(GDK_DRAWABLE(widget
->window
));
154 get_color(widget
, type
, state
, &r
, &g
, &b
);
155 create_rectangle(cr
, x
, y
, width
, height
, rad
);
156 cairo_set_source_rgb(cr
, r
, g
, b
);
160 draw_bevel(cr
, x
, y
, width
, height
, rad
, bevel
);
164 void _draw_inset (cairo_t
* cr
, gint x
, gint y
, gint width
, gint height
, gint rad
, gint depth
) {
165 cairo_pattern_t
*pat
= cairo_pattern_create_linear (x
, y
, x
, y
+ height
);
166 cairo_pattern_add_color_stop_rgba(pat
, 0.0, 0.0, 0.0, 0.0, 0.33);
167 cairo_pattern_add_color_stop_rgba(pat
, 1.0, 1.0, 1.0, 1.0, 0.1);
168 cairo_set_source(cr
, pat
);
169 create_rectangle(cr
, x
-depth
*0.5, y
-depth
, width
+depth
, height
+2*depth
, rad
);
172 void draw_inset (GtkWidget
* widget
, gint x
, gint y
, gint width
, gint height
, gint rad
, gint depth
) {
173 cairo_t
* cr
= gdk_cairo_create(GDK_DRAWABLE(widget
->window
));
174 _draw_inset(cr
, x
, y
, width
, height
, rad
, depth
);
177 void _draw_glass (cairo_t
*cr
, gint x
, gint y
, gint width
, gint height
, gint rad
) {
178 cairo_pattern_t
*pat
= cairo_pattern_create_linear (x
, y
, x
, y
+ 3);
179 cairo_pattern_add_color_stop_rgba(pat
, 0.0, 0.0, 0.0, 0.0, 0.5);
180 cairo_pattern_add_color_stop_rgba(pat
, 1.0, 0.0, 0.0, 0.0, 0.0);
181 cairo_set_source(cr
, pat
);
182 create_rectangle(cr
, x
, y
, width
, height
, rad
);
185 void draw_glass (GtkWidget
* widget
, gint x
, gint y
, gint width
, gint height
, gint rad
) {
186 cairo_t
* cr
= gdk_cairo_create(GDK_DRAWABLE(widget
->window
));
187 _draw_glass(cr
, x
, y
, width
, height
, rad
);
191 void get_bg_color (GtkWidget
* widget
, GtkStateType
* state
, float * r
, float * g
, float * b
) {
192 get_color(widget
, "bg", state
, r
, g
, b
);
194 void get_fg_color (GtkWidget
* widget
, GtkStateType
* state
, float * r
, float * g
, float * b
) {
195 get_color(widget
, "fg", state
, r
, g
, b
);
197 void get_base_color (GtkWidget
* widget
, GtkStateType
* state
, float * r
, float * g
, float * b
) {
198 get_color(widget
, "base", state
, r
, g
, b
);
200 void get_text_color (GtkWidget
* widget
, GtkStateType
* state
, float * r
, float * g
, float * b
) {
201 get_color(widget
, "text", state
, r
, g
, b
);
203 void get_color (GtkWidget
* widget
, const gchar
* type
, GtkStateType
* state
, float * r
, float * g
, float * b
) {
205 GtkStyle
* style
= gtk_widget_get_style (widget
);
211 s
= gtk_widget_get_state(widget
);
212 color
= style
->bg
[s
];
213 if (!strcmp(type
, "bg"))
214 color
= style
->bg
[s
];
215 if (!strcmp(type
, "fg"))
216 color
= style
->fg
[s
];
217 if (!strcmp(type
, "base"))
218 color
= style
->base
[s
];
219 if (!strcmp(type
, "text"))
220 color
= style
->text
[s
];
221 *r
= float(color
.red
) / 65535;
222 *g
= float(color
.green
) / 65535;
223 *b
= float(color
.blue
) / 65535;
227 void clip_context (GtkWidget
* widget
, cairo_t
* cr
, GdkRegion
*region
) {
228 GdkRegion
*reg
= gdk_region_rectangle(&widget
->allocation
);
230 gdk_region_intersect(reg
, region
);
231 gdk_cairo_region(cr
, reg
);
235 void create_rectangle (cairo_t
* cr
, gint x
, gint y
, gint width
, gint height
, gint rad
) {
237 cairo_rectangle(cr
, x
, y
, width
, height
);
240 cairo_move_to(cr
,x
+rad
,y
); // Move to A
241 cairo_line_to(cr
,x
+width
-rad
,y
); // Straight line to B
242 cairo_curve_to(cr
,x
+width
,y
,x
+width
,y
,x
+width
,y
+rad
); // Curve to C, Control points are both at Q
243 cairo_line_to(cr
,x
+width
,y
+height
-rad
); // Move to D
244 cairo_curve_to(cr
,x
+width
,y
+height
,x
+width
,y
+height
,x
+width
-rad
,y
+height
); // Curve to E
245 cairo_line_to(cr
,x
+rad
,y
+height
); // Line to F
246 cairo_curve_to(cr
,x
,y
+height
,x
,y
+height
,x
,y
+height
-rad
); // Curve to G
247 cairo_line_to(cr
,x
,y
+rad
); // Line to H
248 cairo_curve_to(cr
,x
,y
,x
,y
,x
+rad
,y
); // Curve to A
251 void draw_bevel (cairo_t
* cr
, gint x
, gint y
, gint width
, gint height
, gint rad
, float bevel
) {
255 create_rectangle(cr
, x
, y
, width
, height
, rad
);
256 cairo_pattern_t
* pat
;
258 pat
= cairo_pattern_create_linear (x
, y
, x
, y
+ height
);
260 pat
= cairo_pattern_create_linear (x
, y
+ height
, x
, y
);
261 cairo_pattern_add_color_stop_rgba(pat
, 0.0, 1.0, 1.0, 1.0, bevel
/ 2);
262 cairo_pattern_add_color_stop_rgba(pat
, 1.0, 0.0, 0.0, 0.0, bevel
);
263 cairo_set_source(cr
, pat
);
264 cairo_set_operator(cr
, CAIRO_OPERATOR_SOFT_LIGHT
);
265 cairo_fill_preserve(cr
);
266 cairo_set_operator(cr
, CAIRO_OPERATOR_OVER
);
268 cairo_pattern_destroy (pat
);