1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<unistd.h>
#include<string.h>
#include<cairo/cairo.h>
#include<wayland-server.h>
#include<wayland-client.h>
#include<wayland-client-protocol.h>
#include"wlclock.h"
#include"surface.h"
#include"output.h"
#include"misc.h"
#include"colour.h"
#include"render.h"
static void rounded_rectangle (cairo_t *cairo, uint32_t x, uint32_t y, uint32_t w, uint32_t h,
double tl_r, double tr_r, double bl_r, double br_r)
{
double degrees = 3.1415927 / 180.0;
cairo_new_sub_path(cairo);
cairo_arc(cairo, x + w - tr_r, y + tr_r, tr_r, -90 * degrees, 0 * degrees);
cairo_arc(cairo, x + w - br_r, y + h - br_r, br_r, 0 * degrees, 90 * degrees);
cairo_arc(cairo, x + bl_r, y + h - bl_r, bl_r, 90 * degrees, 180 * degrees);
cairo_arc(cairo, x + tl_r, y + tl_r, tl_r, 180 * degrees, 270 * degrees);
cairo_close_path(cairo);
}
static void draw_background (cairo_t *cairo,
uint32_t x, uint32_t y, uint32_t w, uint32_t h,
uint32_t border_top, uint32_t border_right,
uint32_t border_bottom, uint32_t border_left,
uint32_t top_left_radius, uint32_t top_right_radius,
uint32_t bottom_left_radius, uint32_t bottom_right_radius,
uint32_t scale,
struct Wlclock_colour *background_colour,
struct Wlclock_colour *border_colour)
{
if ( colour_is_transparent(background_colour) && colour_is_transparent(border_colour) )
return;
/* Scale. */
x *= scale, y *= scale, w *= scale, h *= scale;
border_top *= scale, border_bottom *= scale;
border_left *= scale, border_right *= scale;
top_left_radius *= scale, top_right_radius *= scale;
bottom_left_radius *= scale, bottom_right_radius *= scale;
cairo_save(cairo);
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
if ( top_left_radius == 0 && top_right_radius == 0
&& bottom_left_radius == 0 && bottom_right_radius == 0 )
{
if ( border_top == 0 && border_bottom == 0
&& border_left == 0 && border_right == 0 )
{
cairo_rectangle(cairo, x, y, w, h);
colour_set_cairo_source(cairo, background_colour);
cairo_fill(cairo);
}
else
{
fputs("here\n", stderr);
/* Calculate dimensions of center. */
uint32_t cx = x + border_left,
cy = y + border_top,
cw = w - (border_left + border_right),
ch = h - (border_top + border_bottom);
/* Borders. */
cairo_rectangle(cairo, x, y, w, border_top);
cairo_rectangle(cairo, x + w - border_right, y + border_top,
border_right, h - border_top - border_bottom);
cairo_rectangle(cairo, x, y + h - border_bottom, w, border_bottom);
cairo_rectangle(cairo, x, y + border_top, border_left,
h - border_top - border_bottom);
colour_set_cairo_source(cairo, border_colour);
cairo_fill(cairo);
/* Center. */
cairo_rectangle(cairo, cx, cy, cw, ch);
colour_set_cairo_source(cairo, background_colour);
cairo_fill(cairo);
}
}
else
{
if ( border_top == 0 && border_bottom == 0
&& border_left == 0 && border_right == 0 )
{
rounded_rectangle(cairo, x, y, w, h,
top_left_radius, top_right_radius,
bottom_left_radius, bottom_right_radius);
colour_set_cairo_source(cairo, background_colour);
cairo_fill(cairo);
}
else
{
rounded_rectangle(cairo, x, y, w, h,
top_left_radius, top_right_radius,
bottom_left_radius, bottom_right_radius);
colour_set_cairo_source(cairo, border_colour);
cairo_fill(cairo);
rounded_rectangle(cairo, x + border_left, y + border_top,
w - (border_left + border_right),
h - (border_bottom + border_top),
top_left_radius, top_right_radius,
bottom_left_radius, bottom_right_radius);
colour_set_cairo_source(cairo, background_colour);
cairo_fill(cairo);
}
}
cairo_restore(cairo);
}
static void clear_buffer (cairo_t *cairo)
{
cairo_save(cairo);
cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
cairo_paint(cairo);
cairo_restore(cairo);
}
void render_surface_frame (struct Wlclock_surface *surface)
{
struct Wlclock_output *output = surface->output;
struct Wlclock *clock = output->clock;
uint32_t scale = output->scale;
clocklog(clock, 2, "[render] Render frame: global_name=%d\n", output->global_name);
/* Get new/next buffer. */
if (! next_buffer(&surface->current_buffer, clock->shm, surface->buffers,
surface->size * scale, surface->size * scale))
return;
cairo_t *cairo = surface->current_buffer->cairo;
clear_buffer(cairo);
draw_background(cairo, 0, 0, surface->size, surface->size,
clock->border_top, clock->border_right,
clock->border_bottom, clock->border_left,
clock->radius_top_left, clock->radius_top_right,
clock->radius_bottom_left, clock->radius_bottom_right,
scale, &clock->background_colour, &clock->border_colour);
// TODO draw clock stuff
wl_surface_set_buffer_scale(surface->surface, scale);
wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0);
wl_surface_damage_buffer(surface->surface, 0, 0, INT32_MAX, INT32_MAX);
}
|