Add a few more members for SKCanvas (#1090)

- DrawArc
- DrawAtlas
- DrawPatch
- DrawRoundRectDifference
- IsClipEmpty and IsClipRect
This commit is contained in:
Matthew Leibowitz 2020-01-08 16:46:04 +02:00 коммит произвёл GitHub
Родитель e2514cda18
Коммит 48c9d72a56
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 429 добавлений и 21 удалений

Просмотреть файл

@ -3,18 +3,12 @@
namespace SkiaSharp
{
// TODO: carefully consider the `PeekPixels`, `ReadPixels`
// TODO: `ClipRRect` may be useful
// TODO: `DrawRRect` may be useful
// TODO: `DrawDRRect` may be useful
// TODO: add the `DrawArc` variants
// TODO: add `DrawTextBlob` variants if/when we bind `SKTextBlob`
// TODO: add `DrawPatch` variants
// TODO: add `DrawAtlas` variants
// TODO: add `DrawDrawable` variants if/when we bind `SKDrawable`
// TODO: add `IsClipEmpty` and `IsClipRect`
public unsafe class SKCanvas : SKObject
{
private const int PatchCornerCount = 4;
private const int PatchCubicsCount = 12;
[Preserve]
internal SKCanvas (IntPtr handle, bool owns)
: base (handle, owns)
@ -220,6 +214,10 @@ namespace SkiaSharp
}
}
public bool IsClipEmpty => SkiaApi.sk_canvas_is_clip_empty (Handle);
public bool IsClipRect => SkiaApi.sk_canvas_is_clip_rect (Handle);
public bool GetLocalClipBounds (out SKRect bounds)
{
fixed (SKRect* b = &bounds) {
@ -833,6 +831,102 @@ namespace SkiaSharp
throw new ArgumentNullException (nameof (paint));
SkiaApi.sk_canvas_draw_vertices (Handle, vertices.Handle, mode, paint.Handle);
}
public void DrawArc (SKRect oval, float startAngle, float sweepAngle, bool useCenter, SKPaint paint)
{
if (paint == null)
throw new ArgumentNullException (nameof (paint));
SkiaApi.sk_canvas_draw_arc (Handle, &oval, startAngle, sweepAngle, useCenter, paint.Handle);
}
public void DrawRoundRectDifference (SKRoundRect outer, SKRoundRect inner, SKPaint paint)
{
if (outer == null)
throw new ArgumentNullException (nameof (outer));
if (inner == null)
throw new ArgumentNullException (nameof (inner));
if (paint == null)
throw new ArgumentNullException (nameof (paint));
SkiaApi.sk_canvas_draw_drrect (Handle, outer.Handle, inner.Handle, paint.Handle);
}
public void DrawAtlas (SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKPaint paint)
=> DrawAtlas (atlas, sprites, transforms, null, SKBlendMode.Dst, null, paint);
public void DrawAtlas (SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKRect cullRect, SKPaint paint)
=> DrawAtlas (atlas, sprites, transforms, null, SKBlendMode.Dst, &cullRect, paint);
public void DrawAtlas (SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKBlendMode mode, SKPaint paint)
=> DrawAtlas (atlas, sprites, transforms, null, mode, null, paint);
public void DrawAtlas (SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKBlendMode mode, SKRect cullRect, SKPaint paint)
=> DrawAtlas (atlas, sprites, transforms, null, mode, &cullRect, paint);
public void DrawAtlas (SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKColor[] colors, SKBlendMode mode, SKPaint paint)
=> DrawAtlas (atlas, sprites, transforms, colors, mode, null, paint);
public void DrawAtlas (SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKColor[] colors, SKBlendMode mode, SKRect cullRect, SKPaint paint)
=> DrawAtlas (atlas, sprites, transforms, colors, mode, &cullRect, paint);
private void DrawAtlas (SKImage atlas, SKRect[] sprites, SKRotationScaleMatrix[] transforms, SKColor[] colors, SKBlendMode mode, SKRect* cullRect, SKPaint paint)
{
if (atlas == null)
throw new ArgumentNullException (nameof (atlas));
if (sprites == null)
throw new ArgumentNullException (nameof (sprites));
if (transforms == null)
throw new ArgumentNullException (nameof (transforms));
if (transforms.Length != sprites.Length)
throw new ArgumentException ("The number of transforms must match the number of sprites.", nameof (transforms));
if (colors != null && colors.Length != sprites.Length)
throw new ArgumentException ("The number of colors must match the number of sprites.", nameof (colors));
fixed (SKRect* s = sprites)
fixed (SKRotationScaleMatrix* t = transforms)
fixed (SKColor* c = colors) {
SkiaApi.sk_canvas_draw_atlas (Handle, atlas.Handle, t, s, (uint*)c, transforms.Length, mode, cullRect, paint.Handle);
}
}
public void DrawPatch (SKPoint[] cubics, SKColor[] colors, SKPaint paint)
=> DrawPatch (cubics, colors, null, SKBlendMode.Modulate, paint);
public void DrawPatch (SKPoint[] cubics, SKColor[] colors, SKBlendMode mode, SKPaint paint)
=> DrawPatch (cubics, colors, null, mode, paint);
public void DrawPatch (SKPoint[] cubics, SKPoint[] texCoords, SKPaint paint)
=> DrawPatch (cubics, null, texCoords, SKBlendMode.Modulate, paint);
public void DrawPatch (SKPoint[] cubics, SKPoint[] texCoords, SKBlendMode mode, SKPaint paint)
=> DrawPatch (cubics, null, texCoords, mode, paint);
public void DrawPatch (SKPoint[] cubics, SKColor[] colors, SKPoint[] texCoords, SKPaint paint)
=> DrawPatch (cubics, colors, texCoords, SKBlendMode.Modulate, paint);
public void DrawPatch (SKPoint[] cubics, SKColor[] colors, SKPoint[] texCoords, SKBlendMode mode, SKPaint paint)
{
if (cubics == null)
throw new ArgumentNullException (nameof (cubics));
if (cubics.Length != PatchCubicsCount)
throw new ArgumentException ($"Cubics must have a length of {PatchCubicsCount}.", nameof (cubics));
if (colors != null && colors.Length != PatchCornerCount)
throw new ArgumentException ($"Colors must have a length of {PatchCornerCount}.", nameof (colors));
if (texCoords != null && texCoords.Length != PatchCornerCount)
throw new ArgumentException ($"Texture coordinates must have a length of {PatchCornerCount}.", nameof (texCoords));
if (paint == null)
throw new ArgumentNullException (nameof (paint));
fixed (SKPoint* cubes = cubics)
fixed (SKColor* cols = colors)
fixed (SKPoint* coords = texCoords) {
SkiaApi.sk_canvas_draw_patch (Handle, cubes, (uint*)cols, coords, mode, paint.Handle);
}
}
}
public class SKAutoCanvasRestore : IDisposable

Просмотреть файл

@ -486,6 +486,8 @@ namespace SkiaSharp
public bool IsAlphaOnly => SkiaApi.sk_image_is_alpha_only (Handle);
public SKData EncodedData => GetObject<SKData> (SkiaApi.sk_image_ref_encoded (Handle));
public SKShader ToShader () => ToShader (SKShaderTileMode.Clamp, SKShaderTileMode.Clamp);
public SKShader ToShader (SKShaderTileMode tileX, SKShaderTileMode tileY)
{
return GetObject<SKShader> (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, null));

Просмотреть файл

@ -5,6 +5,8 @@ namespace SkiaSharp
{
public unsafe partial struct SKMatrix
{
internal const float DegreesToRadians = (float)System.Math.PI / 180.0f;
private class Indices {
public const int ScaleX = 0;
public const int SkewX = 1;
@ -122,7 +124,7 @@ namespace SkiaSharp
#if OPTIMIZED_SKMATRIX
, typeMask = Mask.Identity | Mask.RectStaysRect
#endif
};
};
}
public void SetScaleTranslate (float sx, float sy, float tx, float ty)
@ -219,19 +221,17 @@ typeMask = Mask.Scale | Mask.RectStaysRect
return matrix;
}
const float degToRad = (float)System.Math.PI / 180.0f;
public static SKMatrix MakeRotationDegrees (float degrees)
{
return MakeRotation (degrees * degToRad);
return MakeRotation (degrees * DegreesToRadians);
}
public static SKMatrix MakeRotationDegrees (float degrees, float pivotx, float pivoty)
{
return MakeRotation (degrees * degToRad, pivotx, pivoty);
return MakeRotation (degrees * DegreesToRadians, pivotx, pivoty);
}
static void SetSinCos (ref SKMatrix matrix, float sin, float cos)
private static void SetSinCos (ref SKMatrix matrix, float sin, float cos)
{
matrix.scaleX = cos;
matrix.skewX = -sin;
@ -247,7 +247,7 @@ typeMask = Mask.Scale | Mask.RectStaysRect
#endif
}
static void SetSinCos (ref SKMatrix matrix, float sin, float cos, float pivotx, float pivoty)
private static void SetSinCos (ref SKMatrix matrix, float sin, float cos, float pivotx, float pivoty)
{
float oneMinusCos = 1-cos;
@ -274,8 +274,8 @@ typeMask = Mask.Scale | Mask.RectStaysRect
public static void RotateDegrees (ref SKMatrix matrix, float degrees, float pivotx, float pivoty)
{
var sin = (float) Math.Sin (degrees * degToRad);
var cos = (float) Math.Cos (degrees * degToRad);
var sin = (float) Math.Sin (degrees * DegreesToRadians);
var cos = (float) Math.Cos (degrees * DegreesToRadians);
SetSinCos (ref matrix, sin, cos, pivotx, pivoty);
}
@ -288,8 +288,8 @@ typeMask = Mask.Scale | Mask.RectStaysRect
public static void RotateDegrees (ref SKMatrix matrix, float degrees)
{
var sin = (float) Math.Sin (degrees * degToRad);
var cos = (float) Math.Cos (degrees * degToRad);
var sin = (float) Math.Sin (degrees * DegreesToRadians);
var cos = (float) Math.Cos (degrees * DegreesToRadians);
SetSinCos (ref matrix, sin, cos);
}
@ -1006,4 +1006,48 @@ typeMask = Mask.Scale | Mask.RectStaysRect
return SkiaApi.sk_matrix44_determinant (Handle);
}
}
public unsafe partial struct SKRotationScaleMatrix
{
public static readonly SKRotationScaleMatrix Empty;
public SKRotationScaleMatrix (float scos, float ssin, float tx, float ty)
{
fSCos = scos;
fSSin = ssin;
fTX = tx;
fTY = ty;
}
public SKMatrix ToMatrix () =>
new SKMatrix (fSCos, -fSSin, fTX, fSSin, fSCos, fTY, 0, 0, 1);
public static SKRotationScaleMatrix FromDegrees (float scale, float degrees, float tx, float ty, float anchorX, float anchorY) =>
FromRadians (scale, degrees * SKMatrix.DegreesToRadians, tx, ty, anchorX, anchorY);
public static SKRotationScaleMatrix FromRadians (float scale, float radians, float tx, float ty, float anchorX, float anchorY)
{
var s = (float)Math.Sin (radians) * scale;
var c = (float)Math.Cos (radians) * scale;
var x = tx + -c * anchorX + s * anchorY;
var y = ty + -s * anchorX - c * anchorY;
return new SKRotationScaleMatrix (c, s, x, y);
}
public static SKRotationScaleMatrix CreateIdentity () =>
new SKRotationScaleMatrix (1, 0, 0, 0);
public static SKRotationScaleMatrix CreateTranslate (float x, float y) =>
new SKRotationScaleMatrix (1, 0, x, y);
public static SKRotationScaleMatrix CreateScale (float s) =>
new SKRotationScaleMatrix (s, 0, 0, 0);
public static SKRotationScaleMatrix CreateRotation (float radians, float anchorX, float anchorY) =>
FromRadians (1, radians, 0, 0, anchorX, anchorY);
public static SKRotationScaleMatrix CreateRotationDegrees (float degrees, float anchorX, float anchorY) =>
FromDegrees (1, degrees, 0, 0, anchorX, anchorY);
}
}

Просмотреть файл

@ -28,6 +28,11 @@ namespace SkiaSharp
SetRect (rect);
}
public SKRoundRect (SKRect rect, float radius)
: this (rect, radius, radius)
{
}
public SKRoundRect (SKRect rect, float xRadius, float yRadius)
: this (SkiaApi.sk_rrect_new (), true)
{

Просмотреть файл

@ -653,6 +653,14 @@ namespace SkiaSharp
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_annotation (sk_canvas_t t, SKRect* rect, /* char */ void* key, sk_data_t value);
// void sk_canvas_draw_arc(sk_canvas_t* ccanvas, const sk_rect_t* oval, float startAngle, float sweepAngle, bool useCenter, const sk_paint_t* paint)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_arc (sk_canvas_t ccanvas, SKRect* oval, Single startAngle, Single sweepAngle, [MarshalAs (UnmanagedType.I1)] bool useCenter, sk_paint_t paint);
// void sk_canvas_draw_atlas(sk_canvas_t* ccanvas, const sk_image_t* atlas, const sk_rsxform_t* xform, const sk_rect_t* tex, const sk_color_t* colors, int count, sk_blendmode_t mode, const sk_rect_t* cullRect, const sk_paint_t* paint)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_atlas (sk_canvas_t ccanvas, sk_image_t atlas, SKRotationScaleMatrix* xform, SKRect* tex, UInt32* colors, Int32 count, SKBlendMode mode, SKRect* cullRect, sk_paint_t paint);
// void sk_canvas_draw_bitmap(sk_canvas_t* ccanvas, const sk_bitmap_t* bitmap, float left, float top, const sk_paint_t* paint)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_bitmap (sk_canvas_t ccanvas, sk_bitmap_t bitmap, Single left, Single top, sk_paint_t paint);
@ -681,6 +689,10 @@ namespace SkiaSharp
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_drawable (sk_canvas_t param0, sk_drawable_t param1, SKMatrix* param2);
// void sk_canvas_draw_drrect(sk_canvas_t* ccanvas, const sk_rrect_t* outer, const sk_rrect_t* inner, const sk_paint_t* paint)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_drrect (sk_canvas_t ccanvas, sk_rrect_t outer, sk_rrect_t inner, sk_paint_t paint);
// void sk_canvas_draw_image(sk_canvas_t*, const sk_image_t*, float x, float y, const sk_paint_t*)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_image (sk_canvas_t param0, sk_image_t param1, Single x, Single y, sk_paint_t param4);
@ -717,6 +729,10 @@ namespace SkiaSharp
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_paint (sk_canvas_t param0, sk_paint_t param1);
// void sk_canvas_draw_patch(sk_canvas_t* ccanvas, const sk_point_t* cubics, const sk_color_t* colors, const sk_point_t* texCoords, sk_blendmode_t mode, const sk_paint_t* paint)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_patch (sk_canvas_t ccanvas, SKPoint* cubics, UInt32* colors, SKPoint* texCoords, SKBlendMode mode, sk_paint_t paint);
// void sk_canvas_draw_path(sk_canvas_t*, const sk_path_t*, const sk_paint_t*)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_path (sk_canvas_t param0, sk_path_t param1, sk_paint_t param2);
@ -769,7 +785,7 @@ namespace SkiaSharp
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_url_annotation (sk_canvas_t t, SKRect* rect, sk_data_t value);
// void sk_canvas_draw_vertices(sk_canvas_t* ccanvas, sk_vertices_t* vertices, sk_blendmode_t mode, const sk_paint_t* paint)
// void sk_canvas_draw_vertices(sk_canvas_t* ccanvas, const sk_vertices_t* vertices, sk_blendmode_t mode, const sk_paint_t* paint)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_draw_vertices (sk_canvas_t ccanvas, sk_vertices_t vertices, SKBlendMode mode, sk_paint_t paint);
@ -795,6 +811,16 @@ namespace SkiaSharp
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_canvas_get_total_matrix (sk_canvas_t ccanvas, SKMatrix* matrix);
// bool sk_canvas_is_clip_empty(sk_canvas_t* ccanvas)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs (UnmanagedType.I1)]
internal static extern bool sk_canvas_is_clip_empty (sk_canvas_t ccanvas);
// bool sk_canvas_is_clip_rect(sk_canvas_t* ccanvas)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs (UnmanagedType.I1)]
internal static extern bool sk_canvas_is_clip_rect (sk_canvas_t ccanvas);
// sk_canvas_t* sk_canvas_new_from_bitmap(const sk_bitmap_t* bitmap)
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_canvas_t sk_canvas_new_from_bitmap (sk_bitmap_t bitmap);
@ -4214,6 +4240,39 @@ namespace SkiaSharp
}
// sk_rsxform_t
[StructLayout (LayoutKind.Sequential)]
public unsafe partial struct SKRotationScaleMatrix {
// public float fSCos
private Single fSCos;
public Single SCos {
get => fSCos;
set => fSCos = value;
}
// public float fSSin
private Single fSSin;
public Single SSin {
get => fSSin;
set => fSSin = value;
}
// public float fTX
private Single fTX;
public Single TX {
get => fTX;
set => fTX = value;
}
// public float fTY
private Single fTY;
public Single TY {
get => fTY;
set => fTY = value;
}
}
// sk_size_t
[StructLayout (LayoutKind.Sequential)]
public unsafe partial struct SKSize {

Просмотреть файл

@ -102,6 +102,9 @@
"sk_colortype_t": {
"cs": "SKColorType"
},
"sk_rsxform_t": {
"cs": "SKRotationScaleMatrix"
},
"sk_shader_tilemode_t": {
"cs": "SKShaderTileMode"
},

Просмотреть файл

@ -80,6 +80,90 @@ namespace SkiaSharp.Tests
Assert.Equal(textPixels, glyphsPixels);
}
[SkippableFact]
public void CanDrawRoundRectDifference()
{
using var outer = new SKRoundRect(SKRect.Create(50, 50, 200, 200), 20);
using var inner = new SKRoundRect(SKRect.Create(100, 100, 100, 100), 20);
using var paint = new SKPaint();
SKColor[] diff;
using (var bmp = new SKBitmap(new SKImageInfo(300, 300)))
using (var canvas = new SKCanvas(bmp))
{
canvas.Clear(SKColors.Transparent);
canvas.DrawRoundRectDifference(outer, inner, paint);
diff = bmp.Pixels;
}
SKColor[] paths;
using (var bmp = new SKBitmap(new SKImageInfo(300, 300)))
using (var canvas = new SKCanvas(bmp))
using (var path = new SKPath())
{
canvas.Clear(SKColors.Transparent);
path.AddRoundRect(outer);
path.AddRoundRect(inner);
path.FillType = SKPathFillType.EvenOdd;
canvas.DrawPath(path, paint);
paths = bmp.Pixels;
}
Assert.Equal(paths, diff);
}
[SkippableFact]
public void DrawAtlasThrowsOnMismatchingArgs()
{
using var bmp = new SKBitmap(new SKImageInfo(300, 300));
using var img = SKImage.FromBitmap(bmp);
using var canvas = new SKCanvas(bmp);
using var paint = new SKPaint();
var sprites = new[] { SKRect.Empty, SKRect.Empty };
var transforms = new[] { SKRotationScaleMatrix.Empty };
Assert.Throws<ArgumentException>("transforms", () => canvas.DrawAtlas(img, sprites, transforms, SKBlendMode.Src, paint));
}
[SkippableFact]
public void CanDrawPatch()
{
var cubics = new SKPoint[12] {
// top points
new SKPoint(100, 100), new SKPoint(150, 50), new SKPoint(250, 150), new SKPoint(300, 100),
// right points
new SKPoint(250, 150), new SKPoint(350, 250),
// bottom points
new SKPoint(300, 300), new SKPoint(250, 250), new SKPoint(150, 350), new SKPoint(100, 300),
// left points
new SKPoint(50, 250), new SKPoint(150, 150)
};
var baboon = SKImage.FromEncodedData(Path.Combine(PathToImages, "baboon.jpg"));
var tex = new SKPoint[4] {
new SKPoint(0, 0),
new SKPoint(baboon.Width, 0),
new SKPoint(baboon.Width, baboon.Height),
new SKPoint(0, baboon.Height),
};
using var bmp = new SKBitmap(new SKImageInfo(400, 400));
using var canvas = new SKCanvas(bmp);
using var paint = new SKPaint
{
IsAntialias = true,
Shader = baboon.ToShader(),
};
canvas.DrawPatch(cubics, tex, paint);
}
[SkippableFact]
public void CanDrawText()
{
@ -200,6 +284,96 @@ namespace SkiaSharp.Tests
}
}
[SkippableFact]
public void DrawAtlasSupportsTransforms()
{
var target = new SKRect(50, 50, 80, 90);
var rec = new[]
{
(Scale: 1, Degrees: 0, TX: 10, TY: 10), // just translate
(Scale: 2, Degrees: 0, TX: 110, TY: 10), // scale + translate
(Scale: 1, Degrees: 30, TX: 210, TY: 10), // rotate + translate
(Scale: 2, Degrees: -30, TX: 310, TY: 30), // scale + rotate + translate
};
var N = rec.Length;
var xform = new SKRotationScaleMatrix[N];
var tex = new SKRect[N];
var colors = new SKColor[N];
for (var i = 0; i < N; ++i)
{
xform[i] = Apply(rec[i]);
tex[i] = target;
colors[i] = 0x80FF0000 + (uint)(i * 40 * 256);
}
using var atlas = CreateAtlas(target);
using var bitmap = new SKBitmap(new SKImageInfo(640, 480));
using var canvas = new SKCanvas(bitmap);
using var paint = new SKPaint
{
FilterQuality = SKFilterQuality.Low,
IsAntialias = true
};
canvas.Clear(SKColors.White);
canvas.DrawAtlas(atlas, tex, xform, paint);
canvas.Translate(0, 100);
canvas.DrawAtlas(atlas, tex, xform, colors, SKBlendMode.SrcIn, paint);
Assert.Equal(SKColors.Blue, bitmap.GetPixel(32, 41));
Assert.Equal(SKColors.Blue, bitmap.GetPixel(156, 77));
Assert.Equal(SKColors.Blue, bitmap.GetPixel(201, 45));
Assert.Equal(SKColors.Blue, bitmap.GetPixel(374, 80));
Assert.Equal(0xFF7F7FFF, bitmap.GetPixel(32, 141));
Assert.Equal(0xFF7F7FFF, bitmap.GetPixel(156, 177));
Assert.Equal(0xFF7F7FFF, bitmap.GetPixel(201, 145));
Assert.Equal(0xFF7F7FFF, bitmap.GetPixel(374, 180));
static SKRotationScaleMatrix Apply((float Scale, float Degrees, float TX, float TY) rec)
{
var rad = SKMatrix.DegreesToRadians * rec.Degrees;
return new SKRotationScaleMatrix(
rec.Scale * (float)Math.Cos(rad),
rec.Scale * (float)Math.Sin(rad),
rec.TX,
rec.TY);
}
static SKImage CreateAtlas(SKRect target)
{
var info = new SKImageInfo(100, 100);
using var surface = SKSurface.Create(info);
using var canvas = surface.Canvas;
// draw red everywhere, but we don't expect to see it in the draw, testing the notion
// that drawAtlas draws a subset-region of the atlas.
canvas.Clear(SKColors.Red);
using var paint = new SKPaint
{
BlendMode = SKBlendMode.Clear
};
// zero out a place (with a 1-pixel border) to land our drawing.
var r = target;
r.Inflate(1, 1);
canvas.DrawRect(r, paint);
paint.BlendMode = SKBlendMode.SrcOver;
paint.Color = SKColors.Blue;
paint.IsAntialias = true;
canvas.DrawOval(target, paint);
return surface.Snapshot();
}
}
[SkippableFact]
public void TotalMatrixIsCorrect()
{

Просмотреть файл

@ -187,6 +187,33 @@ namespace SkiaSharp.Tests
Assert.Equal(SKMatrix.MakeTranslation(15, 27).Values, a.Values);
}
[SkippableFact]
public void SKRotationScaleMatrixTranslationToMatrixIsCorrect()
{
var m = SKMatrix.MakeTranslation(5, 7);
var rsm = SKRotationScaleMatrix.CreateTranslate(5, 7).ToMatrix();
Assert.Equal(m.Values, rsm.Values);
}
[SkippableFact]
public void SKRotationScaleMatrixRotationToMatrixIsCorrect()
{
var m = SKMatrix.MakeRotationDegrees(45);
var rsm = SKRotationScaleMatrix.CreateRotationDegrees(45, 0, 0).ToMatrix();
Assert.Equal(m.Values, rsm.Values);
}
[SkippableFact]
public void SKRotationScaleMatrixScaleToMatrixIsCorrect()
{
var m = SKMatrix.MakeScale(3.5f, 3.5f);
var rsm = SKRotationScaleMatrix.CreateScale(3.5f).ToMatrix();
Assert.Equal(m.Values, rsm.Values);
}
[SkippableFact]
public void MatrixMapsPoints()
{