libxputty 0.1
Loading...
Searching...
No Matches
xmeter_private.c
Go to the documentation of this file.
1/*
2 * 0BSD
3 *
4 * BSD Zero Clause License
5 *
6 * Copyright (c) 2019 Hermann Meyer
7 *
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted.
10
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 *
19 */
20
21
22#include "xmeter_private.h"
23
24
25void _draw_vmeter_scale(void *w_, void* user_data) {
26 Widget_t *w = (Widget_t*)w_;
27 Metrics_t metrics;
28 os_get_window_metrics(w, &metrics);
29 int rect_width = metrics.width;
30 int rect_height = metrics.height;
31 double x0 = 0;
32 double y0 = 0;
33
34 int db_points[] = { -50, -40, -30, -20, -15, -10, -6, -3, 0, 3 };
35 //int db_points[] = { -50, -40, -30, -20, -10, -3, 0, 4 };
36 char buf[32];
37
38 cairo_set_font_size (w->crb, (float)rect_width/2);
39 cairo_set_source_rgb(w->crb, 0.8, 0.8, 0.8);
40
41 for (unsigned int i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i)
42 {
43 float fraction = _log_meter((double)db_points[i]);
44 cairo_move_to (w->crb, 0,y0+rect_height - (rect_height * fraction));
45 cairo_line_to (w->crb, x0+rect_width-3 ,y0+rect_height - (rect_height * fraction));
46 if (i<6)
47 {
48 snprintf (buf, sizeof (buf), "%d", db_points[i]);
49 cairo_move_to (w->crb, x0+rect_width*0.1,y0+rect_height - (rect_height * fraction)-3);
50 }
51 else if (i<8)
52 {
53 snprintf (buf, sizeof (buf), "%d", db_points[i]);
54 cairo_move_to (w->crb, x0+rect_width*0.2,y0+rect_height - (rect_height * fraction)-3);
55 }
56 else
57 {
58 snprintf (buf, sizeof (buf), " %d", db_points[i]);
59 cairo_move_to (w->crb, x0+rect_width*0.21,y0+rect_height - (rect_height * fraction)-3);
60 }
61 cairo_show_text (w->crb, buf);
62 }
63
64 cairo_set_source_rgb(w->crb, 0.6, 0.6, 0.6);
65 cairo_set_line_width(w->crb, 2.0);
66 cairo_stroke(w->crb);
67}
68
69void _draw_hmeter_scale(void *w_, void* user_data) {
70 Widget_t *w = (Widget_t*)w_;
71 Metrics_t metrics;
72 os_get_window_metrics(w, &metrics);
73 int rect_width = metrics.width;
74 int rect_height = metrics.height;
75 double x0 = 0;
76 double y0 = 0;
77
78 int db_points[] = { -50, -40, -30, -20, -15, -10, -6, -3, 0, 3 };
79 char buf[32];
80
81 cairo_set_font_size (w->crb, (float)rect_height/2);
82 cairo_set_source_rgba(w->crb, 0.6, 0.6, 0.6, 0.6);
83
84 for (unsigned int i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i)
85 {
86 float fraction = _log_meter(db_points[i]);
87 //cairo_set_source_rgb (w->crb,0.32 + 0.22*i/2,0.5 + 0.1*i/2, 0.1);
88
89 cairo_move_to (w->crb, x0+(rect_width * fraction),y0+rect_height*0.1);
90 cairo_line_to (w->crb, x0+(rect_width * fraction) ,y0+rect_height*0.6);
91 if (i<6)
92 {
93 snprintf (buf, sizeof (buf), "%d", db_points[i]);
94 cairo_move_to (w->crb, x0+(rect_width * fraction)+3,y0+rect_height);
95 }
96 else
97 {
98 snprintf (buf, sizeof (buf), " %d", db_points[i]);
99 cairo_move_to (w->crb, x0+(rect_width * fraction)+3,y0+rect_height );
100 }
101 cairo_show_text (w->crb, buf);
102 }
103
104 cairo_set_source_rgba(w->crb, 0.6, 0.6, 0.6, 0.6);
105 cairo_set_line_width(w->crb, 1.5);
106 cairo_stroke(w->crb);
107}
108
109float _log_meter (float db) {
110 float def = 0.0f; /* Meter deflection %age */
111
112 if (db < -70.0f) {
113 def = 0.0f;
114 } else if (db < -60.0f) {
115 def = (db + 70.0f) * 0.25f;
116 } else if (db < -50.0f) {
117 def = (db + 60.0f) * 0.5f + 2.5f;
118 } else if (db < -40.0f) {
119 def = (db + 50.0f) * 0.75f + 7.5f;
120 } else if (db < -30.0f) {
121 def = (db + 40.0f) * 1.5f + 15.0f;
122 } else if (db < -20.0f) {
123 def = (db + 30.0f) * 2.0f + 30.0f;
124 } else if (db < 6.0f) {
125 def = (db + 20.0f) * 2.5f + 50.0f;
126 } else {
127 def = 115.0f;
128 }
129
130 /* 115 is the deflection %age that would be
131 when db=6.0. this is an arbitrary
132 endpoint for our scaling.
133 */
134
135 return def/115.0f;
136}
137
138void _create_vertical_meter_image(Widget_t *w, int width, int height) {
139 cairo_surface_destroy(w->image);
140 w->image = NULL;
141 w->image = cairo_surface_create_similar (w->surface,
142 CAIRO_CONTENT_COLOR_ALPHA, width*2, height);
143 cairo_t *cri = cairo_create (w->image);
144
145 cairo_rectangle(cri,0.0, 0.0, width, height);
147 cairo_fill(cri);
148
149 cairo_rectangle(cri,width, 0.0, width, height);
151 cairo_fill(cri);
152
153 cairo_pattern_t *pat = cairo_pattern_create_linear (0, 0, 0.0, height);
154 cairo_pattern_add_color_stop_rgba(pat, 1.0, 0.1, 0.5, 0.1, 0.4);
155 cairo_pattern_add_color_stop_rgba(pat, 0.2, 0.4, 0.4, 0.1, 0.4);
156 cairo_pattern_add_color_stop_rgba(pat, 0.0, 0.5, 0.0, 0.0, 0.4);
157 cairo_set_source(cri, pat);
158
159 int c = (width)/2 ;
160 int ci = c-2;
161
162 int i = 1;
163 int j = 1;
164 for(;i<height-3;) {
165 for(;j<width;) {
166 cairo_rectangle(cri,j,i,ci,2);
167 cairo_fill(cri);
168 j +=c;
169 }
170 i +=3;
171 j = 1;
172 }
173
174 cairo_pattern_destroy (pat);
175 pat = cairo_pattern_create_linear (0, 0, 0.0, height);
176 cairo_pattern_add_color_stop_rgba(pat, 1.0, 0.1, 0.5, 0.1, 1);
177 cairo_pattern_add_color_stop_rgba(pat, 0.2, 0.4, 0.4, 0.1, 1);
178 cairo_pattern_add_color_stop_rgba(pat, 0.0, 0.5, 0.0, 0.0, 1);
179 cairo_set_source(cri, pat);
180 i = 1;
181 j = 1;
182 for(;i<height-3;) {
183 for(;j<width;) {
184 cairo_rectangle(cri,width+j,i,ci,2);
185 cairo_fill(cri);
186 j +=c;
187 }
188 i +=3;
189 j = 1;
190 }
191
192 cairo_pattern_destroy (pat);
193 cairo_destroy(cri);
194}
195
196void _create_horizontal_meter_image(Widget_t *w, int width, int height) {
197 cairo_surface_destroy(w->image);
198 w->image = NULL;
199 w->image = cairo_surface_create_similar (w->surface,
200 CAIRO_CONTENT_COLOR_ALPHA, width, height*2);
201 cairo_t *cri = cairo_create (w->image);
202
203 cairo_rectangle(cri,0.0, 0.0, width, height);
205 cairo_fill(cri);
206
207 cairo_rectangle(cri, 0.0, height, width, height);
209 cairo_fill(cri);
210
211 cairo_pattern_t *pat = cairo_pattern_create_linear (0, 0, width, 0.0);
212 cairo_pattern_add_color_stop_rgba(pat, 0.0, 0.1, 0.5, 0.1, 0.4);
213 cairo_pattern_add_color_stop_rgba(pat, 0.8, 0.4, 0.4, 0.1, 0.4);
214 cairo_pattern_add_color_stop_rgba(pat, 1.0, 0.5, 0.0, 0.0, 0.4);
215 cairo_set_source(cri, pat);
216
217 int c = (height)/2 ;
218 int ci = c-2;
219
220 int i = 1;
221 int j = 1;
222 for(;i<width;) {
223 for(;j<height;) {
224 cairo_rectangle(cri,i,j,2,ci);
225 cairo_fill(cri);
226 j +=c;
227 }
228 i +=3;
229 j = 1;
230 }
231
232 cairo_pattern_destroy (pat);
233 pat = cairo_pattern_create_linear (0, 0, width, 0.0);
234 cairo_pattern_add_color_stop_rgba(pat, 0.0, 0.1, 0.5, 0.1, 1);
235 cairo_pattern_add_color_stop_rgba(pat, 0.8, 0.4, 0.4, 0.1, 1);
236 cairo_pattern_add_color_stop_rgba(pat, 1.0, 0.5, 0.0, 0.0, 1);
237 cairo_set_source(cri, pat);
238 i = 1;
239 j = 1;
240 for(;i<width;) {
241 for(;j<height;) {
242 cairo_rectangle(cri,i,height+j,2,ci);
243 cairo_fill(cri);
244 j +=c;
245 }
246 i +=3;
247 j = 1;
248 }
249
250 cairo_pattern_destroy (pat);
251 cairo_destroy(cri);
252}
253
254void _draw_v_meter(void *w_, void* user_data) {
255 Widget_t *w = (Widget_t*)w_;
256
257 int width, height;
258 os_get_surface_size(w->image, &width, &height);
259 Metrics_t metrics;
260 os_get_window_metrics(w, &metrics);
261 int width_t = metrics.width;
262 int height_t = metrics.height;
263 if (width != width_t*2 || height != height_t) {
264 _create_vertical_meter_image(w, width_t, height_t);
265 os_get_surface_size(w->image, &width, &height);
266 }
267 double meterstate = _log_meter(adj_get_value(w->adj_y));
268 double oldstate = _log_meter(w->adj_y->start_value);
269 cairo_set_source_surface (w->crb, w->image, 0, 0);
270 cairo_rectangle(w->crb,0, 0, width/2, height);
271 cairo_fill(w->crb);
272 cairo_set_source_surface (w->crb, w->image, -width/2, 0);
273 cairo_rectangle(w->crb, 0, height, width/2, -height*meterstate);
274 cairo_fill(w->crb);
275
276 cairo_rectangle(w->crb, 0, height-height*oldstate, width/2, 3);
277 cairo_fill(w->crb);
278}
279
280void _draw_h_meter(void *w_, void* user_data) {
281 Widget_t *w = (Widget_t*)w_;
282
283 int width, height;
284 os_get_surface_size(w->image, &width, &height);
285 Metrics_t metrics;
286 os_get_window_metrics(w, &metrics);
287 int width_t = metrics.width;
288 int height_t = metrics.height;
289 if (width != width_t || height != height_t*2) {
290 _create_horizontal_meter_image(w, width_t, height_t);
291 os_get_surface_size(w->image, &width, &height);
292 }
293 double meterstate = _log_meter(adj_get_value(w->adj_x));
294 double oldstate = _log_meter(w->adj_x->start_value);
295 cairo_set_source_surface (w->crb, w->image, 0, 0);
296 cairo_rectangle(w->crb,0, 0, width, height/2);
297 cairo_fill(w->crb);
298 cairo_set_source_surface (w->crb, w->image, 0, -height/2);
299 cairo_rectangle(w->crb, 0, 0, width*meterstate, height/2);
300 cairo_fill(w->crb);
301
302 cairo_rectangle(w->crb,(width*oldstate)-3, 0, 3, height/2);
303 cairo_fill(w->crb);
304}
float start_value
Definition xadjustment.h:96
Metrics_t - struct to receive window size, position & visibility Pass this struct to os_get_window_...
Widget_t - struct to hold the basic Widget_t info.
Definition xwidget.h:457
Adjustment_t * adj_y
Definition xwidget.h:495
Adjustment_t * adj_x
Definition xwidget.h:493
cairo_surface_t * image
Definition xwidget.h:491
cairo_surface_t * surface
Definition xwidget.h:483
cairo_t * crb
Definition xwidget.h:489
float adj_get_value(Adjustment_t *adj)
adj_get_value - get the current value of the Adjustment_t
void use_shadow_color_scheme(Widget_t *w, Color_state st)
use_shadow_color_scheme - use shadow Colors to paint on Widget_t
Definition xcolor.c:273
@ NORMAL_
Definition xcolor.h:44
void _draw_vmeter_scale(void *w_, void *user_data)
_draw_meter_scale - draw a meter scale beside the meter widget
void _draw_hmeter_scale(void *w_, void *user_data)
_draw_hmeter_scale - draw a hmeter scale beside the meter widget
void _draw_h_meter(void *w_, void *user_data)
_draw_h_meter - internal draw the meter to the buffer
void _create_vertical_meter_image(Widget_t *w, int width, int height)
_create_vertical_meter_image - internal draw the meter image to the cairo image surface
float _log_meter(float db)
_log_meter - logaritmic meter deflection
void _create_horizontal_meter_image(Widget_t *w, int width, int height)
_create_horizontal_meter_image - internal draw the meter image to the cairo image surface
void _draw_v_meter(void *w_, void *user_data)
_draw_v_meter - internal draw the meter to the buffer
void os_get_window_metrics(Widget_t *w, Metrics_t *metrics)
os_get_window_metrics - Get the Merics_t struct related to a Widget_t
void os_get_surface_size(cairo_surface_t *surface, int *width, int *height)
os_get_surface_size - get the size of the cairo surface