Remove duplicate licenses
[mono.git] / mcs / class / Mono.Cairo / Mono.Cairo / Graphics.cs
1 //
2 // Mono.Cairo.Graphics.cs
3 //
4 // Author:
5 //   Duncan Mak (duncan@ximian.com)
6 //   Miguel de Icaza (miguel@novell.com)
7 //
8 // (C) Ximian Inc, 2003.
9 // (C) Novell Inc, 2003.
10 //
11 // This is an OO wrapper API for the Cairo API.
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System;
36 using System.Drawing;
37 using System.Runtime.InteropServices;
38 using Cairo;
39
40 namespace Cairo {
41
42         public class Graphics : IDisposable 
43         {
44                 internal IntPtr state = IntPtr.Zero;
45
46                 public Graphics ()
47                 {
48                         state = CairoAPI.cairo_create ();
49                 }
50
51                 private Graphics (IntPtr state)
52                 {
53                         this.state = state;
54                 }
55                 
56                 ~Graphics ()
57                 {
58                         Console.WriteLine ("Cairo not thread safe, you might want to call IDisposable.Dispose on Cairo.Surface");
59
60                 }
61
62                 void IDisposable.Dispose ()
63                 {
64                         Dispose (true);
65                         GC.SuppressFinalize (this);
66                 }
67                 
68                 protected virtual void Dispose (bool disposing)
69                 {
70                         if (!disposing){
71                                 Console.WriteLine ("Cairo.Graphics: called from thread");
72                                 return;
73                         }
74                         
75                         if (state == (IntPtr) 0)
76                                 return;
77
78                         CairoAPI.cairo_destroy (state);
79                         state = (IntPtr) 0;
80                 }
81
82                 public Cairo.Graphics Copy ()
83                 {
84                         IntPtr dest;
85                         CairoAPI.cairo_copy (out dest, state);
86                         return new Cairo.Graphics (dest);
87                 }
88                 
89                 public void Save ()
90                 {
91                         CairoAPI.cairo_save (state);
92                 }
93
94                 public void Restore ()
95                 {
96                         CairoAPI.cairo_restore (state);
97                 }
98                 
99                 public Cairo.Status Status {
100                         get {
101                                 return CairoAPI.cairo_status (state);
102                         }
103                 }
104
105                 public string StatusString {
106                         get {
107                                 return CairoAPI.cairo_status_string (state);
108                         }
109                 }
110
111                 public IntPtr Handle {
112                         get {
113                                 return state;
114                         }
115                 }
116                 
117                 public Cairo.Operator Operator {
118                         set {
119                                 CairoAPI.cairo_set_operator (state, value);
120                         }
121
122                         get {
123                                 return CairoAPI.cairo_current_operator (state);
124                         }
125                 }
126                 
127                 public void SetRGBColor (double r, double g, double b)
128                 {
129                         CairoAPI.cairo_set_rgb_color (state, r, g, b);
130                 }
131
132                 public double Tolerance {
133                         set {
134                                 CairoAPI.cairo_set_tolerance (state, value);
135                         }
136
137                         get {
138                                 return CairoAPI.cairo_current_tolerance (state);
139                         }
140                 }                                
141
142                 public double Alpha {
143                         set {
144                                 CairoAPI.cairo_set_alpha (state, value);
145                         }
146
147                         get {
148                                 return CairoAPI.cairo_current_alpha (state);
149                         }
150                 }
151                 
152                 public Cairo.FillRule FillRule {
153                         set {
154                                 CairoAPI.cairo_set_fill_rule (state, value);
155                         }
156
157                         get {
158                                 return CairoAPI.cairo_current_fill_rule (state);
159                         }
160                 }
161                                         
162                 public double LineWidth {
163                         set {
164                                 CairoAPI.cairo_set_line_width (state, value);
165                         }
166
167                         get {
168                                 return CairoAPI.cairo_current_line_width (state);
169                         }
170                 }
171
172                 public Cairo.LineCap LineCap {
173                         set {
174                                 CairoAPI.cairo_set_line_cap (state, value);
175                         }
176
177                         get {
178                                 return CairoAPI.cairo_current_line_cap (state);
179                         }
180                 }
181
182                 public Cairo.LineJoin LineJoin {
183                         set {
184                                 CairoAPI.cairo_set_line_join (state, value);
185                         }
186
187                         get {
188                                 return CairoAPI.cairo_current_line_join (state);
189                         }
190                 }
191
192                 public void SetDash (double [] dashes, int ndash, double offset)
193                 {
194                         CairoAPI.cairo_set_dash (state, dashes, ndash, offset);
195                 }
196
197                 public Cairo.Surface Pattern {
198                         set {
199                                 CairoAPI.cairo_set_pattern (state, value.Handle);
200                         }
201                 }
202
203                 public double MiterLimit {
204                         set {
205                                 CairoAPI.cairo_set_miter_limit (state, value);
206                         }
207
208                         get {
209                                 return CairoAPI.cairo_current_miter_limit (state);
210                         }
211                 }
212
213                 public void GetCurrentPoint (out double x, out double y)
214                 {
215                         CairoAPI.cairo_current_point (state, out x, out y);
216                 }
217
218                 public Point CurrentPoint {
219                         get {
220                                 double x, y;
221                                 CairoAPI.cairo_current_point (state, out x, out y);
222                                 return new Point ((int) x, (int) y);
223                         }
224                 }
225
226                 public Cairo.Surface TargetSurface {
227                         set {
228                                 CairoAPI.cairo_set_target_surface (state, value.Handle);
229                         }
230
231                         get {
232                                 return Cairo.Surface.LookupExternalSurface (
233                                         CairoAPI.cairo_current_target_surface (state));
234                         }
235                 }
236
237 #region Path methods
238                 
239                 public void NewPath ()
240                 {
241                         CairoAPI.cairo_new_path (state);
242                 }
243                 
244                 public void MoveTo (double x, double y)
245                 {
246                         CairoAPI.cairo_move_to (state, x, y);
247                 }
248                 
249                 public void LineTo (double x, double y)
250                 {
251                         CairoAPI.cairo_line_to (state, x, y);
252                 }
253
254                 public void CurveTo (double x1, double y1, double x2, double y2, double x3, double y3)
255                 {
256                         CairoAPI.cairo_curve_to (state, x1, y1, x2, y2, x3, y3);
257                 }
258
259                 public void CurveTo (Point p1, Point p2, Point p3)
260                 {
261                         CairoAPI.cairo_curve_to (state, p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y);
262                 }
263
264                 public void RelMoveTo (double dx, double dy)
265                 {
266                         CairoAPI.cairo_rel_move_to (state, dx, dy);
267                 }
268
269                 public void RelLineTo (double dx, double dy)
270                 {
271                         CairoAPI.cairo_rel_line_to (state, dx, dy);
272                 }
273
274                 public void RelCurveTo (double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)
275                 {
276                         CairoAPI.cairo_rel_curve_to (state, dx1, dy1, dx2, dy2, dx3, dy3); 
277                 }
278
279                 public void Arc (double xc, double yc, double radius, double angel1, double angel2)
280                 {
281                         CairoAPI.cairo_arc (state, xc, yc, radius, angel1, angel2);
282                 }
283
284                 public void ArcNegative (double xc, double yc, double radius, double angel1, double angel2)
285                 {
286                         CairoAPI.cairo_arc_negative (state, xc, yc, radius, angel1, angel2);
287                 }
288                 
289                 public void Rectangle (double x, double y, double width, double height)
290                 {
291                         CairoAPI.cairo_rectangle (state, x, y, width, height);
292                 }
293                 
294                 public void ClosePath ()
295                 {
296                         CairoAPI.cairo_close_path (state);
297                 }
298 #endregion
299
300 #region Painting Methods
301
302                 public void Stroke ()
303                 {
304                         CairoAPI.cairo_stroke (state);
305                 }
306
307                 public void Fill ()
308                 {
309                         CairoAPI.cairo_fill (state);
310                 }
311
312 #endregion
313
314                 public void Clip ()
315                 {
316                         CairoAPI.cairo_clip (state);
317                 }
318
319 #region Modified state
320
321                 public void SetTargetImage (
322                         string data, Cairo.Format format, int width, int height, int stride)
323                 {
324                         CairoAPI.cairo_set_target_image (state, data, format, width, height, stride);
325                 }
326
327                 public void SetTargetDrawable (IntPtr dpy, IntPtr drawable)
328                 {
329                         CairoAPI.cairo_set_target_drawable (state, dpy, drawable);
330                 }
331
332                 public void SetPattern (Pattern pattern)
333                 {
334                         CairoAPI.cairo_set_pattern (state, pattern.Pointer);
335                 }
336 #endregion
337
338                 public void Rotate (double angle)
339                 {
340                         CairoAPI.cairo_rotate (state, angle);
341                 }
342
343                 public void Scale (double sx, double sy)
344                 {
345                         CairoAPI.cairo_scale (state, sx, sy);
346                 }
347
348                 public void Translate (double tx, double ty)
349                 {
350                         CairoAPI.cairo_translate (state, tx, ty);
351                 }
352
353                 public void TransformPoint (ref double x, ref double y)
354                 {
355                         CairoAPI.cairo_transform_point (state, ref x, ref y);
356                 }
357
358                 public void TransformDistance (ref double dx, ref double dy)
359                 {
360                         CairoAPI.cairo_transform_distance (state, ref dx, ref dy);
361                 }
362
363                 public void InverseTransformPoint (ref double x, ref double y)
364                 {
365                         CairoAPI.cairo_inverse_transform_point (state, ref x, ref y);
366                 }
367
368                 public void InverseTransformDistance (ref double dx, ref double dy)
369                 {
370                         CairoAPI.cairo_inverse_transform_distance (state, ref dx, ref dy);
371                 }
372
373                 public void ConcatMatrix (Cairo.Matrix matrix)
374                 {
375                         CairoAPI.cairo_concat_matrix (state, matrix.Pointer);
376                 }
377
378                 public Cairo.Matrix Matrix {
379                         set {
380                                 CairoAPI.cairo_set_matrix (state, value.Pointer);
381                         }
382
383                         get {
384                                                                 IntPtr p = CairoAPI.cairo_matrix_create ();
385                                                                 CairoAPI.cairo_current_matrix (state, p);
386                                 Matrix mat = new Cairo.Matrix (p);
387                                                                 return mat;
388                         }
389                 }
390
391                 public Font Font {
392                         set {
393                                 CairoAPI.cairo_set_font (state, value.Pointer);
394
395                         }
396
397                         get {
398                                 IntPtr fnt = IntPtr.Zero;
399
400                                 fnt = CairoAPI.cairo_current_font (state);
401
402                                 return new Font (fnt);
403                         }
404                 }
405
406
407                 public void ScaleFont (double scale)
408                 {
409                         CairoAPI.cairo_scale_font (state, scale);
410                 }
411
412                 public void SetText (string str)
413                 {
414                         /* Use UTF8 encoding*/
415                         CairoAPI.cairo_show_text (state, str);
416                 }
417                 
418                 public void TransformFont (Matrix matrix)
419                 {
420                         CairoAPI.cairo_transform_font (state, matrix.Pointer);
421                 }
422
423
424                 
425                 static internal IntPtr FromGlyphToUnManagedMemory(Glyph [] glyphs)
426                 {
427                         int size =  Marshal.SizeOf (glyphs[0]);
428                         IntPtr dest = Marshal.AllocHGlobal (size * glyphs.Length);
429                         int pos = dest.ToInt32();
430
431                         for (int i=0; i < glyphs.Length; i++, pos += size)
432                                 Marshal.StructureToPtr (glyphs[i], (IntPtr)pos, false);
433
434                         return dest;
435                 }
436
437
438                 public void ShowGlyphs (Matrix matrix, Glyph[] glyphs)
439                 {
440
441                         IntPtr ptr;
442
443                         ptr = FromGlyphToUnManagedMemory (glyphs);
444                         
445                         CairoAPI.cairo_show_glyphs (state, ptr, glyphs.Length);
446
447                         Marshal.FreeHGlobal (ptr);              
448                      
449                 }
450
451                 public void TextPath (string str)
452                 {
453                         CairoAPI.cairo_text_path  (state, str);
454                 }
455
456                 public void GlyphPath (Matrix matrix, Glyph[] glyphs)
457                 {
458
459                         IntPtr ptr;
460
461                         ptr = FromGlyphToUnManagedMemory (glyphs);
462
463                         CairoAPI.cairo_glyph_path (state, ptr, glyphs.Length);
464
465                         Marshal.FreeHGlobal (ptr);
466
467                 }
468
469                 public void SelectFont (string key, FontSlant slant, FontWeight weight)
470                 {
471                         CairoAPI.cairo_select_font (state, key, slant, weight);
472                 }
473
474
475
476                 public Extents Extents {
477                         get {
478
479                                 Extents extents = new Extents();
480                                 CairoAPI.cairo_current_font_extents (state, ref extents);
481                                 return extents;
482                         }
483                 }
484
485         }
486 }