2
* Copyright © 2012 Keith Packard <keithp@keithp.com>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; version 2 of the License.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* General Public License for more details.
13
* You should have received a copy of the GNU General Public License along
14
* with this program; if not, write to the Free Software Foundation, Inc.,
15
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22
extend namespace Client {
24
public namespace Draw {
30
public typedef struct {
36
Cairo::surface_t surface;
41
sprite_t sprite_from_string(string xml) = (sprite_t) {
42
.svg = Cairo::Rsvg::new_from_string(xml),
47
sprite_t[2] cell = { sprite_from_string(Client::SVG::cell1),
48
sprite_from_string(Client::SVG::cell2) };
50
sprite_t[Color] robots = {
51
Color.Red => sprite_from_string(Client::SVG::robot_red),
52
Color.Blue => sprite_from_string(Client::SVG::robot_blue),
53
Color.Yellow => sprite_from_string(Client::SVG::robot_yellow),
54
Color.Green => sprite_from_string(Client::SVG::robot_green) };
56
sprite_t robot_shadow = sprite_from_string(Client::SVG::robot_shadow);
58
sprite_t[Color][Shape] targets = {
60
Shape.Triangle => sprite_from_string(Client::SVG::target_red_triangle),
61
Shape.Square => sprite_from_string(Client::SVG::target_red_square),
62
Shape.Octagon => sprite_from_string(Client::SVG::target_red_octagon),
63
Shape.Circle => sprite_from_string(Client::SVG::target_red_circle),
66
Shape.Triangle => sprite_from_string(Client::SVG::target_yellow_triangle),
67
Shape.Square => sprite_from_string(Client::SVG::target_yellow_square),
68
Shape.Octagon => sprite_from_string(Client::SVG::target_yellow_octagon),
69
Shape.Circle => sprite_from_string(Client::SVG::target_yellow_circle),
72
Shape.Triangle => sprite_from_string(Client::SVG::target_green_triangle),
73
Shape.Square => sprite_from_string(Client::SVG::target_green_square),
74
Shape.Octagon => sprite_from_string(Client::SVG::target_green_octagon),
75
Shape.Circle => sprite_from_string(Client::SVG::target_green_circle),
78
Shape.Triangle => sprite_from_string(Client::SVG::target_blue_triangle),
79
Shape.Square => sprite_from_string(Client::SVG::target_blue_square),
80
Shape.Octagon => sprite_from_string(Client::SVG::target_blue_octagon),
81
Shape.Circle => sprite_from_string(Client::SVG::target_blue_circle),
84
Shape.Whirl => sprite_from_string(Client::SVG::target_whirl),
88
sprite_t wall = sprite_from_string(Client::SVG::wall);
90
void draw_sprite(&sprite_t sprite, cairo_t cr) {
91
render(sprite.svg, cr);
94
dimensions_t cell_dim = get_dimensions(cell[0].svg);
96
public int cell_width = cell_dim.width;
97
public int cell_height = cell_dim.height;
99
void draw_cached_sprite(&sprite_t sprite, cairo_t cr, &transform_t t) {
100
int width = ceil(cell_width * t.xscale);
101
int height = ceil(cell_width * t.yscale);
104
if (width != sprite.width || height != sprite.height) {
105
if (!is_uninit(&sprite.surface))
106
Cairo::Surface::destroy(sprite.surface);
107
sprite.width = width;
108
sprite.height = height;
109
if (width > 0 && height > 0) {
110
sprite.surface = Cairo::Surface::create_similar(Cairo::get_target(cr),
111
Cairo::content_t.COLOR_ALPHA,
113
cairo_t scr = Cairo::create(sprite.surface);
114
scale(scr, t.xscale, t.yscale);
115
draw_sprite(&sprite, scr);
119
if (sprite.width > 0 && sprite.height > 0) {
120
set_source_surface(cr, sprite.surface, 0, 0);
126
public void background (cairo_t cr, int x, int y, RR::Object object, &transform_t t) {
128
translate(cr, x * cell_width * t.xscale + t.xoff, y * cell_height * t.yscale + t.yoff);
130
draw_cached_sprite(&cell[x+y & 1], cr, &t);
134
public void walls(cairo_t cr, int x, int y, RR::Object object, &transform_t t) {
136
translate(cr, t.xoff, t.yoff);
137
scale(cr, t.xscale, t.yscale);
138
translate(cr, x * cell_width, y * cell_height);
139
rectangle(cr, 0, 0, cell_width, cell_height);
142
void draw_wall (bool doit, bool vertical, bool shift) {
148
translate(cr, 0, -cell_height);
150
translate(cr, 0, cell_height);
151
draw_sprite(&wall, cr);
154
draw_wall (object.walls.left, true, false);
155
draw_wall (object.walls.above, false, false);
156
draw_wall (object.walls.right, true, true);
157
draw_wall (object.walls.below, false, true);
161
public void contents (cairo_t cr, int x, int y, RR::Object object, RR::RobotOrNone active_robot,
164
translate(cr, x * cell_width * t.xscale + t.xoff, y * cell_height * t.yscale + t.yoff);
166
union switch (object.target) {
170
draw_cached_sprite(&targets[target.color][target.shape], cr, &t);
173
union switch(object.robot) {
177
union switch (active_robot) {
179
if (a.color == r.color) {
181
scale(cr, t.xscale, t.yscale);
184
draw_sprite(&robot_shadow, cr);
190
draw_cached_sprite(&robots[r.color], cr, &t);
196
public void target (cairo_t cr, real x, real y, TargetOrNone target, &transform_t t) {
198
translate(cr, x * cell_width * t.xscale + t.xoff, y * cell_height * t.yscale + t.yoff);
199
scale(cr, 2 * t.xscale, 2 *t.yscale);
200
union switch (target) {
202
draw_sprite(&targets[t.color][t.shape], cr);