1 // 2 // Mono.Cairo.Context.cs 3 // 4 // Author: 5 // Duncan Mak (duncan@ximian.com) 6 // Miguel de Icaza (miguel@novell.com) 7 // Hisham Mardam Bey (hisham.mardambey@gmail.com) 8 // Alp Toker (alp@atoker.com) 9 // 10 // (C) Ximian Inc, 2003. 11 // (C) Novell Inc, 2003. 12 // 13 // This is an OO wrapper API for the Cairo API. 14 // 15 // Copyright (C) 2004 Novell, Inc (http://www.novell.com) 16 // 17 // Permission is hereby granted, free of charge, to any person obtaining 18 // a copy of this software and associated documentation files (the 19 // "Software"), to deal in the Software without restriction, including 20 // without limitation the rights to use, copy, modify, merge, publish, 21 // distribute, sublicense, and/or sell copies of the Software, and to 22 // permit persons to whom the Software is furnished to do so, subject to 23 // the following conditions: 24 // 25 // The above copyright notice and this permission notice shall be 26 // included in all copies or substantial portions of the Software. 27 // 28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 // 36 37 using System; 38 using System.Runtime.InteropServices; 39 using System.Text; 40 using Cairo; 41 42 namespace Cairo { 43 44 [Obsolete ("Renamed Cairo.Context per suggestion from cairo binding guidelines.")] 45 public class Graphics : Context { Graphics(IntPtr state)46 public Graphics (IntPtr state) : base (state) {} Graphics(Surface surface)47 public Graphics (Surface surface) : base (surface) {} 48 } 49 50 public class Context : IDisposable 51 { 52 IntPtr handle = IntPtr.Zero; 53 54 static int native_glyph_size, c_compiler_long_size; 55 Context()56 static Context () 57 { 58 // 59 // This is used to determine what kind of structure 60 // we should use to marshal Glyphs, as the public 61 // definition in Cairo uses `long', which can be 62 // 32 bits or 64 bits depending on the platform. 63 // 64 // We assume that sizeof(long) == sizeof(void*) 65 // except in the case of Win64 where sizeof(long) 66 // is 32 bits 67 // 68 int ptr_size = Marshal.SizeOf (typeof (IntPtr)); 69 70 PlatformID platform = Environment.OSVersion.Platform; 71 if (platform == PlatformID.Win32NT || 72 platform == PlatformID.Win32S || 73 platform == PlatformID.Win32Windows || 74 platform == PlatformID.WinCE || 75 ptr_size == 4){ 76 c_compiler_long_size = 4; 77 native_glyph_size = Marshal.SizeOf (typeof (NativeGlyph_4byte_longs)); 78 } else { 79 c_compiler_long_size = 8; 80 native_glyph_size = Marshal.SizeOf (typeof (Glyph)); 81 } 82 } 83 Context(Surface surface)84 public Context (Surface surface) : this (NativeMethods.cairo_create (surface.Handle), true) 85 { 86 } 87 Context(IntPtr handle, bool owner)88 public Context (IntPtr handle, bool owner) 89 { 90 if (handle == IntPtr.Zero) 91 throw new ArgumentException ("handle should not be NULL", "handle"); 92 93 this.handle = handle; 94 if (!owner) 95 NativeMethods.cairo_reference (handle); 96 if (CairoDebug.Enabled) 97 CairoDebug.OnAllocated (handle); 98 } 99 100 [Obsolete] Context(IntPtr state)101 public Context (IntPtr state) : this (state, true) 102 { 103 } 104 ~Context()105 ~Context () 106 { 107 Dispose (false); 108 } 109 Dispose()110 public void Dispose () 111 { 112 Dispose (true); 113 GC.SuppressFinalize (this); 114 } 115 Dispose(bool disposing)116 protected virtual void Dispose (bool disposing) 117 { 118 if (!disposing || CairoDebug.Enabled) 119 CairoDebug.OnDisposed<Context> (handle, disposing); 120 121 if (handle == IntPtr.Zero) 122 return; 123 124 NativeMethods.cairo_destroy (handle); 125 handle = IntPtr.Zero; 126 } 127 CheckDisposed()128 void CheckDisposed () 129 { 130 if (handle == IntPtr.Zero) 131 throw new ObjectDisposedException ("Object has already been disposed"); 132 } 133 Save()134 public void Save () 135 { 136 CheckDisposed (); 137 NativeMethods.cairo_save (handle); 138 } 139 Restore()140 public void Restore () 141 { 142 CheckDisposed (); 143 NativeMethods.cairo_restore (handle); 144 } 145 146 public Antialias Antialias { 147 get { 148 CheckDisposed (); 149 return NativeMethods.cairo_get_antialias (handle); 150 } 151 set { 152 CheckDisposed (); 153 NativeMethods.cairo_set_antialias (handle, value); 154 } 155 } 156 157 public Cairo.Status Status { 158 get { 159 CheckDisposed (); 160 return NativeMethods.cairo_status (handle); 161 } 162 } 163 164 public IntPtr Handle { 165 get { 166 return handle; 167 } 168 } 169 170 public Operator Operator { 171 set { 172 CheckDisposed (); 173 NativeMethods.cairo_set_operator (handle, value); 174 } 175 176 get { 177 CheckDisposed (); 178 return NativeMethods.cairo_get_operator (handle); 179 } 180 } 181 182 [Obsolete ("Use SetSourceColor method")] 183 public Color Color { 184 set { 185 SetSourceColor (value); 186 } 187 } 188 189 [Obsolete ("Use SetSourceRGBA method")] 190 public Cairo.Color ColorRgb { 191 set { 192 SetSourceRGBA (value.R, value.G, value.B, value.A); 193 } 194 } 195 196 public double Tolerance { 197 get { 198 CheckDisposed (); 199 return NativeMethods.cairo_get_tolerance (handle); 200 } 201 202 set { 203 CheckDisposed (); 204 NativeMethods.cairo_set_tolerance (handle, value); 205 } 206 } 207 208 public Cairo.FillRule FillRule { 209 set { 210 CheckDisposed (); 211 NativeMethods.cairo_set_fill_rule (handle, value); 212 } 213 214 get { 215 CheckDisposed (); 216 return NativeMethods.cairo_get_fill_rule (handle); 217 } 218 } 219 220 public double LineWidth { 221 set { 222 CheckDisposed (); 223 NativeMethods.cairo_set_line_width (handle, value); 224 } 225 226 get { 227 CheckDisposed (); 228 return NativeMethods.cairo_get_line_width (handle); 229 } 230 } 231 232 public Cairo.LineCap LineCap { 233 set { 234 CheckDisposed (); 235 NativeMethods.cairo_set_line_cap (handle, value); 236 } 237 238 get { 239 CheckDisposed (); 240 return NativeMethods.cairo_get_line_cap (handle); 241 } 242 } 243 244 public Cairo.LineJoin LineJoin { 245 set { 246 CheckDisposed (); 247 NativeMethods.cairo_set_line_join (handle, value); 248 } 249 250 get { 251 CheckDisposed (); 252 return NativeMethods.cairo_get_line_join (handle); 253 } 254 } 255 SetDash(double [] dashes, double offset)256 public void SetDash (double [] dashes, double offset) 257 { 258 CheckDisposed (); 259 NativeMethods.cairo_set_dash (handle, dashes, dashes.Length, offset); 260 } 261 262 [Obsolete("Use GetSource/GetSource")] 263 public Pattern Pattern { 264 set { 265 SetSource (value); 266 } 267 get { 268 return GetSource (); 269 } 270 } 271 272 //This is obsolete because it wasn't obvious it needed to be disposed 273 [Obsolete("Use GetSource/GetSource")] 274 public Pattern Source { 275 set { 276 SetSource (value); 277 } 278 get { 279 return GetSource (); 280 } 281 } 282 SetSource(Pattern source)283 public void SetSource (Pattern source) 284 { 285 CheckDisposed (); 286 NativeMethods.cairo_set_source (handle, source.Handle); 287 } 288 GetSource()289 public Pattern GetSource () 290 { 291 CheckDisposed (); 292 var ptr = NativeMethods.cairo_get_source (handle); 293 return Cairo.Pattern.Lookup (ptr, false); 294 } 295 296 public double MiterLimit { 297 set { 298 CheckDisposed (); 299 NativeMethods.cairo_set_miter_limit (handle, value); 300 } 301 302 get { 303 CheckDisposed (); 304 return NativeMethods.cairo_get_miter_limit (handle); 305 } 306 } 307 308 public PointD CurrentPoint { 309 get { 310 CheckDisposed (); 311 double x, y; 312 NativeMethods.cairo_get_current_point (handle, out x, out y); 313 return new PointD (x, y); 314 } 315 } 316 317 public bool HasCurrentPoint { 318 get { 319 CheckDisposed (); 320 return NativeMethods.cairo_has_current_point (handle); 321 } 322 } 323 324 [Obsolete ("Use GetTarget/SetTarget")] 325 public Cairo.Surface Target { 326 set { 327 SetTarget (value); 328 } 329 330 get { 331 return GetTarget (); 332 } 333 } 334 GetTarget()335 public Surface GetTarget () 336 { 337 CheckDisposed (); 338 return Surface.Lookup (NativeMethods.cairo_get_target (handle), false); 339 } 340 SetTarget(Surface target)341 public void SetTarget (Surface target) 342 { 343 CheckDisposed (); 344 if (handle != IntPtr.Zero) 345 NativeMethods.cairo_destroy (handle); 346 handle = NativeMethods.cairo_create (target.Handle); 347 } 348 349 [Obsolete("Use GetScaledFont/SetScaledFont")] 350 public ScaledFont ScaledFont { 351 set { 352 SetScaledFont (value); 353 } 354 355 get { 356 return GetScaledFont (); 357 } 358 } 359 GetScaledFont()360 public ScaledFont GetScaledFont () 361 { 362 CheckDisposed (); 363 return new ScaledFont (NativeMethods.cairo_get_scaled_font (handle), false); 364 } 365 SetScaledFont(ScaledFont font)366 public void SetScaledFont (ScaledFont font) 367 { 368 CheckDisposed (); 369 NativeMethods.cairo_set_scaled_font (handle, font.Handle); 370 } 371 372 public uint ReferenceCount { 373 get { 374 CheckDisposed (); 375 return NativeMethods.cairo_get_reference_count (handle); 376 } 377 } 378 SetSourceColor(Color color)379 public void SetSourceColor (Color color) 380 { 381 CheckDisposed (); 382 NativeMethods.cairo_set_source_rgba (handle, color.R, color.G, color.B, color.A); 383 } 384 SetSourceRGB(double r, double g, double b)385 public void SetSourceRGB (double r, double g, double b) 386 { 387 CheckDisposed (); 388 NativeMethods.cairo_set_source_rgb (handle, r, g, b); 389 } 390 SetSourceRGBA(double r, double g, double b, double a)391 public void SetSourceRGBA (double r, double g, double b, double a) 392 { 393 CheckDisposed (); 394 NativeMethods.cairo_set_source_rgba (handle, r, g, b, a); 395 } 396 397 //[Obsolete ("Use SetSource method (with double parameters)")] SetSourceSurface(Surface source, int x, int y)398 public void SetSourceSurface (Surface source, int x, int y) 399 { 400 CheckDisposed (); 401 NativeMethods.cairo_set_source_surface (handle, source.Handle, x, y); 402 } 403 SetSource(Surface source, double x, double y)404 public void SetSource (Surface source, double x, double y) 405 { 406 CheckDisposed (); 407 NativeMethods.cairo_set_source_surface (handle, source.Handle, x, y); 408 } 409 SetSource(Surface source)410 public void SetSource (Surface source) 411 { 412 CheckDisposed (); 413 NativeMethods.cairo_set_source_surface (handle, source.Handle, 0, 0); 414 } 415 416 #region Path methods 417 NewPath()418 public void NewPath () 419 { 420 CheckDisposed (); 421 NativeMethods.cairo_new_path (handle); 422 } 423 NewSubPath()424 public void NewSubPath () 425 { 426 CheckDisposed (); 427 NativeMethods.cairo_new_sub_path (handle); 428 } 429 MoveTo(PointD p)430 public void MoveTo (PointD p) 431 { 432 MoveTo (p.X, p.Y); 433 } 434 MoveTo(double x, double y)435 public void MoveTo (double x, double y) 436 { 437 CheckDisposed (); 438 NativeMethods.cairo_move_to (handle, x, y); 439 } 440 LineTo(PointD p)441 public void LineTo (PointD p) 442 { 443 LineTo (p.X, p.Y); 444 } 445 LineTo(double x, double y)446 public void LineTo (double x, double y) 447 { 448 CheckDisposed (); 449 NativeMethods.cairo_line_to (handle, x, y); 450 } 451 CurveTo(PointD p1, PointD p2, PointD p3)452 public void CurveTo (PointD p1, PointD p2, PointD p3) 453 { 454 CurveTo (p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y); 455 } 456 CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)457 public void CurveTo (double x1, double y1, double x2, double y2, double x3, double y3) 458 { 459 CheckDisposed (); 460 NativeMethods.cairo_curve_to (handle, x1, y1, x2, y2, x3, y3); 461 } 462 RelMoveTo(Distance d)463 public void RelMoveTo (Distance d) 464 { 465 RelMoveTo (d.Dx, d.Dy); 466 } 467 RelMoveTo(double dx, double dy)468 public void RelMoveTo (double dx, double dy) 469 { 470 CheckDisposed (); 471 NativeMethods.cairo_rel_move_to (handle, dx, dy); 472 } 473 RelLineTo(Distance d)474 public void RelLineTo (Distance d) 475 { 476 RelLineTo (d.Dx, d.Dy); 477 } 478 RelLineTo(double dx, double dy)479 public void RelLineTo (double dx, double dy) 480 { 481 CheckDisposed (); 482 NativeMethods.cairo_rel_line_to (handle, dx, dy); 483 } 484 RelCurveTo(Distance d1, Distance d2, Distance d3)485 public void RelCurveTo (Distance d1, Distance d2, Distance d3) 486 { 487 RelCurveTo (d1.Dx, d1.Dy, d2.Dx, d2.Dy, d3.Dx, d3.Dy); 488 } 489 RelCurveTo(double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)490 public void RelCurveTo (double dx1, double dy1, double dx2, double dy2, double dx3, double dy3) 491 { 492 CheckDisposed (); 493 NativeMethods.cairo_rel_curve_to (handle, dx1, dy1, dx2, dy2, dx3, dy3); 494 } 495 Arc(double xc, double yc, double radius, double angle1, double angle2)496 public void Arc (double xc, double yc, double radius, double angle1, double angle2) 497 { 498 CheckDisposed (); 499 NativeMethods.cairo_arc (handle, xc, yc, radius, angle1, angle2); 500 } 501 ArcNegative(double xc, double yc, double radius, double angle1, double angle2)502 public void ArcNegative (double xc, double yc, double radius, double angle1, double angle2) 503 { 504 CheckDisposed (); 505 NativeMethods.cairo_arc_negative (handle, xc, yc, radius, angle1, angle2); 506 } 507 Rectangle(Rectangle rectangle)508 public void Rectangle (Rectangle rectangle) 509 { 510 Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); 511 } 512 Rectangle(PointD p, double width, double height)513 public void Rectangle (PointD p, double width, double height) 514 { 515 Rectangle (p.X, p.Y, width, height); 516 } 517 Rectangle(double x, double y, double width, double height)518 public void Rectangle (double x, double y, double width, double height) 519 { 520 CheckDisposed (); 521 NativeMethods.cairo_rectangle (handle, x, y, width, height); 522 } 523 ClosePath()524 public void ClosePath () 525 { 526 CheckDisposed (); 527 NativeMethods.cairo_close_path (handle); 528 } 529 CopyPath()530 public Path CopyPath () 531 { 532 CheckDisposed (); 533 return new Path (NativeMethods.cairo_copy_path (handle)); 534 } 535 CopyPathFlat()536 public Path CopyPathFlat () 537 { 538 CheckDisposed (); 539 return new Path (NativeMethods.cairo_copy_path_flat (handle)); 540 } 541 AppendPath(Path path)542 public void AppendPath (Path path) 543 { 544 CheckDisposed (); 545 NativeMethods.cairo_append_path (handle, path.Handle); 546 } 547 548 #endregion 549 550 #region Painting Methods Paint()551 public void Paint () 552 { 553 CheckDisposed (); 554 NativeMethods.cairo_paint (handle); 555 } 556 PaintWithAlpha(double alpha)557 public void PaintWithAlpha (double alpha) 558 { 559 CheckDisposed (); 560 NativeMethods.cairo_paint_with_alpha (handle, alpha); 561 } 562 Mask(Pattern pattern)563 public void Mask (Pattern pattern) 564 { 565 CheckDisposed (); 566 NativeMethods.cairo_mask (handle, pattern.Handle); 567 } 568 MaskSurface(Surface surface, double surface_x, double surface_y)569 public void MaskSurface (Surface surface, double surface_x, double surface_y) 570 { 571 CheckDisposed (); 572 NativeMethods.cairo_mask_surface (handle, surface.Handle, surface_x, surface_y); 573 } 574 Stroke()575 public void Stroke () 576 { 577 CheckDisposed (); 578 NativeMethods.cairo_stroke (handle); 579 } 580 StrokePreserve()581 public void StrokePreserve () 582 { 583 CheckDisposed (); 584 NativeMethods.cairo_stroke_preserve (handle); 585 } 586 StrokeExtents()587 public Rectangle StrokeExtents () 588 { 589 CheckDisposed (); 590 double x1, y1, x2, y2; 591 NativeMethods.cairo_stroke_extents (handle, out x1, out y1, out x2, out y2); 592 return new Rectangle (x1, y1, x2 - x1, y2 - y1); 593 } 594 Fill()595 public void Fill () 596 { 597 CheckDisposed (); 598 NativeMethods.cairo_fill (handle); 599 } 600 FillExtents()601 public Rectangle FillExtents () 602 { 603 CheckDisposed (); 604 double x1, y1, x2, y2; 605 NativeMethods.cairo_fill_extents (handle, out x1, out y1, out x2, out y2); 606 return new Rectangle (x1, y1, x2 - x1, y2 - y1); 607 } 608 FillPreserve()609 public void FillPreserve () 610 { 611 CheckDisposed (); 612 NativeMethods.cairo_fill_preserve (handle); 613 } 614 615 #endregion 616 Clip()617 public void Clip () 618 { 619 CheckDisposed (); 620 NativeMethods.cairo_clip (handle); 621 } 622 ClipPreserve()623 public void ClipPreserve () 624 { 625 CheckDisposed (); 626 NativeMethods.cairo_clip_preserve (handle); 627 } 628 ResetClip()629 public void ResetClip () 630 { 631 CheckDisposed (); 632 NativeMethods.cairo_reset_clip (handle); 633 } 634 InStroke(double x, double y)635 public bool InStroke (double x, double y) 636 { 637 CheckDisposed (); 638 return NativeMethods.cairo_in_stroke (handle, x, y); 639 } 640 InClip(double x, double y)641 public bool InClip (double x, double y) 642 { 643 CheckDisposed (); 644 return NativeMethods.cairo_in_clip (handle, x, y); 645 } 646 InFill(double x, double y)647 public bool InFill (double x, double y) 648 { 649 CheckDisposed (); 650 return NativeMethods.cairo_in_fill (handle, x, y); 651 } 652 PopGroup()653 public Pattern PopGroup () 654 { 655 CheckDisposed (); 656 return Pattern.Lookup (NativeMethods.cairo_pop_group (handle), true); 657 } 658 PopGroupToSource()659 public void PopGroupToSource () 660 { 661 CheckDisposed (); 662 NativeMethods.cairo_pop_group_to_source (handle); 663 } 664 PushGroup()665 public void PushGroup () 666 { 667 CheckDisposed (); 668 NativeMethods.cairo_push_group (handle); 669 } 670 PushGroup(Content content)671 public void PushGroup (Content content) 672 { 673 CheckDisposed (); 674 NativeMethods.cairo_push_group_with_content (handle, content); 675 } 676 677 [Obsolete ("Use GetGroupTarget()")] 678 public Surface GroupTarget { 679 get { 680 return GetGroupTarget (); 681 } 682 } 683 GetGroupTarget()684 public Surface GetGroupTarget () 685 { 686 CheckDisposed (); 687 IntPtr surface = NativeMethods.cairo_get_group_target (handle); 688 return Surface.Lookup (surface, false); 689 } 690 Rotate(double angle)691 public void Rotate (double angle) 692 { 693 CheckDisposed (); 694 NativeMethods.cairo_rotate (handle, angle); 695 } 696 Scale(double sx, double sy)697 public void Scale (double sx, double sy) 698 { 699 CheckDisposed (); 700 NativeMethods.cairo_scale (handle, sx, sy); 701 } 702 Translate(double tx, double ty)703 public void Translate (double tx, double ty) 704 { 705 CheckDisposed (); 706 NativeMethods.cairo_translate (handle, tx, ty); 707 } 708 Transform(Matrix m)709 public void Transform (Matrix m) 710 { 711 CheckDisposed (); 712 NativeMethods.cairo_transform (handle, m); 713 } 714 715 [Obsolete("Use UserToDevice instead")] TransformPoint(ref double x, ref double y)716 public void TransformPoint (ref double x, ref double y) 717 { 718 UserToDevice (ref x, ref y); 719 } 720 721 [Obsolete("Use UserToDeviceDistance instead")] TransformDistance(ref double dx, ref double dy)722 public void TransformDistance (ref double dx, ref double dy) 723 { 724 UserToDevice (ref dx, ref dy); 725 } 726 727 [Obsolete("Use DeviceToUser instead")] InverseTransformPoint(ref double x, ref double y)728 public void InverseTransformPoint (ref double x, ref double y) 729 { 730 UserToDevice (ref x, ref y); 731 } 732 733 [Obsolete("Use DeviceToUserDistance instead")] InverseTransformDistance(ref double dx, ref double dy)734 public void InverseTransformDistance (ref double dx, ref double dy) 735 { 736 DeviceToUserDistance (ref dx, ref dy); 737 } 738 UserToDevice(ref double x, ref double y)739 public void UserToDevice (ref double x, ref double y) 740 { 741 CheckDisposed (); 742 NativeMethods.cairo_user_to_device (handle, ref x, ref y); 743 } 744 UserToDeviceDistance(ref double dx, ref double dy)745 public void UserToDeviceDistance (ref double dx, ref double dy) 746 { 747 CheckDisposed (); 748 NativeMethods.cairo_user_to_device_distance (handle, ref dx, ref dy); 749 } 750 DeviceToUser(ref double x, ref double y)751 public void DeviceToUser (ref double x, ref double y) 752 { 753 CheckDisposed (); 754 NativeMethods.cairo_device_to_user (handle, ref x, ref y); 755 } 756 DeviceToUserDistance(ref double dx, ref double dy)757 public void DeviceToUserDistance (ref double dx, ref double dy) 758 { 759 CheckDisposed (); 760 NativeMethods.cairo_device_to_user_distance (handle, ref dx, ref dy); 761 } 762 763 public Matrix Matrix { 764 set { 765 CheckDisposed (); 766 NativeMethods.cairo_set_matrix (handle, value); 767 } 768 769 get { 770 CheckDisposed (); 771 Matrix m = new Matrix (); 772 NativeMethods.cairo_get_matrix (handle, m); 773 return m; 774 } 775 } 776 SetFontSize(double scale)777 public void SetFontSize (double scale) 778 { 779 CheckDisposed (); 780 NativeMethods.cairo_set_font_size (handle, scale); 781 } 782 IdentityMatrix()783 public void IdentityMatrix () 784 { 785 CheckDisposed (); 786 NativeMethods.cairo_identity_matrix (handle); 787 } 788 789 [Obsolete ("Use SetFontSize() instead.")] FontSetSize(double scale)790 public void FontSetSize (double scale) 791 { 792 SetFontSize (scale); 793 } 794 795 [Obsolete ("Use SetFontSize() instead.")] 796 public double FontSize { 797 set { SetFontSize (value); } 798 } 799 800 public Matrix FontMatrix { 801 get { 802 CheckDisposed (); 803 Matrix m; 804 NativeMethods.cairo_get_font_matrix (handle, out m); 805 return m; 806 } 807 set { 808 CheckDisposed (); 809 NativeMethods.cairo_set_font_matrix (handle, value); 810 } 811 } 812 813 public FontOptions FontOptions { 814 get { 815 CheckDisposed (); 816 FontOptions options = new FontOptions (); 817 NativeMethods.cairo_get_font_options (handle, options.Handle); 818 return options; 819 } 820 set { 821 CheckDisposed (); 822 NativeMethods.cairo_set_font_options (handle, value.Handle); 823 } 824 } 825 826 [StructLayout(LayoutKind.Sequential)] 827 internal struct NativeGlyph_4byte_longs { 828 public int index; 829 public double x; 830 public double y; 831 NativeGlyph_4byte_longsCairo.Context.NativeGlyph_4byte_longs832 public NativeGlyph_4byte_longs (Glyph source) 833 { 834 index = (int) source.index; 835 x = source.x; 836 y = source.y; 837 } 838 } 839 FromGlyphToUnManagedMemory(Glyph [] glyphs)840 static internal IntPtr FromGlyphToUnManagedMemory(Glyph [] glyphs) 841 { 842 IntPtr dest = Marshal.AllocHGlobal (native_glyph_size * glyphs.Length); 843 long pos = dest.ToInt64(); 844 845 if (c_compiler_long_size == 8){ 846 foreach (Glyph g in glyphs){ 847 Marshal.StructureToPtr (g, (IntPtr)pos, false); 848 pos += native_glyph_size; 849 } 850 } else { 851 foreach (Glyph g in glyphs){ 852 NativeGlyph_4byte_longs n = new NativeGlyph_4byte_longs (g); 853 854 Marshal.StructureToPtr (n, (IntPtr)pos, false); 855 pos += native_glyph_size; 856 } 857 } 858 859 return dest; 860 } 861 ShowGlyphs(Glyph[] glyphs)862 public void ShowGlyphs (Glyph[] glyphs) 863 { 864 CheckDisposed (); 865 866 IntPtr ptr; 867 868 ptr = FromGlyphToUnManagedMemory (glyphs); 869 870 NativeMethods.cairo_show_glyphs (handle, ptr, glyphs.Length); 871 872 Marshal.FreeHGlobal (ptr); 873 } 874 875 [Obsolete("The matrix argument was never used, use ShowGlyphs(Glyphs []) instead")] ShowGlyphs(Matrix matrix, Glyph[] glyphs)876 public void ShowGlyphs (Matrix matrix, Glyph[] glyphs) 877 { 878 ShowGlyphs (glyphs); 879 } 880 881 [Obsolete("The matrix argument was never used, use GlyphPath(Glyphs []) instead")] GlyphPath(Matrix matrix, Glyph[] glyphs)882 public void GlyphPath (Matrix matrix, Glyph[] glyphs) 883 { 884 GlyphPath (glyphs); 885 } 886 GlyphPath(Glyph[] glyphs)887 public void GlyphPath (Glyph[] glyphs) 888 { 889 CheckDisposed (); 890 891 IntPtr ptr; 892 893 ptr = FromGlyphToUnManagedMemory (glyphs); 894 895 NativeMethods.cairo_glyph_path (handle, ptr, glyphs.Length); 896 897 Marshal.FreeHGlobal (ptr); 898 } 899 900 public FontExtents FontExtents { 901 get { 902 CheckDisposed (); 903 FontExtents f_extents; 904 NativeMethods.cairo_font_extents (handle, out f_extents); 905 return f_extents; 906 } 907 } 908 CopyPage()909 public void CopyPage () 910 { 911 CheckDisposed (); 912 NativeMethods.cairo_copy_page (handle); 913 } 914 915 [Obsolete ("Use SelectFontFace() instead.")] FontFace(string family, FontSlant slant, FontWeight weight)916 public void FontFace (string family, FontSlant slant, FontWeight weight) 917 { 918 SelectFontFace (family, slant, weight); 919 } 920 921 [Obsolete("Use GetFontFace/SetFontFace")] 922 public FontFace ContextFontFace { 923 get { 924 return GetContextFontFace (); 925 } 926 set { 927 SetContextFontFace (value); 928 } 929 } 930 GetContextFontFace()931 public FontFace GetContextFontFace () 932 { 933 CheckDisposed (); 934 return Cairo.FontFace.Lookup (NativeMethods.cairo_get_font_face (handle), false); 935 } 936 SetContextFontFace(FontFace value)937 public void SetContextFontFace (FontFace value) 938 { 939 CheckDisposed (); 940 NativeMethods.cairo_set_font_face (handle, value == null ? IntPtr.Zero : value.Handle); 941 } 942 SelectFontFace(string family, FontSlant slant, FontWeight weight)943 public void SelectFontFace (string family, FontSlant slant, FontWeight weight) 944 { 945 CheckDisposed (); 946 NativeMethods.cairo_select_font_face (handle, family, slant, weight); 947 } 948 ShowPage()949 public void ShowPage () 950 { 951 CheckDisposed (); 952 NativeMethods.cairo_show_page (handle); 953 } 954 TerminateUtf8(byte[] utf8)955 private static byte[] TerminateUtf8(byte[] utf8) 956 { 957 if (utf8.Length > 0 && utf8[utf8.Length - 1] == 0) 958 return utf8; 959 var termedArray = new byte[utf8.Length + 1]; 960 Array.Copy(utf8, termedArray, utf8.Length); 961 termedArray[utf8.Length] = 0; 962 return termedArray; 963 } 964 TerminateUtf8(string s)965 private static byte[] TerminateUtf8(string s) 966 { 967 // compute the byte count including the trailing \0 968 var byteCount = Encoding.UTF8.GetMaxByteCount(s.Length + 1); 969 var bytes = new byte[byteCount]; 970 Encoding.UTF8.GetBytes(s, 0, s.Length, bytes, 0); 971 return bytes; 972 } 973 ShowText(string str)974 public void ShowText (string str) 975 { 976 CheckDisposed (); 977 NativeMethods.cairo_show_text (handle, TerminateUtf8 (str)); 978 } 979 ShowText(byte[] utf8)980 public void ShowText (byte[] utf8) 981 { 982 CheckDisposed (); 983 NativeMethods.cairo_show_text (handle, TerminateUtf8 (utf8)); 984 } 985 TextPath(string str)986 public void TextPath (string str) 987 { 988 CheckDisposed (); 989 NativeMethods.cairo_text_path (handle, TerminateUtf8 (str)); 990 } 991 TextPath(byte[] utf8)992 public void TextPath (byte[] utf8) 993 { 994 CheckDisposed (); 995 NativeMethods.cairo_text_path (handle, TerminateUtf8 (utf8)); 996 } 997 TextExtents(string s)998 public TextExtents TextExtents (string s) 999 { 1000 CheckDisposed (); 1001 TextExtents extents; 1002 NativeMethods.cairo_text_extents (handle, TerminateUtf8 (s), out extents); 1003 return extents; 1004 } 1005 TextExtents(byte[] utf8)1006 public TextExtents TextExtents(byte[] utf8) 1007 { 1008 CheckDisposed (); 1009 TextExtents extents; 1010 NativeMethods.cairo_text_extents (handle, TerminateUtf8 (utf8), out extents); 1011 return extents; 1012 } 1013 GlyphExtents(Glyph[] glyphs)1014 public TextExtents GlyphExtents (Glyph[] glyphs) 1015 { 1016 CheckDisposed (); 1017 1018 IntPtr ptr = FromGlyphToUnManagedMemory (glyphs); 1019 1020 TextExtents extents; 1021 1022 NativeMethods.cairo_glyph_extents (handle, ptr, glyphs.Length, out extents); 1023 1024 Marshal.FreeHGlobal (ptr); 1025 1026 return extents; 1027 } 1028 } 1029 } 1030