1 module skia.SKPaint; 2 3 import skia.SKObject; 4 import skia.SKFont; 5 import skia.SkiaApi; 6 import skia.SKColor; 7 import skia.SKColorF; 8 import skia.SKColorFilter; 9 import skia.SKShader; 10 import skia.SKMaskFilter; 11 import skia.SKColorSpace; 12 import skia.SKImageFilter; 13 import skia.SKTypeface; 14 import skia.Definitions; 15 import skia.SKPath; 16 import skia.MathTypes; 17 import skia.SKPathEffect; 18 import skia.SKTextBlob; 19 import skia.Exceptions; 20 21 import std.experimental.logger; 22 23 enum SKPaintHinting { 24 NoHinting = 0, 25 Slight = 1, 26 Normal = 2, 27 Full = 3, 28 } 29 30 class SKPaint : SKObject, ISKSkipObjectRegistration { 31 private SKFont font; 32 33 this(void* handle, bool owns) { 34 super(handle, owns); 35 } 36 37 this() { 38 this(SkiaApi.sk_compatpaint_new(), true); 39 if (Handle is null) { 40 throw new InvalidOperationException("Unable to create a new SKPaint instance."); 41 } 42 } 43 44 this(SKFont font) { 45 this(null, true); 46 47 if (font is null) 48 throw new ArgumentNullException(font.stringof); 49 50 Handle = SkiaApi.sk_compatpaint_new_with_font(cast(sk_font_t*) font.Handle); 51 52 if (Handle is null) 53 throw new InvalidOperationException("Unable to create a new SKPaint instance."); 54 } 55 56 protected override void Dispose(bool disposing) { 57 return super.Dispose(disposing); 58 } 59 60 override void Dispose() { 61 return super.Dispose(); 62 } 63 64 protected override void DisposeNative() { 65 return SkiaApi.sk_compatpaint_delete(cast(sk_compatpaint_t*) Handle); 66 } 67 68 // Reset 69 70 void Reset() { 71 return SkiaApi.sk_compatpaint_reset(cast(sk_compatpaint_t*) Handle); 72 } 73 74 // properties 75 76 bool IsAntialias() { 77 return SkiaApi.sk_paint_is_antialias(cast(sk_paint_t*) Handle); 78 } 79 80 void IsAntialias(bool value) { 81 SkiaApi.sk_paint_set_antialias(cast(sk_paint_t*) Handle, value); 82 } 83 84 bool IsDither() { 85 return SkiaApi.sk_paint_is_dither(cast(sk_paint_t*) Handle); 86 } 87 88 void IsDither(bool value) { 89 SkiaApi.sk_paint_set_dither(cast(sk_paint_t*) Handle, value); 90 } 91 92 bool IsVerticalText() { 93 return false; 94 } 95 96 bool IsLinearText() { 97 return GetFont().LinearMetrics; 98 } 99 100 void SubpixelText(bool value) { 101 GetFont().Subpixel = value; 102 } 103 104 bool LcdRenderText() { 105 return GetFont().Edging == SKFontEdging.SubpixelAntialias; 106 } 107 108 void LcdRenderText(bool value) { 109 GetFont().Edging = value ? SKFontEdging.SubpixelAntialias : SKFontEdging.Antialias; 110 } 111 112 bool IsEmbeddedBitmapText() { 113 return GetFont().EmbeddedBitmaps; 114 } 115 116 void IsEmbeddedBitmapText(bool value) { 117 GetFont().EmbeddedBitmaps = value; 118 } 119 120 bool IsAutohinted() { 121 return GetFont().ForceAutoHinting; 122 } 123 124 void IsAutohinted(bool value) { 125 GetFont().ForceAutoHinting = value; 126 } 127 128 SKPaintHinting HintingLevel() { 129 return cast(SKPaintHinting) GetFont().Hinting; 130 } 131 132 void HintingLevel(SKPaintHinting value) { 133 GetFont().Hinting = cast(SKFontHinting) value; 134 } 135 136 bool FakeBoldText() { 137 return GetFont().Embolden; 138 } 139 140 void FakeBoldText(bool value) { 141 GetFont().Embolden = value; 142 } 143 144 bool DeviceKerningEnabled() { 145 return false; 146 } 147 148 bool IsStroke() { 149 return Style != SKPaintStyle.Fill; 150 } 151 152 void IsStroke(bool value) { 153 Style = value ? SKPaintStyle.Stroke : SKPaintStyle.Fill; 154 } 155 156 SKPaintStyle Style() { 157 return SkiaApi.sk_paint_get_style(cast(sk_paint_t*) Handle); 158 } 159 160 void Style(SKPaintStyle value) { 161 SkiaApi.sk_paint_set_style(cast(sk_paint_t*) Handle, value); 162 } 163 164 SKColor Color() { 165 return cast(SKColor) SkiaApi.sk_paint_get_color(cast(sk_paint_t*) Handle); 166 } 167 168 void Color(SKColor value) { 169 SkiaApi.sk_paint_set_color(cast(sk_paint_t*) Handle, cast(uint) value); 170 } 171 172 SKColorF ColorF() { 173 174 SKColorF color4f; 175 SkiaApi.sk_paint_get_color4f(cast(sk_paint_t*) Handle, &color4f); 176 return color4f; 177 } 178 179 void ColorF(SKColorF value) { 180 181 SkiaApi.sk_paint_set_color4f(cast(sk_paint_t*) Handle, &value, null); 182 } 183 184 void SetColor(SKColorF color, SKColorSpace colorspace) { 185 return SkiaApi.sk_paint_set_color4f(cast(sk_paint_t*) Handle, &color, 186 cast(sk_colorspace_t*)(colorspace.Handle ? colorspace.Handle : null)); 187 } 188 189 float StrokeWidth() { 190 return SkiaApi.sk_paint_get_stroke_width(cast(sk_paint_t*) Handle); 191 } 192 193 void StrokeWidth(float value) { 194 SkiaApi.sk_paint_set_stroke_width(cast(sk_paint_t*) Handle, value); 195 } 196 197 float StrokeMiter() { 198 return SkiaApi.sk_paint_get_stroke_miter(cast(sk_paint_t*) Handle); 199 } 200 201 void StrokeMiter(float value) { 202 SkiaApi.sk_paint_get_stroke_miter(cast(sk_paint_t*) Handle); 203 } 204 205 SKStrokeCap StrokeCap() { 206 return SkiaApi.sk_paint_get_stroke_cap(cast(sk_paint_t*) Handle); 207 } 208 209 void StrokeCap(SKStrokeCap value) { 210 SkiaApi.sk_paint_set_stroke_cap(cast(sk_paint_t*) Handle, value); 211 } 212 213 SKStrokeJoin StrokeJoin() { 214 return SkiaApi.sk_paint_get_stroke_join(cast(sk_paint_t*) Handle); 215 } 216 217 void StrokeJoin(SKStrokeJoin value) { 218 SkiaApi.sk_paint_set_stroke_join(cast(sk_paint_t*) Handle, value); 219 } 220 221 SKShader Shader() { 222 return SKShader.GetObject(SkiaApi.sk_paint_get_shader(cast(sk_paint_t*) Handle)); 223 } 224 225 void Shader(SKShader value) { 226 SkiaApi.sk_paint_set_shader(cast(sk_paint_t*) Handle, 227 cast(sk_shader_t*)(value is null ? null : value.Handle)); 228 } 229 230 SKMaskFilter MaskFilter() { 231 return SKMaskFilter.GetObject(SkiaApi.sk_paint_get_maskfilter(cast(sk_paint_t*) Handle)); 232 } 233 234 void MaskFilter(SKMaskFilter value) { 235 SkiaApi.sk_paint_set_maskfilter(cast(sk_paint_t*) Handle, 236 cast(sk_maskfilter_t*)(value is null ? null : value.Handle)); 237 } 238 239 SKColorFilter ColorFilter() { 240 return SKColorFilter.GetObject(SkiaApi.sk_paint_get_colorfilter(cast(sk_paint_t*) Handle)); 241 } 242 243 void ColorFilter(SKColorFilter value) { 244 SkiaApi.sk_paint_set_colorfilter(cast(sk_paint_t*) Handle, 245 cast(sk_colorfilter_t*)(value is null ? null : value.Handle)); 246 } 247 248 SKImageFilter ImageFilter() { 249 return SKImageFilter.GetObject(SkiaApi.sk_paint_get_imagefilter(cast(sk_paint_t*) Handle)); 250 } 251 252 void ImageFilter(SKImageFilter value) { 253 SkiaApi.sk_paint_set_imagefilter(cast(sk_paint_t*) Handle, 254 cast(sk_imagefilter_t*)(value is null ? null : value.Handle)); 255 } 256 257 SKBlendMode BlendMode() { 258 return SkiaApi.sk_paint_get_blendmode(cast(sk_paint_t*) Handle); 259 } 260 261 void BlendMode(SKBlendMode value) { 262 SkiaApi.sk_paint_set_blendmode(cast(sk_paint_t*) Handle, value); 263 } 264 265 SKFilterQuality FilterQuality() { 266 return SkiaApi.sk_paint_get_filter_quality(cast(sk_paint_t*) Handle); 267 } 268 269 void FilterQuality(SKFilterQuality value) { 270 SkiaApi.sk_paint_set_filter_quality(cast(sk_paint_t*) Handle, value); 271 } 272 273 SKTypeface Typeface() { 274 return GetFont().Typeface; 275 } 276 277 void Typeface(SKTypeface value) { 278 GetFont().Typeface = value; 279 } 280 281 float TextSize() { 282 return GetFont().Size; 283 } 284 285 void TextSize(float value) { 286 GetFont().Size = value; 287 } 288 289 SKTextAlign TextAlign() { 290 return SkiaApi.sk_compatpaint_get_text_align(cast(sk_compatpaint_t*) Handle); 291 292 } 293 294 void TextAlign(SKTextAlign value) { 295 SkiaApi.sk_compatpaint_set_text_align(cast(sk_compatpaint_t*) Handle, value); 296 } 297 298 SKTextEncoding TextEncoding() { 299 return SkiaApi.sk_compatpaint_get_text_encoding(cast(sk_compatpaint_t*) Handle); 300 } 301 302 void TextEncoding(SKTextEncoding value) { 303 304 SkiaApi.sk_compatpaint_set_text_encoding(cast(sk_compatpaint_t*) Handle, value); 305 } 306 307 float TextScaleX() { 308 return GetFont().ScaleX; 309 } 310 311 void TextScaleX(float value) { 312 GetFont().ScaleX = value; 313 } 314 315 float TextSkewX() { 316 return GetFont().SkewX; 317 } 318 319 void TextSkewX(float value) { 320 GetFont().SkewX = value; 321 } 322 323 SKPathEffect PathEffect() { 324 return SKPathEffect.GetObject(SkiaApi.sk_paint_get_path_effect(cast(sk_paint_t*) Handle)); 325 } 326 327 void PathEffect(SKPathEffect value) { 328 SkiaApi.sk_paint_set_path_effect(cast(sk_paint_t*) Handle, 329 cast(sk_path_effect_t*)(value is null ? null : value.Handle)); 330 } 331 332 // FontSpacing 333 334 float FontSpacing() { 335 return GetFont().Spacing; 336 } 337 338 // FontMetrics 339 340 SKFontMetrics FontMetrics() { 341 return GetFont().Metrics; 342 } 343 344 float GetFontMetrics(out SKFontMetrics metrics) { 345 return GetFont().GetFontMetrics(metrics); 346 } 347 348 float GetFontMetrics(out SKFontMetrics metrics, float scale) { 349 return GetFontMetrics(metrics); 350 } 351 352 // Clone 353 354 SKPaint Clone() { 355 return GetObject(SkiaApi.sk_compatpaint_clone(cast(sk_compatpaint_t*) Handle)); 356 } 357 358 // MeasureText 359 360 float MeasureText(string text) { 361 return GetFont().MeasureText(text, this); 362 } 363 364 // float MeasureText(const(char)[] text) { 365 // return GetFont().MeasureText(text, this); 366 // } 367 368 float MeasureText(byte[] text) { 369 return GetFont().MeasureText(text, TextEncoding, this); 370 } 371 372 float MeasureText(const(byte)[] text) { 373 return GetFont().MeasureText(text, TextEncoding, this); 374 } 375 376 float MeasureText(void* buffer, int length) { 377 return GetFont().MeasureText(buffer, length, TextEncoding, this); 378 } 379 380 float MeasureText(void* buffer, void* length) { 381 return GetFont().MeasureText(buffer, cast(int) length, TextEncoding, this); 382 } 383 384 float MeasureText(string text, ref SKRect bounds) { 385 return GetFont().MeasureText(text, bounds, this); 386 } 387 388 // float MeasureText(const(char)[] text, ref SKRect bounds) { 389 // return GetFont().MeasureText(text, bounds, this); 390 // } 391 392 float MeasureText(byte[] text, ref SKRect bounds) { 393 return GetFont().MeasureText(text, TextEncoding, bounds, this); 394 } 395 396 float MeasureText(const(byte)[] text, ref SKRect bounds) { 397 return GetFont().MeasureText(text, TextEncoding, bounds, this); 398 } 399 400 float MeasureText(void* buffer, int length, ref SKRect bounds) { 401 return GetFont().MeasureText(buffer, length, TextEncoding, bounds, this); 402 } 403 404 float MeasureText(void* buffer, void* length, ref SKRect bounds) { 405 return GetFont().MeasureText(buffer, cast(int) length, TextEncoding, bounds, this); 406 } 407 408 // BreakText 409 410 long BreakText(string text, float maxWidth) { 411 float measuredWidth; 412 return GetFont().BreakText(text, maxWidth, measuredWidth, this); 413 } 414 415 long BreakText(string text, float maxWidth, out float measuredWidth) { 416 return GetFont().BreakText(text, maxWidth, measuredWidth, this); 417 } 418 419 long BreakText(string text, float maxWidth, out float measuredWidth, out string measuredText) { 420 if (text is null) 421 throw new ArgumentNullException(text.stringof); 422 423 auto charsRead = GetFont().BreakText(text, maxWidth, measuredWidth, this); 424 if (charsRead == 0) { 425 measuredText = null; 426 return 0; 427 } 428 if (charsRead == text.length) { 429 measuredText = text; 430 return text.length; 431 } 432 measuredText = text[0 .. charsRead]; 433 return charsRead; 434 } 435 436 long BreakText(const(char)[] text, float maxWidth) { 437 float measuredWidth; 438 return GetFont().BreakText(text, maxWidth, measuredWidth, this); 439 } 440 441 long BreakText(const(char)[] text, float maxWidth, out float measuredWidth) { 442 return GetFont().BreakText(text, maxWidth, measuredWidth, this); 443 } 444 445 long BreakText(byte[] text, float maxWidth) { 446 float measuredWidth; 447 return GetFont().BreakText(text, TextEncoding, maxWidth, measuredWidth, this); 448 } 449 450 long BreakText(byte[] text, float maxWidth, out float measuredWidth) { 451 return GetFont().BreakText(text, TextEncoding, maxWidth, measuredWidth, this); 452 453 } 454 455 long BreakText(const(byte)[] text, float maxWidth) { 456 float measuredWidth; 457 return GetFont().BreakText(text, TextEncoding, maxWidth, measuredWidth, this); 458 } 459 460 long BreakText(const(byte)[] text, float maxWidth, out float measuredWidth) { 461 return GetFont().BreakText(text, TextEncoding, maxWidth, measuredWidth, this); 462 } 463 464 long BreakText(void* buffer, int length, float maxWidth) { 465 float measuredWidth; 466 return GetFont().BreakText(buffer, length, TextEncoding, maxWidth, measuredWidth, this); 467 } 468 469 long BreakText(void* buffer, int length, float maxWidth, out float measuredWidth) { 470 return GetFont().BreakText(buffer, length, TextEncoding, maxWidth, measuredWidth, this); 471 } 472 473 long BreakText(void* buffer, void* length, float maxWidth) { 474 float measuredWidth; 475 return GetFont().BreakText(buffer, cast(int) length, TextEncoding, 476 maxWidth, measuredWidth, this); 477 } 478 479 long BreakText(void* buffer, void* length, float maxWidth, out float measuredWidth) { 480 return GetFont().BreakText(buffer, cast(int) length, TextEncoding, 481 maxWidth, measuredWidth, this); 482 } 483 484 // GetTextPath 485 486 SKPath GetTextPath(string text, float x, float y) { 487 return GetFont().GetTextPath(text, SKPoint(x, y)); 488 } 489 490 SKPath GetTextPath(const(char)[] text, float x, float y) { 491 return GetFont().GetTextPath(text, SKPoint(x, y)); 492 } 493 494 SKPath GetTextPath(byte[] text, float x, float y) { 495 return GetFont().GetTextPath(text, TextEncoding, SKPoint(x, y)); 496 } 497 498 SKPath GetTextPath(const(byte)[] text, float x, float y) { 499 return GetFont().GetTextPath(text, TextEncoding, SKPoint(x, y)); 500 } 501 502 SKPath GetTextPath(void* buffer, int length, float x, float y) { 503 return GetFont().GetTextPath(buffer, length, TextEncoding, SKPoint(x, y)); 504 505 } 506 507 SKPath GetTextPath(void* buffer, void* length, float x, float y) { 508 return GetFont().GetTextPath(buffer, cast(int) length, TextEncoding, SKPoint(x, y)); 509 } 510 511 SKPath GetTextPath(string text, SKPoint[] points) { 512 return GetFont().GetTextPath(text, points); 513 } 514 515 SKPath GetTextPath(const(char)[] text, const(SKPoint)[] points) { 516 return GetFont().GetTextPath(text, points); 517 } 518 519 SKPath GetTextPath(byte[] text, SKPoint[] points) { 520 return GetFont().GetTextPath(text, TextEncoding, points); 521 } 522 523 SKPath GetTextPath(const(byte)[] text, const(SKPoint)[] points) { 524 return GetFont().GetTextPath(text, TextEncoding, points); 525 } 526 527 SKPath GetTextPath(void* buffer, int length, SKPoint[] points) { 528 return GetFont().GetTextPath(buffer, length, TextEncoding, points); 529 } 530 531 SKPath GetTextPath(void* buffer, int length, const(SKPoint)[] points) { 532 return GetFont().GetTextPath(buffer, length, TextEncoding, points); 533 } 534 535 SKPath GetTextPath(void* buffer, void* length, SKPoint[] points) { 536 return GetFont().GetTextPath(buffer, cast(int) length, TextEncoding, points); 537 } 538 539 // GetFillPath 540 541 SKPath GetFillPath(SKPath src) { 542 return GetFillPath(src, 1f); 543 } 544 545 SKPath GetFillPath(SKPath src, float resScale) { 546 auto dst = new SKPath(); 547 548 if (GetFillPath(src, dst, resScale)) { 549 return dst; 550 } else { 551 dst.Dispose(); 552 return null; 553 } 554 } 555 556 SKPath GetFillPath(SKPath src, SKRect cullRect) { 557 return GetFillPath(src, cullRect, 1f); 558 } 559 560 SKPath GetFillPath(SKPath src, SKRect cullRect, float resScale) { 561 auto dst = new SKPath(); 562 563 if (GetFillPath(src, dst, cullRect, resScale)) { 564 return dst; 565 } else { 566 dst.Dispose(); 567 return null; 568 } 569 } 570 571 bool GetFillPath(SKPath src, SKPath dst) { 572 return GetFillPath(src, dst, 1f); 573 } 574 575 bool GetFillPath(SKPath src, SKPath dst, float resScale) { 576 if (src is null) 577 throw new ArgumentNullException(src.stringof); 578 if (dst is null) 579 throw new ArgumentNullException(dst.stringof); 580 581 return SkiaApi.sk_paint_get_fill_path(cast(sk_paint_t*) Handle, 582 cast(sk_path_t*) src.Handle, cast(sk_path_t*) dst.Handle, null, resScale); 583 } 584 585 bool GetFillPath(SKPath src, SKPath dst, SKRect cullRect) { 586 return GetFillPath(src, dst, cullRect, 1f); 587 } 588 589 bool GetFillPath(SKPath src, SKPath dst, SKRect cullRect, float resScale) { 590 if (src is null) 591 throw new ArgumentNullException(src.stringof); 592 if (dst is null) 593 throw new ArgumentNullException(dst.stringof); 594 595 return SkiaApi.sk_paint_get_fill_path(cast(sk_paint_t*) Handle, 596 cast(sk_path_t*) src.Handle, cast(sk_path_t*) dst.Handle, &cullRect, resScale); 597 } 598 599 // CountGlyphs 600 601 int CountGlyphs(string text) { 602 return GetFont().CountGlyphs(text); 603 } 604 605 int CountGlyphs(const(char)[] text) { 606 return GetFont().CountGlyphs(text); 607 } 608 609 int CountGlyphs(byte[] text) { 610 return GetFont().CountGlyphs(text, TextEncoding); 611 } 612 613 int CountGlyphs(const(byte)[] text) { 614 return GetFont().CountGlyphs(text, TextEncoding); 615 } 616 617 int CountGlyphs(void* text, int length) { 618 return GetFont().CountGlyphs(text, length, TextEncoding); 619 } 620 621 // GetGlyphs 622 623 ushort[] GetGlyphs(string text) { 624 return GetFont().GetGlyphs(text); 625 } 626 627 ushort[] GetGlyphs(const(char)[] text) { 628 return GetFont().GetGlyphs(text); 629 } 630 631 ushort[] GetGlyphs(byte[] text) { 632 return GetFont().GetGlyphs(text, TextEncoding); 633 } 634 635 ushort[] GetGlyphs(const(byte)[] text) { 636 return GetFont().GetGlyphs(text, TextEncoding); 637 } 638 639 ushort[] GetGlyphs(void* text, int length) { 640 return GetFont().GetGlyphs(text, length, TextEncoding); 641 } 642 643 // ContainsGlyphs 644 645 bool ContainsGlyphs(string text) { 646 return GetFont().ContainsGlyphs(text); 647 } 648 649 bool ContainsGlyphs(const(char)[] text) { 650 return GetFont().ContainsGlyphs(text); 651 } 652 653 bool ContainsGlyphs(byte[] text) { 654 return GetFont().ContainsGlyphs(text, TextEncoding); 655 } 656 657 bool ContainsGlyphs(const(byte)[] text) { 658 return GetFont().ContainsGlyphs(text, TextEncoding); 659 } 660 661 bool ContainsGlyphs(void* text, int length) { 662 return GetFont().ContainsGlyphs(text, length, TextEncoding); 663 } 664 665 bool ContainsGlyphs(void* text, void* length) { 666 return GetFont().ContainsGlyphs(text, cast(int) length, TextEncoding); 667 } 668 669 // GetGlyphPositions 670 671 SKPoint[] GetGlyphPositions(string text, SKPoint origin = SKPoint.Empty) { 672 return GetFont().GetGlyphPositions(text, origin); 673 } 674 675 SKPoint[] GetGlyphPositions(const(char)[] text, SKPoint origin = SKPoint.Empty) { 676 return GetFont().GetGlyphPositions(text, origin); 677 } 678 679 SKPoint[] GetGlyphPositions(const(byte)[] text, SKPoint origin = SKPoint.Empty) { 680 return GetFont().GetGlyphPositions(text, TextEncoding, origin); 681 } 682 683 SKPoint[] GetGlyphPositions(void* text, int length, SKPoint origin = SKPoint.Empty) { 684 return GetFont().GetGlyphPositions(text, length, TextEncoding, origin); 685 } 686 687 // GetGlyphOffsets 688 689 float[] GetGlyphOffsets(string text, float origin = 0f) { 690 return GetFont().GetGlyphOffsets(text, origin); 691 } 692 693 float[] GetGlyphOffsets(const(char)[] text, float origin = 0f) { 694 return GetFont().GetGlyphOffsets(text, origin); 695 } 696 697 float[] GetGlyphOffsets(byte[] text, float origin = 0f) { 698 return GetFont().GetGlyphOffsets(text, TextEncoding, origin); 699 } 700 701 float[] GetGlyphOffsets(void* text, int length, float origin = 0f) { 702 return GetFont().GetGlyphOffsets(text, length, TextEncoding, origin); 703 } 704 705 // GetGlyphWidths 706 707 float[] GetGlyphWidths(string text) { 708 return GetFont().GetGlyphWidths(text, this); 709 } 710 711 float[] GetGlyphWidths(char[] text) { 712 return GetFont().GetGlyphWidths(text, this); 713 } 714 715 float[] GetGlyphWidths(byte[] text) { 716 return GetFont().GetGlyphWidths(text, TextEncoding, this); 717 } 718 719 float[] GetGlyphWidths(void* text, int length) { 720 return GetFont().GetGlyphWidths(text, length, TextEncoding, this); 721 } 722 723 float[] GetGlyphWidths(string text, out SKRect[] bounds) { 724 return GetFont().GetGlyphWidths(text, bounds, this); 725 } 726 727 float[] GetGlyphWidths(char[] text, out SKRect[] bounds) { 728 return GetFont().GetGlyphWidths(text, bounds, this); 729 } 730 731 float[] GetGlyphWidths(byte[] text, out SKRect[] bounds) { 732 return GetFont().GetGlyphWidths(text, TextEncoding, bounds, this); 733 } 734 735 float[] GetGlyphWidths(void* text, int length, out SKRect[] bounds) { 736 return GetFont().GetGlyphWidths(text, length, TextEncoding, bounds, this); 737 } 738 739 // GetTextIntercepts 740 741 float[] GetTextIntercepts(string text, float x, float y, float upperBounds, float lowerBounds) { 742 return GetTextIntercepts(cast(char[]) text, x, y, upperBounds, lowerBounds); 743 } 744 745 float[] GetTextIntercepts(char[] text, float x, float y, float upperBounds, float lowerBounds) { 746 if (text is null) 747 throw new ArgumentNullException(text.stringof); 748 749 auto blob = SKTextBlob.Create(cast(byte[]) text, SKTextEncoding.Utf8, 750 GetFont(), SKPoint(x, y)); 751 scope (exit) { 752 blob.Dispose(); 753 } 754 755 return blob.GetIntercepts(upperBounds, lowerBounds, this); 756 } 757 758 float[] GetTextIntercepts(byte[] text, float x, float y, float upperBounds, float lowerBounds) { 759 return GetTextIntercepts(cast(const(byte)[]) text, x, y, upperBounds, lowerBounds); 760 } 761 762 float[] GetTextIntercepts(const(byte)[] text, float x, float y, 763 float upperBounds, float lowerBounds) { 764 if (text is null) 765 throw new ArgumentNullException(text.stringof); 766 767 auto blob = SKTextBlob.Create(text, TextEncoding, GetFont(), SKPoint(x, y)); 768 scope (exit) { 769 blob.Dispose(); 770 } 771 772 return blob.GetIntercepts(upperBounds, lowerBounds, this); 773 } 774 775 float[] GetTextIntercepts(void* text, void* length, float x, float y, 776 float upperBounds, float lowerBounds) { 777 return GetTextIntercepts(text, cast(int) length, x, y, upperBounds, lowerBounds); 778 } 779 780 float[] GetTextIntercepts(void* text, int length, float x, float y, 781 float upperBounds, float lowerBounds) { 782 if (text is null && length != 0) 783 throw new ArgumentNullException(text.stringof); 784 785 auto blob = SKTextBlob.Create(text, length, TextEncoding, GetFont(), SKPoint(x, y)); 786 scope (exit) { 787 blob.Dispose(); 788 } 789 790 return blob.GetIntercepts(upperBounds, lowerBounds, this); 791 } 792 793 // GetTextIntercepts (SKTextBlob) 794 795 float[] GetTextIntercepts(SKTextBlob text, float upperBounds, float lowerBounds) { 796 if (text is null) 797 throw new ArgumentNullException(text.stringof); 798 799 return text.GetIntercepts(upperBounds, lowerBounds, this); 800 } 801 802 // GetPositionedTextIntercepts 803 804 float[] GetPositionedTextIntercepts(string text, SKPoint[] positions, 805 float upperBounds, float lowerBounds) { 806 return GetPositionedTextIntercepts(cast(const(char)[]) text, positions, 807 upperBounds, lowerBounds); 808 } 809 810 float[] GetPositionedTextIntercepts(const(char)[] text, 811 const(SKPoint)[] positions, float upperBounds, float lowerBounds) { 812 if (text is null) 813 throw new ArgumentNullException(text.stringof); 814 815 auto blob = SKTextBlob.CreatePositioned(text, GetFont(), positions); 816 scope (exit) { 817 blob.Dispose(); 818 } 819 820 return blob.GetIntercepts(upperBounds, lowerBounds, this); 821 } 822 823 float[] GetPositionedTextIntercepts(byte[] text, SKPoint[] positions, 824 float upperBounds, float lowerBounds) { 825 return GetPositionedTextIntercepts(cast(const(byte)[]) text, positions, 826 upperBounds, lowerBounds); 827 } 828 829 float[] GetPositionedTextIntercepts(const(byte)[] text, 830 const(SKPoint)[] positions, float upperBounds, float lowerBounds) { 831 if (text is null) 832 throw new ArgumentNullException(text.stringof); 833 834 auto blob = SKTextBlob.CreatePositioned(text, TextEncoding, GetFont(), positions); 835 scope (exit) { 836 blob.Dispose(); 837 } 838 839 return blob.GetIntercepts(upperBounds, lowerBounds, this); 840 } 841 842 float[] GetPositionedTextIntercepts(void* text, int length, 843 SKPoint[] positions, float upperBounds, float lowerBounds) { 844 return GetPositionedTextIntercepts(text, cast(void*) length, positions, 845 upperBounds, lowerBounds); 846 } 847 848 float[] GetPositionedTextIntercepts(void* text, void* length, 849 SKPoint[] positions, float upperBounds, float lowerBounds) { 850 if (text is null && length !is null) 851 throw new ArgumentNullException(text.stringof); 852 853 auto blob = SKTextBlob.CreatePositioned(text, cast(int) length, 854 TextEncoding, GetFont(), positions); 855 scope (exit) { 856 blob.Dispose(); 857 } 858 859 return blob.GetIntercepts(upperBounds, lowerBounds, this); 860 } 861 862 // GetHorizontalTextIntercepts 863 864 float[] GetHorizontalTextIntercepts(string text, float[] xpositions, float y, 865 float upperBounds, float lowerBounds) { 866 return GetHorizontalTextIntercepts(cast(const(char)[]) text, xpositions, 867 y, upperBounds, lowerBounds); 868 } 869 870 float[] GetHorizontalTextIntercepts(const(char)[] text, 871 const(float)[] xpositions, float y, float upperBounds, float lowerBounds) { 872 if (text is null) 873 throw new ArgumentNullException(text.stringof); 874 875 auto blob = SKTextBlob.CreateHorizontal(text, GetFont(), xpositions, y); 876 scope (exit) { 877 blob.Dispose(); 878 } 879 880 return blob.GetIntercepts(upperBounds, lowerBounds, this); 881 } 882 883 float[] GetHorizontalTextIntercepts(byte[] text, float[] xpositions, float y, 884 float upperBounds, float lowerBounds) { 885 return GetHorizontalTextIntercepts(cast(const(byte)[]) text, xpositions, 886 y, upperBounds, lowerBounds); 887 } 888 889 float[] GetHorizontalTextIntercepts(const(byte)[] text, 890 const(float)[] xpositions, float y, float upperBounds, float lowerBounds) { 891 if (text is null) 892 throw new ArgumentNullException(text.stringof); 893 894 auto blob = SKTextBlob.CreateHorizontal(text, TextEncoding, GetFont(), xpositions, y); 895 scope (exit) { 896 blob.Dispose(); 897 } 898 899 return blob.GetIntercepts(upperBounds, lowerBounds, this); 900 } 901 902 float[] GetHorizontalTextIntercepts(void* text, int length, 903 float[] xpositions, float y, float upperBounds, float lowerBounds) { 904 return GetHorizontalTextIntercepts(text, cast(void*) length, 905 xpositions, y, upperBounds, lowerBounds); 906 } 907 908 float[] GetHorizontalTextIntercepts(void* text, void* length, 909 float[] xpositions, float y, float upperBounds, float lowerBounds) { 910 if (text is null && length !is null) 911 throw new ArgumentNullException(text.stringof); 912 913 auto blob = SKTextBlob.CreateHorizontal(text, cast(int) length, 914 TextEncoding, GetFont(), xpositions, y); 915 scope (exit) { 916 blob.Dispose(); 917 } 918 919 return blob.GetIntercepts(upperBounds, lowerBounds, this); 920 } 921 922 // Font 923 924 SKFont ToFont() { 925 return SKFont.GetObject(SkiaApi.sk_compatpaint_make_font(cast(sk_compatpaint_t*) Handle)); 926 } 927 928 SKFont GetFont() { 929 if(font is null) { 930 sk_font_t* fontPtr = SkiaApi.sk_compatpaint_get_font( 931 cast(sk_compatpaint_t*) Handle); 932 SKFont skFont = SKFont.GetObject(fontPtr, false); 933 font = OwnedBy(skFont, this); 934 } 935 936 return font; 937 // return font ? font : OwnedBy(SKFont.GetObject(SkiaApi.sk_compatpaint_get_font( 938 // cast(sk_compatpaint_t*) Handle), false), this); 939 } 940 941 // 942 943 static SKPaint GetObject(void* handle) { 944 return handle is null ? null : new SKPaint(handle, true); 945 } 946 947 }