Mercurial > projects > dynamin
annotate dynamin/painting/graphics.d @ 113:4636a64afabc default tip
Add reverse() function.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Sat, 19 Jan 2013 21:08:52 -0600 |
parents | acdbb30fee7e |
children |
rev | line source |
---|---|
0 | 1 |
2 /* | |
103
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
16
diff
changeset
|
3 * Copyright Jordan Miner |
0 | 4 * |
103
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
16
diff
changeset
|
5 * This Source Code Form is subject to the terms of the Mozilla Public |
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
16
diff
changeset
|
6 * License, v. 2.0. If a copy of the MPL was not distributed with this |
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
16
diff
changeset
|
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
0 | 8 * |
9 */ | |
10 | |
11 module dynamin.painting.graphics; | |
12 | |
13 import dynamin.c.cairo; | |
14 import dynamin.core.string; | |
15 import dynamin.core.math; | |
16 import dynamin.core.file; | |
17 import dynamin.painting.coordinates; | |
18 import dynamin.painting.color; | |
19 import tango.io.Stdout; | |
20 | |
21 /// | |
22 class Font { | |
23 private: | |
24 string _family; | |
25 int _style = 0; | |
26 int _size; | |
27 public: | |
106 | 28 this(string family_ = null, int size = 10, bool b = false, bool i = false, bool u = false) { |
0 | 29 this.family = family_; |
30 this.size = size; | |
31 bold = b; | |
32 italic = i; | |
33 underline = u; | |
34 } | |
35 /** | |
36 * Gets or sets the family name of this font. Common font family names on | |
37 * Windows are "Arial", "Times New Roman", and "Tahoma". | |
38 */ | |
39 string family() { return _family; } | |
40 /// ditto | |
41 void family(string str) { _family = str; } | |
42 /// | |
43 int style() { return _style; } | |
44 /// ditto | |
45 void style(int s) { _style = s; } | |
46 /// Gets or sets whether this font is bold. | |
47 bool bold() { return cast(bool)(_style & 1); } | |
48 /// ditto | |
49 void bold(bool b) { b ? (_style |= 1) : (_style &= ~1); } | |
50 /// Gets or sets whether this font is italic. | |
51 bool italic() { return cast(bool)(_style & 2); } | |
52 /// ditto | |
53 void italic(bool b) { b ? (_style |= 2) : (_style &= ~2); } | |
54 /// Gets or sets whether this font is underline. | |
55 bool underline() { return cast(bool)(_style & 4); } | |
56 /// ditto | |
57 void underline(bool b) { b ? (_style |= 4) : (_style &= ~4); } | |
58 /// Gets or sets whether this font is strikethrough. | |
59 bool strikethrough() { return cast(bool)(_style & 8); } | |
60 /// ditto | |
61 void strikethrough(bool b) { b ? (_style |= 8) : (_style &= ~8); } | |
62 /** | |
63 * Gets or sets the size of this font in user space units, not in points. | |
64 * This size is the ascent plus the descent, not including the leading. | |
65 */ | |
66 int size() { return _size; } | |
67 /// ditto | |
68 void size(int s) { _size = s; } | |
69 } | |
70 | |
71 /// | |
72 struct FontExtents { | |
73 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
74 double ascent; |
0 | 75 /// |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
76 double descent; |
0 | 77 /// |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
78 double leading() { return height - ascent - descent; } |
0 | 79 /// |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
80 double height; |
0 | 81 /// |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
82 double maxAdvance; |
0 | 83 } |
84 | |
85 //import lodepng = dynamin.lodepng.decode; | |
86 /// An RGBA 32-bit-per-pixel image. | |
87 class Image { | |
88 Color* _data; | |
89 uint _width, _height; | |
90 Color* data() { return _data; } | |
91 uint width() { return _width; } | |
92 uint height() { return _height; } | |
93 protected this() { | |
94 } | |
95 Color* opIndex(int x, int y) { | |
96 return _data + x+y*_width; | |
97 } | |
106 | 98 static Image load(cstring file) { |
0 | 99 static if(false) { |
100 auto img = new Image; | |
101 lodepng.PngInfo info; | |
102 img._data = cast(Color*)lodepng.decode32(readFileBytes(file), info); | |
103 img._width = info.image.width; | |
104 img._height = info.image.height; | |
105 | |
106 ubyte r; | |
107 for(uint i = 0; i < img.width * img.height; ++i) { | |
108 // lodepng returns data as ABGR instead of the ARGB that cairo, | |
109 // Windows, and I think X use. | |
110 r = img.data[i].R; | |
111 img.data[i].R = img.data[i].B; | |
112 img.data[i].B = r; | |
113 // cairo, Windows, and I think X use pre-multiplied alpha | |
114 img.data[i].R = img.data[i].R * img.data[i].A / 255; | |
115 img.data[i].G = img.data[i].G * img.data[i].A / 255; | |
116 img.data[i].B = img.data[i].B * img.data[i].A / 255; | |
117 } | |
118 | |
119 return img; | |
120 } else { return null; } | |
121 } | |
122 } | |
123 | |
124 /// | |
125 enum GraphicsOperator { | |
126 Clear, /// | |
127 | |
128 Source, /// | |
129 Over, /// | |
130 In, /// | |
131 Out, /// | |
132 Atop, /// | |
133 | |
134 Dest, /// | |
135 DestOver, /// | |
136 DestIn, /// | |
137 DestOut, /// | |
138 DestAtop, /// | |
139 | |
140 Xor, /// | |
141 Add, /// | |
142 Saturate /// | |
143 } | |
144 | |
145 /// | |
146 enum GraphicsFillRule { | |
147 /// | |
148 Winding, | |
149 EvenOdd /// | |
150 } | |
151 /** | |
152 * Example: | |
153 * ----- | |
154 * graphics.source = Color.Gold; | |
155 * graphics.rectangle(40, 10, 100, 120); | |
156 * graphics.fill(); | |
157 * graphics.source = Color.Black; | |
158 * | |
159 * graphics.lineWidth = 20; | |
160 * | |
161 * // GraphicsLineCap.Butt is default | |
162 * graphics.moveTo(40, 30); | |
163 * graphics.lineTo(140, 30); | |
164 * graphics.stroke(); | |
165 * | |
166 * graphics.lineCap = GraphicsLineCap.Round; | |
167 * graphics.moveTo(40, 70); | |
168 * graphics.lineTo(140, 70); | |
169 * graphics.stroke(); | |
170 * | |
171 * graphics.lineCap = GraphicsLineCap.Square; | |
172 * graphics.moveTo(40, 110); | |
173 * graphics.lineTo(140, 110); | |
174 * graphics.stroke(); | |
175 * ----- | |
176 * $(IMAGE ../web/example_line_cap.png) | |
177 */ | |
178 enum GraphicsLineCap { | |
179 /** | |
180 * Uses no ending. The line ends exactly at the end point. | |
181 */ | |
182 Butt, | |
183 /** | |
184 * Uses a rounded ending with the center of the circle at the end point. | |
185 * Therefore, the cap extends past the end point for half the line width. | |
186 */ | |
187 Round, | |
188 /** | |
189 * Uses a square ending with the center of the square at the end point. | |
190 * Therefore, the cap extends past the end point for half the line width. | |
191 */ | |
192 Square | |
193 } | |
194 | |
106 | 195 // cairo_copy_clip_rectangles --> Rectangle[] clipRectangles() |
196 // cairo_get_dash --> dashes() | |
197 // cairo_get_color_stop_rgba --> colorStops() | |
0 | 198 /** |
199 * A Graphics object uses its source to draw on its target. Its target is set | |
200 * when it is created, but its source can be changed whenever desired. For | |
201 * example, for a painting event, the target of a Graphics is the control | |
202 * being painted. In other cases it could be an image. Its source is usually a | |
203 * color, but could be a gradient, an image, or some other pattern. | |
204 * | |
205 * If the documentation here is not sufficient, cairo might have | |
206 * better documentation at $(LINK http://www.cairographics.org/manual/). | |
207 */ | |
208 class Graphics { | |
209 private: | |
210 cairo_t* cr; | |
211 public: | |
212 this(cairo_t* cr) { | |
213 this.cr = cr; | |
214 cairo_reference(cr); | |
215 checkStatus(); | |
216 } | |
217 ~this() { | |
218 cairo_destroy(cr); | |
219 } | |
220 /** | |
221 * Returns: a pointer to the cairo context (cairo_t*) that backs this object | |
222 */ | |
223 cairo_t* handle() { return cr; } | |
224 void checkStatus() { | |
225 cairo_status_t status = cairo_status(cr); | |
226 if(status == CAIRO_STATUS_SUCCESS) | |
227 return; | |
228 | |
229 Stdout("Cairo error: ")(cairo_status_to_string(status)).newline; | |
230 assert(0); | |
231 } | |
232 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
233 void moveTo(double x, double y) { |
0 | 234 cairo_move_to(cr, x, y); |
235 } | |
236 /// ditto | |
237 void moveTo(Point pt) { | |
238 moveTo(pt.x, pt.y); | |
239 } | |
240 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
241 void lineTo(double x, double y) { |
0 | 242 cairo_line_to(cr, x, y); |
243 } | |
244 /// ditto | |
245 void lineTo(Point pt) { | |
246 lineTo(pt.x, pt.y); | |
247 } | |
248 /// | |
249 void curveTo(Point pt1, Point pt2, Point pt3) { | |
250 curveTo(pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y); | |
251 } | |
252 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
253 void curveTo(double x1, double y1, double x2, double y2, double x3, double y3) { |
0 | 254 cairo_curve_to(cr, x1, y1, x2, y2, x3, y3); |
255 } | |
256 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
257 void relMoveTo(double x, double y) { |
0 | 258 cairo_rel_move_to(cr, x, y); |
259 } | |
260 /// ditto | |
261 void relMoveTo(Point pt) { | |
262 relMoveTo(pt.x, pt.y); | |
263 } | |
264 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
265 void relLineTo(double x, double y) { |
0 | 266 cairo_rel_line_to(cr, x, y); |
267 } | |
268 /// ditto | |
269 void relLineTo(Point pt) { | |
270 relLineTo(pt.x, pt.y); | |
271 } | |
272 /// | |
273 void relCurveTo(Point pt1, Point pt2, Point pt3) { | |
274 relCurveTo(pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y); | |
275 } | |
276 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
277 void relCurveTo(double x1, double y1, double x2, double y2, double x3, double y3) { |
0 | 278 cairo_rel_curve_to(cr, x1, y1, x2, y2, x3, y3); |
279 } | |
280 /** | |
281 * Adds an arc to the current path. A line is added connecting the | |
282 * current point to the beginning of the arc. | |
283 * Example: | |
284 * ----- | |
285 * graphics.moveTo(5, 5); | |
286 * graphics.arc(50.5, 80.5, 40, 40, -0.2, PI/2); | |
287 * graphics.stroke(); | |
288 * ----- | |
289 * $(IMAGE ../web/example_arc.png) | |
290 */ | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
291 void arc(Point ptc, double radius, double angle1, double angle2) { |
0 | 292 arc(ptc.x, ptc.y, radius, angle1, angle2); |
293 } | |
294 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
295 void arc(double xc, double yc, double radius, double angle1, double angle2) { |
0 | 296 cairo_arc(cr, xc, yc, radius, angle1, angle2); |
297 } | |
298 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
299 void arc(double xc, double yc, double xradius, double yradius, double angle1, double angle2) { |
0 | 300 cairo_save(cr); |
301 cairo_translate(cr, xc, yc); | |
302 cairo_scale(cr, xradius, yradius); | |
303 cairo_arc(cr, 0, 0, 1, angle1, angle2); | |
304 cairo_restore(cr); | |
305 } | |
306 /** | |
307 * Adds an ellipse as a closed sub-path--a line will not connect it | |
308 * to the current point. | |
309 * Example: | |
310 * ----- | |
311 * graphics.ellipse(70.5, 50.5, 60, 25); | |
312 * graphics.stroke(); | |
313 * ----- | |
314 * $(IMAGE ../web/example_ellipse.png) | |
315 */ | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
316 void ellipse(double xc, double yc, double radius) { |
0 | 317 cairo_new_sub_path(cr); |
318 cairo_arc(cr, xc, yc, radius, 0, Pi * 2); | |
319 cairo_close_path(cr); | |
320 } | |
321 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
322 void ellipse(double xc, double yc, double xradius, double yradius) { |
0 | 323 cairo_new_sub_path(cr); |
324 arc(xc, yc, xradius, yradius, 0, Pi * 2); | |
325 cairo_close_path(cr); | |
326 } | |
327 /** | |
328 * Adds a rectangle as a sub-path--a line will not connect it | |
329 * to the current point. | |
330 * Example: | |
331 * ----- | |
332 * graphics.rectangle(5.5, 5.5, 70, 20); | |
333 * graphics.stroke(); | |
334 * ----- | |
335 * $(IMAGE ../web/example_rectangle.png) | |
336 */ | |
337 void rectangle(Rect rect) { | |
338 rectangle(rect.x, rect.y, rect.width, rect.height); | |
339 } | |
340 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
341 void rectangle(double x, double y, double width, double height) { |
0 | 342 cairo_rectangle(cr, x, y, width, height); |
343 } | |
16
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
344 /** |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
345 * Adds a rectangle with rounded corners as a sub-path--a line will |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
346 * not connect it to the current point. |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
347 */ |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
348 void roundedRectangle(Rect rect, double radius) { |
16
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
349 roundedRectangle(rect.x, rect.y, rect.width, rect.height, radius); |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
350 } |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
351 /// ditto |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
352 void roundedRectangle(double x, double y, double width, double height, double radius) { |
16
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
353 alias radius r; |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
354 cairo_new_sub_path(cr); |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
355 arc(x+r, y+r, r, Pi, 3*Pi/2); |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
356 arc(x+width-r, y+r, r, 3*Pi/2, 0); |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
357 arc(x+width-r, y+height-r, r, 0, Pi/2); |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
358 arc(x+r, y+height-r, r, Pi/2, Pi); |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
359 closePath(); |
dcaa95190f4b
Add roundedRectangle() method to Graphics.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
360 } |
0 | 361 /// |
362 void closePath() { | |
363 cairo_close_path(cr); | |
364 } | |
365 /** | |
366 * Draws the outline of the current path. | |
367 * Example: | |
368 * ----- | |
369 * graphics.moveTo(12.5, 14.5); | |
370 * graphics.lineTo(123.5, 22.5); | |
371 * graphics.lineTo(139.5, 108.5); | |
372 * graphics.lineTo(49.5, 86.5); | |
373 * graphics.closePath(); | |
374 * graphics.stroke(); | |
375 * ----- | |
376 * $(IMAGE ../web/example_stroke.png) | |
377 */ | |
378 void stroke() { | |
379 cairo_stroke(cr); | |
380 } | |
381 /** | |
382 * Draws the inside of the current path. | |
383 * Example: | |
384 * ----- | |
106 | 385 * graphics.moveTo(12.5, 14.5); |
386 * graphics.lineTo(123.5, 22.5); | |
387 * graphics.lineTo(139.5, 108.5); | |
388 * graphics.lineTo(49.5, 86.5); | |
389 * graphics.closePath(); | |
390 * graphics.fill(); | |
0 | 391 * ----- |
392 * $(IMAGE ../web/example_fill.png) | |
393 */ | |
394 void fill() { | |
395 cairo_fill(cr); | |
396 } | |
397 /** | |
398 * Paints the current source everywhere within the current clip region. | |
399 * Examples: | |
400 * ----- | |
401 * graphics.source = Color(255, 128, 0); | |
402 * graphics.paint(); | |
403 * ----- | |
404 * $(IMAGE ../web/example_paint.png) | |
405 */ | |
406 void paint() { | |
407 cairo_paint(cr); | |
408 } | |
409 /** | |
410 * Gets or sets the line _width used for stroking. | |
411 * Example: | |
412 * ----- | |
413 * graphics.ellipse(40.5, 30.5, 30, 20); | |
414 * graphics.lineWidth = 1; | |
415 * graphics.stroke(); | |
416 * graphics.ellipse(40.5, 80.5, 30, 20); | |
417 * graphics.lineWidth = 5; | |
418 * graphics.stroke(); | |
419 * ----- | |
420 * $(IMAGE ../web/example_line_width.png) | |
421 */ | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
422 double lineWidth() { |
0 | 423 return cairo_get_line_width(cr); |
424 } | |
425 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
426 void lineWidth(double width) { |
0 | 427 cairo_set_line_width(cr, width); |
428 } | |
429 /** | |
430 * Gets or sets the line cap used for stroking. | |
431 * | |
432 * The line cap is only examined when the stroke is performed, not before. | |
433 * Therefore, drawing two lines, each with a different line cap, would | |
434 * require calling stroke twice. | |
435 */ | |
436 GraphicsLineCap lineCap() { | |
437 return cast(GraphicsLineCap)cairo_get_line_cap(cr); | |
438 } | |
439 /// ditto | |
440 void lineCap(GraphicsLineCap cap) { | |
441 cairo_set_line_cap(cr, cap); | |
442 } | |
443 /** | |
444 * Sets the font size to the specified size in user space units, not | |
445 * in points. | |
446 */ | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
447 void fontSize(double size) { |
0 | 448 assert(size != 0); |
449 cairo_set_font_size(cr, size); | |
450 } | |
451 /** | |
452 * Set the font used to draw text. | |
453 */ | |
454 void font(Font f) { | |
455 assert(f.size != 0); | |
456 cairo_set_font_size(cr, f.size); | |
457 cairo_select_font_face(cr, toCharPtr(f.family), f.italic, f.bold); | |
458 } | |
459 // TODO: if text is all ascii, do fast path with no uniscribe | |
106 | 460 void drawText(cstring text, double x, double y) { |
0 | 461 auto extents = getFontExtents; |
462 cairo_font_extents_t fextents; | |
463 cairo_font_extents(cr, &fextents); | |
464 cairo_move_to(cr, x, y + fextents.ascent); | |
465 cairo_show_text(cr, toCharPtr(text)); // 99% of time spent in show_text | |
466 checkStatus(); | |
467 } | |
468 /// | |
106 | 469 Size getTextExtents(cstring text) { |
0 | 470 cairo_text_extents_t textents; |
471 cairo_text_extents(cr, toCharPtr(text), &textents); | |
472 cairo_font_extents_t fextents; | |
473 cairo_font_extents(cr, &fextents); | |
474 return Size(textents.x_advance, fextents.height); | |
475 } | |
476 /// | |
477 FontExtents getFontExtents() { // TODO: make property? | |
478 cairo_font_extents_t fextents; | |
479 cairo_font_extents(cr, &fextents); | |
480 FontExtents extents; | |
481 extents.ascent = fextents.ascent; | |
482 extents.descent = fextents.descent; | |
483 extents.height = fextents.height; | |
484 extents.maxAdvance = fextents.max_x_advance; | |
485 return extents; | |
486 } | |
487 /// | |
488 Rect getClipExtents() { // TODO: make property? | |
489 double x, y, width, height; | |
490 cairo_clip_extents(cr, &x, &y, &width, &height); | |
491 return Rect(x, y, width, height); | |
492 } | |
493 /// | |
494 void save() { | |
495 cairo_save(cr); | |
496 } | |
497 /// | |
498 void restore() { | |
499 cairo_restore(cr); | |
500 checkStatus(); | |
501 } | |
502 /// | |
503 void clip() { | |
504 cairo_clip(cr); | |
505 } | |
506 /// | |
507 void translate(Point pt) { | |
508 translate(pt.x, pt.y); | |
509 } | |
510 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
511 void translate(double x, double y) { |
0 | 512 cairo_translate(cr, x, y); |
513 } | |
514 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
515 void scale(double x, double y) { |
0 | 516 cairo_scale(cr, x, y); |
517 } | |
518 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
519 void rotate(double angle) { |
0 | 520 cairo_rotate(cr, angle); |
521 } | |
522 /// | |
523 GraphicsOperator operator() { | |
524 return cast(GraphicsOperator)cairo_get_operator(cr); | |
525 } | |
526 /// | |
527 void operator(GraphicsOperator op) { | |
528 cairo_set_operator(cr, cast(cairo_operator_t)op); | |
529 } | |
530 /** | |
531 * Sets the dash pattern to be used when lines are drawn. | |
532 */ | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
533 void setDash(double[] dashes, double offset) { |
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
534 cairo_set_dash(cr, dashes.ptr, dashes.length, offset); |
0 | 535 } |
536 /** | |
537 * Gets or sets the fill rule the current fill rule. | |
538 * The default is GraphicsFillRule.Winding. | |
539 */ | |
540 GraphicsFillRule fillRule() { | |
541 return cast(GraphicsFillRule)cairo_get_fill_rule(cr); | |
542 } | |
543 /// ditto | |
544 void fillRule(GraphicsFillRule rule) { | |
545 cairo_set_fill_rule(cr, cast(cairo_fill_rule_t)rule); | |
546 } | |
547 /** | |
106 | 548 * The temporary surface created will be the same size as the current clip. To speed up using this function, call clip() to the area you will be drawing in. |
0 | 549 */ |
550 void pushGroup() { | |
551 cairo_push_group(cr); | |
552 } | |
553 //popGroup() { // TODO: returning a pattern | |
554 // cairo_pop_group(cr); | |
555 //} | |
556 /** | |
106 | 557 * Terminates the redirection begun by a call to pushGroup() or |
558 * pushGroupWithContent() and installs the resulting pattern as the | |
0 | 559 * source pattern. |
560 */ | |
561 void popGroupToSource() { | |
562 cairo_pop_group_to_source(cr); | |
563 checkStatus(); | |
564 } | |
565 // TODO: figure out the best way to set the source and get the source | |
566 void source(Color c) { | |
567 cairo_set_source_rgba(cr, c.R/255.0, c.G/255.0, c.B/255.0, c.A/255.0); | |
568 } | |
569 //void source(Pattern s) {} | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
570 //void setSource(Surface s, double x = 0, double y = 0) {} |
0 | 571 // TODO: remove this function and have users do: |
572 // g.setSource(img, x, y); | |
573 // g.paint(); | |
574 // ??? | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
575 // paintSource(Image, double, double) ? |
0 | 576 /// Draws the specified image unscaled. |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
577 void drawImage(Image image, double x, double y) { |
0 | 578 auto surface= cairo_image_surface_create_for_data(cast(char*)image.data, |
579 CAIRO_FORMAT_ARGB32, image.width, image.height, image.width*4); | |
580 save(); | |
581 cairo_set_source_surface(cr, surface, x, y); | |
582 cairo_paint(cr); | |
583 restore(); | |
584 cairo_surface_destroy(surface); | |
585 } | |
586 // Draws the specified image scaled to the specified width and height. | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
587 //void drawImage(Image image, double x, double y, double width, double height); |
0 | 588 } |