Merge branch 'master' into development
Fixed bug with SKObject.SizeOf <T> checking the size of IntPtr instead of T
This commit is contained in:
Коммит
c4edddb40d
|
@ -2688,4 +2688,9 @@ namespace SkiaSharp
|
|||
TriangleStrip,
|
||||
TriangleFan,
|
||||
}
|
||||
|
||||
public enum SKImageCachingHint {
|
||||
Allow,
|
||||
Disallow,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,12 @@ namespace SkiaSharp
|
|||
public class GRGlInterface : SKObject
|
||||
{
|
||||
// so the GC doesn't collect the delegate
|
||||
private static readonly GRGlGetProcDelegateInternal getProcDelegate;
|
||||
private static readonly GRGlGetProcDelegateInternal getProcDelegateInternal;
|
||||
private static readonly IntPtr getProcDelegate;
|
||||
static GRGlInterface ()
|
||||
{
|
||||
getProcDelegate = new GRGlGetProcDelegateInternal (GrGLGetProcInternal);
|
||||
getProcDelegateInternal = new GRGlGetProcDelegateInternal (GrGLGetProcInternal);
|
||||
getProcDelegate = Marshal.GetFunctionPointerForDelegate (getProcDelegateInternal);
|
||||
}
|
||||
|
||||
[Preserve]
|
||||
|
@ -79,13 +81,9 @@ namespace SkiaSharp
|
|||
}
|
||||
|
||||
// try the native default
|
||||
var del = Marshal.GetFunctionPointerForDelegate (getProcDelegate);
|
||||
|
||||
var ctx = new GRGlGetProcDelegateContext (context, get);
|
||||
var ptr = ctx.Wrap ();
|
||||
var glInterface = GetObject<GRGlInterface> (SkiaApi.gr_glinterface_assemble_interface (ptr, del));
|
||||
GRGlGetProcDelegateContext.Free (ptr);
|
||||
return glInterface;
|
||||
using (var ctx = new NativeDelegateContext (context, get)) {
|
||||
return GetObject<GRGlInterface> (SkiaApi.gr_glinterface_assemble_interface (ctx.NativeContext, getProcDelegate));
|
||||
}
|
||||
}
|
||||
|
||||
public static GRGlInterface AssembleAngleInterface (GRGlGetProcDelegate get)
|
||||
|
@ -106,13 +104,9 @@ namespace SkiaSharp
|
|||
|
||||
public static GRGlInterface AssembleGlInterface (object context, GRGlGetProcDelegate get)
|
||||
{
|
||||
var del = Marshal.GetFunctionPointerForDelegate (getProcDelegate);
|
||||
|
||||
var ctx = new GRGlGetProcDelegateContext (context, get);
|
||||
var ptr = ctx.Wrap ();
|
||||
var glInterface = GetObject<GRGlInterface> (SkiaApi.gr_glinterface_assemble_gl_interface (ptr, del));
|
||||
GRGlGetProcDelegateContext.Free (ptr);
|
||||
return glInterface;
|
||||
using (var ctx = new NativeDelegateContext (context, get)) {
|
||||
return GetObject<GRGlInterface> (SkiaApi.gr_glinterface_assemble_gl_interface (ctx.NativeContext, getProcDelegate));
|
||||
}
|
||||
}
|
||||
|
||||
public static GRGlInterface AssembleGlesInterface (GRGlGetProcDelegate get)
|
||||
|
@ -122,13 +116,9 @@ namespace SkiaSharp
|
|||
|
||||
public static GRGlInterface AssembleGlesInterface (object context, GRGlGetProcDelegate get)
|
||||
{
|
||||
var del = Marshal.GetFunctionPointerForDelegate (getProcDelegate);
|
||||
|
||||
var ctx = new GRGlGetProcDelegateContext (context, get);
|
||||
var ptr = ctx.Wrap ();
|
||||
var glInterface = GetObject<GRGlInterface> (SkiaApi.gr_glinterface_assemble_gles_interface (ptr, del));
|
||||
GRGlGetProcDelegateContext.Free (ptr);
|
||||
return glInterface;
|
||||
using (var ctx = new NativeDelegateContext (context, get)) {
|
||||
return GetObject<GRGlInterface> (SkiaApi.gr_glinterface_assemble_gles_interface (ctx.NativeContext, getProcDelegate));
|
||||
}
|
||||
}
|
||||
|
||||
public GRGlInterface Clone ()
|
||||
|
@ -161,62 +151,8 @@ namespace SkiaSharp
|
|||
#endif
|
||||
private static IntPtr GrGLGetProcInternal (IntPtr context, string name)
|
||||
{
|
||||
var ctx = GRGlGetProcDelegateContext.Unwrap (context);
|
||||
return ctx.GetProc (ctx.Context, name);
|
||||
}
|
||||
|
||||
// This is the actual context passed to native code.
|
||||
// Instead of marshalling the user's data as an IntPtr and requiring
|
||||
// him to wrap/unwarp, we do it via a proxy class. This also prevents
|
||||
// us from having to marshal the user's callback too.
|
||||
private struct GRGlGetProcDelegateContext
|
||||
{
|
||||
// instead of pinning the struct, we pin a GUID which is paired to the struct
|
||||
private static readonly IDictionary<Guid, GRGlGetProcDelegateContext> contexts = new Dictionary<Guid, GRGlGetProcDelegateContext>();
|
||||
|
||||
// the "managed version" of the callback
|
||||
public readonly GRGlGetProcDelegate GetProc;
|
||||
public readonly object Context;
|
||||
|
||||
public GRGlGetProcDelegateContext (object context, GRGlGetProcDelegate get)
|
||||
{
|
||||
Context = context;
|
||||
GetProc = get;
|
||||
}
|
||||
|
||||
// wrap this context into a "native" pointer
|
||||
public IntPtr Wrap ()
|
||||
{
|
||||
var guid = Guid.NewGuid ();
|
||||
lock (contexts) {
|
||||
contexts.Add (guid, this);
|
||||
}
|
||||
var gc = GCHandle.Alloc (guid, GCHandleType.Pinned);
|
||||
return GCHandle.ToIntPtr (gc);
|
||||
}
|
||||
|
||||
// unwrap the "native" pointer into a managed context
|
||||
public static GRGlGetProcDelegateContext Unwrap (IntPtr ptr)
|
||||
{
|
||||
var gchandle = GCHandle.FromIntPtr (ptr);
|
||||
var guid = (Guid) gchandle.Target;
|
||||
lock (contexts) {
|
||||
GRGlGetProcDelegateContext value;
|
||||
contexts.TryGetValue (guid, out value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// unwrap and free the context
|
||||
public static void Free (IntPtr ptr)
|
||||
{
|
||||
var gchandle = GCHandle.FromIntPtr (ptr);
|
||||
var guid = (Guid) gchandle.Target;
|
||||
lock (contexts) {
|
||||
contexts.Remove (guid);
|
||||
}
|
||||
gchandle.Free ();
|
||||
}
|
||||
var ctx = NativeDelegateContext.Unwrap (context);
|
||||
return ctx.GetDelegate<GRGlGetProcDelegate> () (ctx.ManagedContext, name);
|
||||
}
|
||||
|
||||
private static class AngleLoader
|
||||
|
|
|
@ -26,10 +26,12 @@ namespace SkiaSharp
|
|||
private const string UnableToAllocatePixelsMessage = "Unable to allocate pixels for the bitmap.";
|
||||
|
||||
// so the GC doesn't collect the delegate
|
||||
private static readonly SKBitmapReleaseDelegateInternal releaseDelegate;
|
||||
private static readonly SKBitmapReleaseDelegateInternal releaseDelegateInternal;
|
||||
private static readonly IntPtr releaseDelegate;
|
||||
static SKBitmap ()
|
||||
{
|
||||
releaseDelegate = new SKBitmapReleaseDelegateInternal (SKBitmapReleaseInternal);
|
||||
releaseDelegateInternal = new SKBitmapReleaseDelegateInternal (SKBitmapReleaseInternal);
|
||||
releaseDelegate = Marshal.GetFunctionPointerForDelegate (releaseDelegateInternal);
|
||||
}
|
||||
|
||||
[Preserve]
|
||||
|
@ -489,12 +491,8 @@ namespace SkiaSharp
|
|||
if (releaseProc == null) {
|
||||
return SkiaApi.sk_bitmap_install_pixels (Handle, ref info, pixels, (IntPtr)rowBytes, ct, IntPtr.Zero, IntPtr.Zero);
|
||||
} else {
|
||||
var del = Marshal.GetFunctionPointerForDelegate (releaseDelegate);
|
||||
|
||||
var ctx = new SKBitmapReleaseDelegateContext (releaseProc, context);
|
||||
var ctxPtr = ctx.Wrap ();
|
||||
|
||||
return SkiaApi.sk_bitmap_install_pixels (Handle, ref info, pixels, (IntPtr)rowBytes, ct, del, ctxPtr);
|
||||
var ctx = new NativeDelegateContext (context, releaseProc);
|
||||
return SkiaApi.sk_bitmap_install_pixels (Handle, ref info, pixels, (IntPtr)rowBytes, ct, releaseDelegate, ctx.NativeContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,63 +550,8 @@ namespace SkiaSharp
|
|||
#endif
|
||||
private static void SKBitmapReleaseInternal (IntPtr address, IntPtr context)
|
||||
{
|
||||
var ctx = SKBitmapReleaseDelegateContext.Unwrap (context);
|
||||
ctx.Release (address, ctx.Context);
|
||||
|
||||
SKBitmapReleaseDelegateContext.Free (context);
|
||||
}
|
||||
|
||||
// This is the actual context passed to native code.
|
||||
// Instead of marshalling the user's data as an IntPtr and requiring
|
||||
// him to wrap/unwarp, we do it via a proxy class. This also prevents
|
||||
// us from having to marshal the user's callback too.
|
||||
private struct SKBitmapReleaseDelegateContext
|
||||
{
|
||||
// instead of pinning the struct, we pin a GUID which is paired to the struct
|
||||
private static readonly IDictionary<Guid, SKBitmapReleaseDelegateContext> contexts = new Dictionary<Guid, SKBitmapReleaseDelegateContext>();
|
||||
|
||||
// the "managed version" of the callback
|
||||
public readonly SKBitmapReleaseDelegate Release;
|
||||
public readonly object Context;
|
||||
|
||||
public SKBitmapReleaseDelegateContext (SKBitmapReleaseDelegate releaseProc, object context)
|
||||
{
|
||||
Release = releaseProc;
|
||||
Context = context;
|
||||
}
|
||||
|
||||
// wrap this context into a "native" pointer
|
||||
public IntPtr Wrap ()
|
||||
{
|
||||
var guid = Guid.NewGuid ();
|
||||
lock (contexts) {
|
||||
contexts.Add (guid, this);
|
||||
}
|
||||
var gc = GCHandle.Alloc (guid, GCHandleType.Pinned);
|
||||
return GCHandle.ToIntPtr (gc);
|
||||
}
|
||||
|
||||
// unwrap the "native" pointer into a managed context
|
||||
public static SKBitmapReleaseDelegateContext Unwrap (IntPtr ptr)
|
||||
{
|
||||
var gchandle = GCHandle.FromIntPtr (ptr);
|
||||
var guid = (Guid) gchandle.Target;
|
||||
lock (contexts) {
|
||||
SKBitmapReleaseDelegateContext value;
|
||||
contexts.TryGetValue (guid, out value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// unwrap and free the context
|
||||
public static void Free (IntPtr ptr)
|
||||
{
|
||||
var gchandle = GCHandle.FromIntPtr (ptr);
|
||||
var guid = (Guid) gchandle.Target;
|
||||
lock (contexts) {
|
||||
contexts.Remove (guid);
|
||||
}
|
||||
gchandle.Free ();
|
||||
using (var ctx = NativeDelegateContext.Unwrap (context)) {
|
||||
ctx.GetDelegate<SKBitmapReleaseDelegate> () (address, ctx.ManagedContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,14 +61,13 @@ namespace SkiaSharp
|
|||
get
|
||||
{
|
||||
var count = Count;
|
||||
var colors = new SKColor[count];
|
||||
var type = typeof(SKColor);
|
||||
var size = SizeOf <SKColor> ();
|
||||
var pointer = ReadColors ();
|
||||
for (var i = 0; i < count; i++) {
|
||||
colors[i] = PtrToStructure <SKColor> (pointer + (i * size));
|
||||
|
||||
if (count == 0 || pointer == IntPtr.Zero) {
|
||||
return new SKColor[0];
|
||||
}
|
||||
return colors;
|
||||
|
||||
return PtrToStructureArray <SKColor> (pointer, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,8 +82,7 @@ namespace SkiaSharp
|
|||
throw new ArgumentOutOfRangeException (nameof (index));
|
||||
}
|
||||
|
||||
var size = SizeOf <SKColor> ();
|
||||
return PtrToStructure <SKColor> (pointer + (index * size));
|
||||
return PtrToStructure <SKColor> (pointer, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
// Copyright 2016 Xamarin Inc
|
||||
//
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
|
@ -21,9 +22,33 @@ namespace SkiaSharp
|
|||
Webp,
|
||||
Ktx,
|
||||
}
|
||||
|
||||
|
||||
// public delegates
|
||||
public delegate void SKImageRasterReleaseDelegate (IntPtr pixels, object context);
|
||||
public delegate void SKImageTextureReleaseDelegate (object context);
|
||||
|
||||
// internal proxy delegates
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void SKImageRasterReleaseDelegateInternal (IntPtr pixels, IntPtr context);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void SKImageTextureReleaseDelegateInternal (IntPtr context);
|
||||
|
||||
public class SKImage : SKObject
|
||||
{
|
||||
// so the GC doesn't collect the delegate
|
||||
private static readonly SKImageRasterReleaseDelegateInternal rasterReleaseDelegateInternal;
|
||||
private static readonly SKImageTextureReleaseDelegateInternal textureReleaseDelegateInternal;
|
||||
private static readonly IntPtr rasterReleaseDelegate;
|
||||
private static readonly IntPtr textureReleaseDelegate;
|
||||
static SKImage()
|
||||
{
|
||||
rasterReleaseDelegateInternal = new SKImageRasterReleaseDelegateInternal (RasterReleaseInternal);
|
||||
textureReleaseDelegateInternal = new SKImageTextureReleaseDelegateInternal (TextureReleaseInternal);
|
||||
|
||||
rasterReleaseDelegate = Marshal.GetFunctionPointerForDelegate (rasterReleaseDelegateInternal);
|
||||
textureReleaseDelegate = Marshal.GetFunctionPointerForDelegate (textureReleaseDelegateInternal);
|
||||
}
|
||||
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (Handle != IntPtr.Zero && OwnsHandle) {
|
||||
|
@ -39,15 +64,65 @@ namespace SkiaSharp
|
|||
{
|
||||
}
|
||||
|
||||
[Obsolete ("Use FromCopyPixels instead.")]
|
||||
public static SKImage FromPixels (SKImageInfo info, IntPtr pixels, int rowBytes)
|
||||
{
|
||||
return FromCopyPixels (info, pixels, rowBytes);
|
||||
}
|
||||
|
||||
public static SKImage FromCopyPixels (SKImageInfo info, IntPtr pixels, int rowBytes)
|
||||
{
|
||||
return FromCopyPixels (info, pixels, rowBytes, null);
|
||||
}
|
||||
|
||||
public static SKImage FromCopyPixels (SKImageInfo info, IntPtr pixels, int rowBytes, SKColorTable ctable)
|
||||
{
|
||||
if (pixels == IntPtr.Zero)
|
||||
throw new ArgumentNullException (nameof (pixels));
|
||||
var handle = SkiaApi.sk_image_new_raster_copy (ref info, pixels, (IntPtr) rowBytes);
|
||||
|
||||
var ct = (ctable == null ? IntPtr.Zero : ctable.Handle);
|
||||
var handle = SkiaApi.sk_image_new_raster_copy_with_colortable (ref info, pixels, (IntPtr) rowBytes, ct);
|
||||
return GetObject<SKImage> (handle);
|
||||
}
|
||||
|
||||
public static SKImage FromData (SKData data, SKRectI subset)
|
||||
public static SKImage FromCopyPixels (SKPixmap pixmap)
|
||||
{
|
||||
if (pixmap == null)
|
||||
throw new ArgumentNullException (nameof (pixmap));
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_raster_copy_with_pixmap (pixmap.Handle));
|
||||
}
|
||||
|
||||
public static SKImage FromPixelData (SKImageInfo info, SKData data, int rowBytes)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_raster_data (ref info, data.Handle, (IntPtr) rowBytes));
|
||||
}
|
||||
|
||||
public static SKImage FromPixels (SKPixmap pixmap)
|
||||
{
|
||||
return FromPixels (pixmap, null, null);
|
||||
}
|
||||
|
||||
public static SKImage FromPixels (SKPixmap pixmap, SKImageRasterReleaseDelegate releaseProc)
|
||||
{
|
||||
return FromPixels (pixmap, releaseProc, null);
|
||||
}
|
||||
|
||||
public static SKImage FromPixels (SKPixmap pixmap, SKImageRasterReleaseDelegate releaseProc, object releaseContext)
|
||||
{
|
||||
if (pixmap == null)
|
||||
throw new ArgumentNullException (nameof (pixmap));
|
||||
|
||||
if (releaseProc == null) {
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_raster (pixmap.Handle, IntPtr.Zero, IntPtr.Zero));
|
||||
} else {
|
||||
var ctx = new NativeDelegateContext (releaseContext, releaseProc);
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_raster (pixmap.Handle, rasterReleaseDelegate, ctx.NativeContext));
|
||||
}
|
||||
}
|
||||
|
||||
public static SKImage FromEncodedData (SKData data, SKRectI subset)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
@ -55,7 +130,7 @@ namespace SkiaSharp
|
|||
return GetObject<SKImage> (handle);
|
||||
}
|
||||
|
||||
public static SKImage FromData (SKData data)
|
||||
public static SKImage FromEncodedData (SKData data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
@ -63,6 +138,18 @@ namespace SkiaSharp
|
|||
return GetObject<SKImage> (handle);
|
||||
}
|
||||
|
||||
[Obsolete ("Use FromEncodedData instead.")]
|
||||
public static SKImage FromData (SKData data, SKRectI subset)
|
||||
{
|
||||
return FromEncodedData (data, subset);
|
||||
}
|
||||
|
||||
[Obsolete ("Use FromEncodedData instead.")]
|
||||
public static SKImage FromData (SKData data)
|
||||
{
|
||||
return FromEncodedData (data);
|
||||
}
|
||||
|
||||
public static SKImage FromBitmap (SKBitmap bitmap)
|
||||
{
|
||||
if (bitmap == null)
|
||||
|
@ -71,6 +158,75 @@ namespace SkiaSharp
|
|||
return GetObject<SKImage> (handle);
|
||||
}
|
||||
|
||||
public static SKImage FromTexture (GRContext context, GRBackendTextureDesc desc)
|
||||
{
|
||||
return FromTexture (context, desc, SKAlphaType.Premul);
|
||||
}
|
||||
|
||||
public static SKImage FromTexture (GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha)
|
||||
{
|
||||
return FromTexture (context, desc, alpha, null);
|
||||
}
|
||||
|
||||
public static SKImage FromTexture (GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha, SKImageTextureReleaseDelegate releaseProc)
|
||||
{
|
||||
return FromTexture (context, desc, alpha, releaseProc, null);
|
||||
}
|
||||
|
||||
public static SKImage FromTexture (GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha, SKImageTextureReleaseDelegate releaseProc, object releaseContext)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
|
||||
if (releaseProc == null) {
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_from_texture (context.Handle, ref desc, alpha, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero));
|
||||
} else {
|
||||
var ctx = new NativeDelegateContext (releaseContext, releaseProc);
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_from_texture (context.Handle, ref desc, alpha, IntPtr.Zero, textureReleaseDelegate, ctx.NativeContext));
|
||||
}
|
||||
}
|
||||
|
||||
public static SKImage FromAdoptedTexture (GRContext context, GRBackendTextureDesc desc)
|
||||
{
|
||||
return FromAdoptedTexture (context, desc, SKAlphaType.Premul);
|
||||
}
|
||||
|
||||
public static SKImage FromAdoptedTexture (GRContext context, GRBackendTextureDesc desc, SKAlphaType alpha)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_from_adopted_texture (context.Handle, ref desc, alpha, IntPtr.Zero));
|
||||
}
|
||||
|
||||
public static SKImage FromPicture (SKPicture picture, SKSizeI dimensions)
|
||||
{
|
||||
return FromPicture (picture, dimensions, null);
|
||||
}
|
||||
|
||||
public static SKImage FromPicture (SKPicture picture, SKSizeI dimensions, SKMatrix matrix)
|
||||
{
|
||||
return FromPicture (picture, dimensions, matrix, null);
|
||||
}
|
||||
|
||||
public static SKImage FromPicture (SKPicture picture, SKSizeI dimensions, SKPaint paint)
|
||||
{
|
||||
if (picture == null)
|
||||
throw new ArgumentNullException (nameof (picture));
|
||||
|
||||
var p = (paint == null ? IntPtr.Zero : paint.Handle);
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_from_picture (picture.Handle, ref dimensions, IntPtr.Zero, p));
|
||||
}
|
||||
|
||||
public static SKImage FromPicture (SKPicture picture, SKSizeI dimensions, SKMatrix matrix, SKPaint paint)
|
||||
{
|
||||
if (picture == null)
|
||||
throw new ArgumentNullException (nameof (picture));
|
||||
|
||||
var p = (paint == null ? IntPtr.Zero : paint.Handle);
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_new_from_picture (picture.Handle, ref dimensions, ref matrix, p));
|
||||
}
|
||||
|
||||
public SKData Encode ()
|
||||
{
|
||||
return GetObject<SKData> (SkiaApi.sk_image_encode (Handle));
|
||||
|
@ -84,6 +240,126 @@ namespace SkiaSharp
|
|||
public int Width => SkiaApi.sk_image_get_width (Handle);
|
||||
public int Height => SkiaApi.sk_image_get_height (Handle);
|
||||
public uint UniqueId => SkiaApi.sk_image_get_unique_id (Handle);
|
||||
public SKAlphaType AlphaType => SkiaApi.sk_image_get_alpha_type (Handle);
|
||||
public bool IsAlphaOnly => SkiaApi.sk_image_is_alpha_only (Handle);
|
||||
|
||||
public SKShader ToShader (SKShaderTileMode tileX, SKShaderTileMode tileY)
|
||||
{
|
||||
return GetObject<SKShader> (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, IntPtr.Zero));
|
||||
}
|
||||
|
||||
public SKShader ToShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKMatrix localMatrix)
|
||||
{
|
||||
return GetObject<SKShader> (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, ref localMatrix));
|
||||
}
|
||||
|
||||
public bool PeekPixels (SKPixmap pixmap)
|
||||
{
|
||||
if (pixmap == null)
|
||||
throw new ArgumentNullException (nameof (pixmap));
|
||||
return SkiaApi.sk_bitmap_peek_pixels (Handle, pixmap.Handle);
|
||||
}
|
||||
|
||||
public SKPixmap PeekPixels ()
|
||||
{
|
||||
var pixmap = new SKPixmap ();
|
||||
if (!PeekPixels (pixmap)) {
|
||||
pixmap.Dispose ();
|
||||
pixmap = null;
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
public bool IsTextureBacked => SkiaApi.sk_image_is_texture_backed (Handle);
|
||||
|
||||
public bool ReadPixels (SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY)
|
||||
{
|
||||
return ReadPixels (dstInfo, dstPixels, dstRowBytes, srcX, srcY, SKImageCachingHint.Allow);
|
||||
}
|
||||
|
||||
public bool ReadPixels (SKImageInfo dstInfo, IntPtr dstPixels, int dstRowBytes, int srcX, int srcY, SKImageCachingHint cachingHint)
|
||||
{
|
||||
return SkiaApi.sk_image_read_pixels (Handle, ref dstInfo, dstPixels, (IntPtr)dstRowBytes, srcX, srcY, cachingHint);
|
||||
}
|
||||
|
||||
public bool ReadPixels (SKPixmap pixmap, int srcX, int srcY)
|
||||
{
|
||||
return ReadPixels (pixmap, srcX, srcY, SKImageCachingHint.Allow);
|
||||
}
|
||||
|
||||
public bool ReadPixels (SKPixmap pixmap, int srcX, int srcY, SKImageCachingHint cachingHint)
|
||||
{
|
||||
if (pixmap == null)
|
||||
throw new ArgumentNullException (nameof (pixmap));
|
||||
return SkiaApi.sk_image_read_pixels_into_pixmap (Handle, pixmap.Handle, srcX, srcY, cachingHint);
|
||||
}
|
||||
|
||||
public SKPixmap ScalePixels (SKFilterQuality quality, SKImageCachingHint cachingHint)
|
||||
{
|
||||
var pixmap = new SKPixmap ();
|
||||
if (!ScalePixels (pixmap, quality, cachingHint)) {
|
||||
pixmap.Dispose ();
|
||||
pixmap = null;
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
public bool ScalePixels (SKPixmap dst, SKFilterQuality quality)
|
||||
{
|
||||
return ScalePixels (dst, quality, SKImageCachingHint.Allow);
|
||||
}
|
||||
|
||||
public bool ScalePixels (SKPixmap dst, SKFilterQuality quality, SKImageCachingHint cachingHint)
|
||||
{
|
||||
if (dst == null)
|
||||
throw new ArgumentNullException (nameof (dst));
|
||||
return SkiaApi.sk_image_scale_pixels (Handle, dst.Handle, quality, cachingHint);
|
||||
}
|
||||
|
||||
public SKImage Subset (SKRectI subset)
|
||||
{
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_make_subset (Handle, ref subset));
|
||||
}
|
||||
|
||||
public SKImage ToTextureImage (GRContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw new ArgumentNullException (nameof (context));
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_make_texture_image (Handle, context.Handle));
|
||||
}
|
||||
|
||||
public SKImage ToRasterImage ()
|
||||
{
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_make_non_texture_image (Handle));
|
||||
}
|
||||
|
||||
public SKImage ApplyImageFilter (SKImageFilter filter, SKRectI subset, SKRectI clipBounds, out SKRectI outSubset, out SKPoint outOffset)
|
||||
{
|
||||
if (filter == null)
|
||||
throw new ArgumentNullException (nameof (filter));
|
||||
return GetObject<SKImage> (SkiaApi.sk_image_make_with_filter (Handle, filter.Handle, ref subset, ref clipBounds, out outSubset, out outOffset));
|
||||
}
|
||||
|
||||
// internal proxies
|
||||
|
||||
#if __IOS__
|
||||
[ObjCRuntime.MonoPInvokeCallback (typeof (SKImageRasterReleaseDelegateInternal))]
|
||||
#endif
|
||||
private static void RasterReleaseInternal (IntPtr pixels, IntPtr context)
|
||||
{
|
||||
using (var ctx = NativeDelegateContext.Unwrap (context)) {
|
||||
ctx.GetDelegate<SKImageRasterReleaseDelegate> () (pixels, ctx.ManagedContext);
|
||||
}
|
||||
}
|
||||
|
||||
#if __IOS__
|
||||
[ObjCRuntime.MonoPInvokeCallback (typeof (SKImageTextureReleaseDelegateInternal))]
|
||||
#endif
|
||||
private static void TextureReleaseInternal (IntPtr context)
|
||||
{
|
||||
using (var ctx = NativeDelegateContext.Unwrap (context)) {
|
||||
ctx.GetDelegate<SKImageTextureReleaseDelegate> () (ctx.ManagedContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace SkiaSharp
|
|||
internal static int SizeOf <T> ()
|
||||
{
|
||||
#if WINDOWS_UWP || NET_STANDARD
|
||||
return Marshal.SizeOf <IntPtr> ();
|
||||
return Marshal.SizeOf <T> ();
|
||||
#else
|
||||
return Marshal.SizeOf (typeof (IntPtr));
|
||||
#endif
|
||||
|
@ -194,6 +194,23 @@ namespace SkiaSharp
|
|||
#endif
|
||||
}
|
||||
|
||||
internal T[] PtrToStructureArray <T> (IntPtr intPtr, int count)
|
||||
{
|
||||
var items = new T[count];
|
||||
var size = SizeOf <T> ();
|
||||
for (var i = 0; i < count; i++) {
|
||||
var newPtr = new IntPtr (intPtr.ToInt64 () + (i * size));
|
||||
items[i] = PtrToStructure <T> (newPtr);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
internal T PtrToStructure <T> (IntPtr intPtr, int index)
|
||||
{
|
||||
var size = SizeOf <T> ();
|
||||
var newPtr = new IntPtr (intPtr.ToInt64 () + (index * size));
|
||||
return PtrToStructure <T> (newPtr);
|
||||
}
|
||||
}
|
||||
|
||||
public class SKNativeObject : IDisposable
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
// Copyright 2015 Xamarin Inc
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using GRBackendObject = System.IntPtr;
|
||||
|
@ -430,28 +431,80 @@ namespace SkiaSharp
|
|||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_paint_t sk_paint_clone(sk_paint_t cpaint);
|
||||
|
||||
// Image
|
||||
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void sk_image_ref(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void sk_image_unref(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_raster_copy(ref SKImageInfo info, IntPtr pixels, IntPtr rowBytes);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_raster_copy_with_pixmap(sk_pixmap_t pixmap);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_raster_copy_with_colortable(ref SKImageInfo info, IntPtr pixels, IntPtr rowBytes, sk_colortable_t ctable);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_raster_data(ref SKImageInfo info, sk_data_t pixels, IntPtr rowBytes);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_raster(sk_pixmap_t pixmap, IntPtr releaseProc, IntPtr context);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_from_bitmap(sk_bitmap_t cbitmap);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_from_encoded(sk_data_t encoded, ref SKRectI subset);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_from_encoded(sk_data_t encoded, IntPtr subsetPtr);
|
||||
public extern static sk_image_t sk_image_new_from_encoded(sk_data_t encoded, IntPtr subsetZero);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_data_t sk_image_encode(sk_image_t t);
|
||||
public extern static sk_image_t sk_image_new_from_texture(gr_context_t context, ref GRBackendTextureDesc desc, SKAlphaType alpha, sk_colorspace_t colorSpace, IntPtr releaseProc, IntPtr releaseContext);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_data_t sk_image_encode_specific(sk_image_t t, SKImageEncodeFormat format, int quality);
|
||||
public extern static sk_image_t sk_image_new_from_adopted_texture(gr_context_t context, ref GRBackendTextureDesc desc, SKAlphaType alpha, sk_colorspace_t colorSpace);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_new_from_bitmap(sk_bitmap_t b);
|
||||
public extern static sk_image_t sk_image_new_from_picture(sk_picture_t picture, ref SKSizeI dimensions, ref SKMatrix matrix, sk_paint_t paint);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void sk_image_unref(sk_image_t t);
|
||||
public extern static sk_image_t sk_image_new_from_picture(sk_picture_t picture, ref SKSizeI dimensions, IntPtr matrixZero, sk_paint_t paint);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int sk_image_get_width(sk_image_t t);
|
||||
public extern static int sk_image_get_width(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int sk_image_get_height(sk_image_t t);
|
||||
public extern static int sk_image_get_height(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static uint sk_image_get_unique_id(sk_image_t t);
|
||||
public extern static uint sk_image_get_unique_id(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static SKAlphaType sk_image_get_alpha_type(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_image_is_alpha_only(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_shader_t sk_image_make_shader(sk_image_t image, SKShaderTileMode tileX, SKShaderTileMode tileY, ref SKMatrix localMatrix);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_shader_t sk_image_make_shader(sk_image_t image, SKShaderTileMode tileX, SKShaderTileMode tileY, IntPtr localMatrixZero);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_image_peek_pixels(sk_image_t image, sk_pixmap_t pixmap);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_image_is_texture_backed(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_image_read_pixels(sk_image_t image, ref SKImageInfo dstInfo, IntPtr dstPixels, IntPtr dstRowBytes, int srcX, int srcY, SKImageCachingHint cachingHint);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_image_read_pixels_into_pixmap(sk_image_t image, sk_pixmap_t dst, int srcX, int srcY, SKImageCachingHint cachingHint);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_image_scale_pixels(sk_image_t image, sk_pixmap_t dst, SKFilterQuality quality, SKImageCachingHint cachingHint);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_data_t sk_image_encode(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_data_t sk_image_encode_specific(sk_image_t image, SKImageEncodeFormat encoder, int quality);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_make_subset(sk_image_t image, ref SKRectI subset);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_make_texture_image(sk_image_t image, gr_context_t context);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_make_non_texture_image(sk_image_t image);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_image_t sk_image_make_with_filter(sk_image_t image, sk_imagefilter_t filter, ref SKRectI subset, ref SKRectI clipbounds, out SKRectI outSubset, out SKPoint outOffset);
|
||||
|
||||
// Path
|
||||
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
|
@ -1531,6 +1584,79 @@ namespace SkiaSharp
|
|||
public extern static void sk_region_get_bounds(sk_region_t r, out SKRectI rect);
|
||||
}
|
||||
|
||||
// This is the actual context passed to native code.
|
||||
// Instead of marshalling the user's data as an IntPtr and requiring
|
||||
// him to wrap/unwarp, we do it via a proxy class. This also prevents
|
||||
// us from having to marshal the user's callback too.
|
||||
internal class NativeDelegateContext : IDisposable
|
||||
{
|
||||
// instead of pinning the struct, we pin a GUID which is paired to the struct
|
||||
private static readonly IDictionary<Guid, NativeDelegateContext> contexts = new Dictionary<Guid, NativeDelegateContext>();
|
||||
|
||||
// the "managed version" of the callback
|
||||
private readonly Delegate managedDelegate;
|
||||
|
||||
public NativeDelegateContext(object context, Delegate get)
|
||||
{
|
||||
managedDelegate = get;
|
||||
ManagedContext = context;
|
||||
NativeContext = Wrap();
|
||||
}
|
||||
|
||||
public object ManagedContext { get; }
|
||||
|
||||
public IntPtr NativeContext { get; }
|
||||
|
||||
public T GetDelegate<T>()
|
||||
{
|
||||
return (T)(object)managedDelegate;
|
||||
}
|
||||
|
||||
// wrap this context into a "native" pointer
|
||||
public IntPtr Wrap()
|
||||
{
|
||||
var guid = Guid.NewGuid();
|
||||
lock (contexts)
|
||||
{
|
||||
contexts.Add(guid, this);
|
||||
}
|
||||
var gc = GCHandle.Alloc(guid, GCHandleType.Pinned);
|
||||
return GCHandle.ToIntPtr(gc);
|
||||
}
|
||||
|
||||
// unwrap the "native" pointer into a managed context
|
||||
public static NativeDelegateContext Unwrap(IntPtr ptr)
|
||||
{
|
||||
var gchandle = GCHandle.FromIntPtr(ptr);
|
||||
var guid = (Guid)gchandle.Target;
|
||||
lock (contexts)
|
||||
{
|
||||
NativeDelegateContext value;
|
||||
contexts.TryGetValue(guid, out value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
Free(NativeContext);
|
||||
}
|
||||
|
||||
// unwrap and free the context
|
||||
public static void Free(IntPtr ptr)
|
||||
{
|
||||
var gchandle = GCHandle.FromIntPtr(ptr);
|
||||
var guid = (Guid)gchandle.Target;
|
||||
lock (contexts)
|
||||
{
|
||||
contexts.Remove(guid);
|
||||
}
|
||||
gchandle.Free();
|
||||
}
|
||||
|
||||
void IDisposable.Dispose() => Free();
|
||||
}
|
||||
|
||||
internal static class PlatformConfiguration
|
||||
{
|
||||
public static bool IsUnix { get; }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<!-- if ShouldIncludeNativeSkiaSharp == False then don't include the native libSkiaSharp -->
|
||||
|
@ -30,7 +30,7 @@
|
|||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)..\..\runtimes\win7-x64\native\libSkiaSharp.dll">
|
||||
<Link>x64\libSkiaSharp.dll</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
|
|
12
build.cake
12
build.cake
|
@ -15,8 +15,7 @@ var NuGetSources = new [] { MakeAbsolute (Directory ("./output")).FullPath, "htt
|
|||
var NugetToolPath = GetToolPath ("nuget.exe");
|
||||
var XamarinComponentToolPath = GetToolPath ("xamarin-component.exe");
|
||||
var CakeToolPath = GetToolPath ("Cake/Cake.exe");
|
||||
var TestConsoleToolPath_x86 = GetToolPath ("xunit.runner.console/tools/xunit.console.x86.exe");
|
||||
var TestConsoleToolPath_x64 = GetToolPath ("xunit.runner.console/tools/xunit.console.exe");
|
||||
var NUnitConsoleToolPath = GetToolPath ("NUnit.ConsoleRunner/tools/nunit3-console.exe");
|
||||
var GenApiToolPath = GetToolPath ("Microsoft.DotNet.BuildTools.GenAPI/tools/GenAPI.exe");
|
||||
var MDocPath = GetToolPath ("mdoc/mdoc.exe");
|
||||
|
||||
|
@ -264,13 +263,13 @@ Task ("tests")
|
|||
c.Properties ["Platform"] = new [] { "x86" };
|
||||
c.Verbosity = VERBOSITY;
|
||||
});
|
||||
RunTests("./tests/SkiaSharp.Desktop.Tests/bin/x86/Release/SkiaSharp.Desktop.Tests.dll", false);
|
||||
RunTests("./tests/SkiaSharp.Desktop.Tests/bin/x86/Release/SkiaSharp.Desktop.Tests.dll");
|
||||
DotNetBuild ("./tests/SkiaSharp.Desktop.Tests/SkiaSharp.Desktop.Tests.sln", c => {
|
||||
c.Configuration = "Release";
|
||||
c.Properties ["Platform"] = new [] { "x64" };
|
||||
c.Verbosity = VERBOSITY;
|
||||
});
|
||||
RunTests("./tests/SkiaSharp.Desktop.Tests/bin/x64/Release/SkiaSharp.Desktop.Tests.dll", true);
|
||||
RunTests("./tests/SkiaSharp.Desktop.Tests/bin/x64/Release/SkiaSharp.Desktop.Tests.dll");
|
||||
}
|
||||
// Mac OSX (Any CPU)
|
||||
if (IsRunningOnMac ()) {
|
||||
|
@ -278,7 +277,7 @@ Task ("tests")
|
|||
c.Configuration = "Release";
|
||||
c.Verbosity = VERBOSITY;
|
||||
});
|
||||
RunTests("./tests/SkiaSharp.Desktop.Tests/bin/AnyCPU/Release/SkiaSharp.Desktop.Tests.dll", false);
|
||||
RunTests("./tests/SkiaSharp.Desktop.Tests/bin/AnyCPU/Release/SkiaSharp.Desktop.Tests.dll");
|
||||
}
|
||||
// .NET Core
|
||||
RunDotNetCoreRestore ("./tests/SkiaSharp.NetCore.Tests");
|
||||
|
@ -726,8 +725,7 @@ Task ("Windows-CI")
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Information ("Cake.exe ToolPath: {0}", CakeToolPath);
|
||||
Information ("Cake.exe TestConsoleToolPath_x86: {0}", TestConsoleToolPath_x86);
|
||||
Information ("Cake.exe TestConsoleToolPath_x64: {0}", TestConsoleToolPath_x64);
|
||||
Information ("Cake.exe NUnitConsoleToolPath: {0}", NUnitConsoleToolPath);
|
||||
Information ("NuGet.exe ToolPath: {0}", NugetToolPath);
|
||||
Information ("Xamarin-Component.exe ToolPath: {0}", XamarinComponentToolPath);
|
||||
Information ("genapi.exe ToolPath: {0}", GenApiToolPath);
|
||||
|
|
|
@ -142,8 +142,10 @@ Task ("externals-native")
|
|||
if (!DirectoryExists ("./output/linux/x64/")) CreateDirectory ("./output/linux/x64/");
|
||||
if (!DirectoryExists ("./output/linux/x86/")) CreateDirectory ("./output/linux/x86/");
|
||||
CopyFileToDirectory ("./native-builds/lib/linux/x64/libSkiaSharp.so." + VERSION_SONAME, "./output/linux/x64/");
|
||||
// CopyFileToDirectory ("./native-builds/lib/linux/x86/libSkiaSharp.so." + VERSION_SONAME, "./output/linux/x86/");
|
||||
// the second copy excludes the file version
|
||||
CopyFile ("./native-builds/lib/linux/x64/libSkiaSharp.so." + VERSION_SONAME, "./output/linux/x64/libSkiaSharp.so");
|
||||
// CopyFile ("./native-builds/lib/linux/x86/libSkiaSharp.so." + VERSION_SONAME, "./output/linux/x86/libSkiaSharp.so");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -422,10 +424,13 @@ Task ("externals-android")
|
|||
// this builds the native C and C++ externals for Linux
|
||||
Task ("externals-linux")
|
||||
.WithCriteria (
|
||||
// !FileExists ("native-builds/lib/linux/x86/libSkiaSharp.so") ||
|
||||
!FileExists ("native-builds/lib/linux/x64/libSkiaSharp.so"))
|
||||
.WithCriteria (IsRunningOnLinux ())
|
||||
.Does (() =>
|
||||
{
|
||||
var SUPPORT_GPU = "1"; // 1 == true, 0 == false
|
||||
|
||||
var ninja = DEPOT_PATH.CombineWithFilePath ("ninja").FullPath;
|
||||
|
||||
// set up the gyp environment variables
|
||||
|
@ -442,22 +447,27 @@ Task ("externals-linux")
|
|||
SetEnvironmentVariable ("SKIA_OUT", outPath);
|
||||
|
||||
// build skia_lib
|
||||
RunGyp ("skia_os='linux' skia_arch_type='" + arch + "' skia_gpu=1 skia_pic=1 skia_pdf_use_sfntly=0", "ninja");
|
||||
RunGyp ("skia_os='linux' skia_arch_type='" + arch + "' skia_gpu=" + SUPPORT_GPU + " skia_pic=1 skia_pdf_use_sfntly=0 skia_freetype_static=1", "ninja");
|
||||
RunProcess (ninja, new ProcessSettings {
|
||||
Arguments = "-C out/" + folder + "/Release " + targets,
|
||||
WorkingDirectory = SKIA_PATH.FullPath,
|
||||
});
|
||||
// build libSkiaSharp
|
||||
// RunProcess ("make", new ProcessSettings {
|
||||
// Arguments = "clean",
|
||||
// WorkingDirectory = "native-builds/libSkiaSharp_linux",
|
||||
// });
|
||||
RunProcess ("make", new ProcessSettings {
|
||||
Arguments = "ARCH=" + folder + " VERSION=" + VERSION_FILE,
|
||||
Arguments = "ARCH=" + folder + " VERSION=" + VERSION_FILE + " SUPPORT_GPU=" + SUPPORT_GPU,
|
||||
WorkingDirectory = "native-builds/libSkiaSharp_linux",
|
||||
});
|
||||
});
|
||||
|
||||
buildArch ("x86_64", "x64");
|
||||
// buildArch ("x86", "x86");
|
||||
|
||||
// copy output
|
||||
foreach (var folder in new [] { "x64" }) {
|
||||
foreach (var folder in new [] { "x64" /* , "x86" */ }) {
|
||||
if (!DirectoryExists ("native-builds/lib/linux/" + folder)) {
|
||||
CreateDirectory ("native-builds/lib/linux/" + folder);
|
||||
}
|
||||
|
|
|
@ -58,11 +58,11 @@ var RunProcess = new Action<FilePath, ProcessSettings> ((process, settings) =>
|
|||
}
|
||||
});
|
||||
|
||||
var RunTests = new Action<FilePath, bool> ((testAssembly, is64) =>
|
||||
var RunTests = new Action<FilePath> ((testAssembly) =>
|
||||
{
|
||||
var dir = testAssembly.GetDirectory ();
|
||||
RunProcess (is64 ? TestConsoleToolPath_x64 : TestConsoleToolPath_x86, new ProcessSettings {
|
||||
Arguments = string.Format ("\"{0}\"", testAssembly),
|
||||
RunProcess (NUnitConsoleToolPath, new ProcessSettings {
|
||||
Arguments = string.Format ("\"{0}\" --work=\"{1}\"", testAssembly, dir),
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit b6f31e1c124184166dbd8e0993095015cf03dd24
|
||||
Subproject commit 705b36175b691b598bc06b12b7e2485946f3c88f
|
|
@ -1,5 +1,6 @@
|
|||
ARCH = x64
|
||||
VERSION = 1.0.0.0
|
||||
SUPPORT_GPU = 1
|
||||
|
||||
noop =
|
||||
space = ${noop} ${noop}
|
||||
|
@ -35,7 +36,6 @@ include_dirs = \
|
|||
library_paths = \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_core.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_effects.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_skgpu.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_opts.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_opts_sse41.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_opts_sse42.a \
|
||||
|
@ -45,7 +45,6 @@ library_paths = \
|
|||
../../externals/skia/out/${ARCH}/Release/libskia_utils.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_ports.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_images.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libsksl.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_pdf.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_codec.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_codec_android.a \
|
||||
|
@ -53,6 +52,7 @@ library_paths = \
|
|||
../../externals/skia/out/${ARCH}/Release/libskia_sfnt.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_svg.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_xml.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libfreetype_static.a \
|
||||
../../externals/skia/out/${ARCH}/Release/obj/gyp/libwebp_enc.a \
|
||||
../../externals/skia/out/${ARCH}/Release/obj/gyp/libwebp_dec.a \
|
||||
../../externals/skia/out/${ARCH}/Release/obj/gyp/libwebp_dsp.a \
|
||||
|
@ -68,24 +68,36 @@ library_paths = \
|
|||
../../externals/skia/out/${ARCH}/Release/obj/gyp/libpiex.a \
|
||||
../../externals/skia/out/${ARCH}/Release/obj/gyp/libexpat_static.a
|
||||
defines = \
|
||||
-DSK_INTERNAL -DSK_GAMMA_APPLY_TO_A8 -DQT_NO_KEYWORDS \
|
||||
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=1 \
|
||||
-DSK_FORCE_DISTANCE_FIELD_TEXT=0 -DSK_HAS_JPEG_LIBRARY \
|
||||
-DSK_HAS_PNG_LIBRARY -DSK_HAS_WEBP_LIBRARY -DSKIA_C_DLL \
|
||||
-DSKIA_IMPLEMENTATION=1 -DSK_CODEC_DECODES_RAW -DSK_SAMPLES_FOR_X \
|
||||
-DSK_INTERNAL -DSK_GAMMA_APPLY_TO_A8 -DQT_NO_KEYWORDS \
|
||||
-DSK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1 -DSK_SUPPORT_GPU=${SUPPORT_GPU} \
|
||||
-DSK_FORCE_DISTANCE_FIELD_TEXT=0 -DSK_HAS_JPEG_LIBRARY \
|
||||
-DSK_HAS_PNG_LIBRARY -DSK_HAS_WEBP_LIBRARY -DSKIA_C_DLL \
|
||||
-DSKIA_IMPLEMENTATION=1 -DSK_CODEC_DECODES_RAW -DSK_SAMPLES_FOR_X \
|
||||
-DSK_BUILD_FOR_UNIX -DNDEBUG
|
||||
cflags = \
|
||||
-msse2 -mfpmath=sse -g -fno-exceptions -fstrict-aliasing -Wall \
|
||||
-Wextra -Winit-self -Wpointer-arith -Wsign-compare -Wvla \
|
||||
-Wno-unused-parameter -Werror -Os \
|
||||
-fPIC -fdata-sections -ffunction-sections
|
||||
ifeq "${ARCH}" "x86"
|
||||
arch_cflags = -m32
|
||||
else
|
||||
arch_cflags =
|
||||
endif
|
||||
cflags_c =
|
||||
cflags_cc = -std=c++11 -fno-rtti -fno-threadsafe-statics -Wnon-virtual-dtor
|
||||
ldflags = $(library_dirs:%=-L%) -lpthread -ldl -lfontconfig -lfreetype -lGL -lGLU -lX11
|
||||
ldflags = $(library_dirs:%=-L%) -lpthread -ldl -lfontconfig
|
||||
includes = $(include_dirs:%=-I%)
|
||||
library_names = $(notdir ${library_paths})
|
||||
libraries = $(library_names:lib%.a=-l%)
|
||||
|
||||
# add the extras for GPU
|
||||
ifeq "${SUPPORT_GPU}" "1"
|
||||
library_paths += \
|
||||
../../externals/skia/out/${ARCH}/Release/libskia_skgpu.a \
|
||||
../../externals/skia/out/${ARCH}/Release/libsksl.a
|
||||
endif
|
||||
|
||||
src = $(shell find ${src_root} -name *.cpp -or -name *.c)
|
||||
src_names = $(notdir ${src})
|
||||
objs = $(src_names:%=${objarch_root}/%.o)
|
||||
|
@ -94,13 +106,13 @@ deps = $(objs:.o=.d)
|
|||
${objarch_root}/%.o: ${src_root}/%
|
||||
# build the local source
|
||||
mkdir -p $(dir $@)
|
||||
c++ -MMD -MF $@.d ${defines} ${includes} ${cflags} ${cflags_cc} -c $< -o $@
|
||||
c++ -MMD -MF $@.d ${defines} ${includes} ${cflags} ${cflags_cc} ${arch_cflags} -c $< -o $@
|
||||
|
||||
${target}: ${objs}
|
||||
# link with skia
|
||||
mkdir -p $(dir $@)
|
||||
c++ -shared -rdynamic -s -o $@ \
|
||||
${defines} ${includes} ${cflags} ${cflags_cc} \
|
||||
${defines} ${includes} ${cflags} ${cflags_cc} ${arch_cflags} \
|
||||
-Wl,--start-group ${objarch_root}/*.o ${library_paths} -Wl,--end-group \
|
||||
${ldflags} -Wl,--gc-sections -Wl,--no-undefined \
|
||||
-Wl,-soname,libSkiaSharp.so.${soname_version}
|
||||
|
|
|
@ -152,6 +152,7 @@ namespace SkiaSharp.Views.UWP
|
|||
|
||||
private void FreeBitmap(bool freeArray)
|
||||
{
|
||||
Background = null;
|
||||
if (bitmap != null)
|
||||
{
|
||||
bitmap = null;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
|
@ -74,6 +73,10 @@
|
|||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="nunit.framework, Version=3.6.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||
<HintPath>packages\NUnit.3.6.0\lib\net45\nunit.framework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
|
@ -83,51 +86,73 @@
|
|||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="xunit.abstractions">
|
||||
<HintPath>packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="xunit.assert">
|
||||
<HintPath>packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="xunit.core">
|
||||
<HintPath>packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="xunit.execution.desktop">
|
||||
<HintPath>packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Tests\SKCodecTest.cs">
|
||||
<Link>SKCodecTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Cgl\Cgl.cs">
|
||||
<Link>GlContexts\Cgl\Cgl.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKStringTest.cs">
|
||||
<Link>SKStringTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Cgl\CglContext.cs">
|
||||
<Link>GlContexts\Cgl\CglContext.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="..\Tests\SKManagedStreamTest.cs">
|
||||
<Link>SKManagedStreamTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Cgl\CGLError.cs">
|
||||
<Link>GlContexts\Cgl\CGLError.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKSurfaceTest.cs">
|
||||
<Link>SKSurfaceTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Cgl\CGLOpenGLProfile.cs">
|
||||
<Link>GlContexts\Cgl\CGLOpenGLProfile.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKTest.cs">
|
||||
<Link>SKTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Cgl\CGLPixelFormatAttribute.cs">
|
||||
<Link>GlContexts\Cgl\CGLPixelFormatAttribute.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKTypefaceTest.cs">
|
||||
<Link>SKTypefaceTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\GlContext.cs">
|
||||
<Link>GlContexts\GlContext.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKPaintTest.cs">
|
||||
<Link>SKPaintTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Glx\Glx.cs">
|
||||
<Link>GlContexts\Glx\Glx.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKPathTest.cs">
|
||||
<Link>SKPathTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Glx\GlxContext.cs">
|
||||
<Link>GlContexts\Glx\GlxContext.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKColorTest.cs">
|
||||
<Link>SKColorTest.cs</Link>
|
||||
<Compile Include="..\Tests\GlContexts\Glx\Xlib.cs">
|
||||
<Link>GlContexts\Glx\Xlib.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Glx\XVisualClass.cs">
|
||||
<Link>GlContexts\Glx\XVisualClass.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Glx\XVisualInfo.cs">
|
||||
<Link>GlContexts\Glx\XVisualInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\Gdi32.cs">
|
||||
<Link>GlContexts\Wgl\Gdi32.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\Kernel32.cs">
|
||||
<Link>GlContexts\Wgl\Kernel32.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\PIXELFORMATDESCRIPTOR.cs">
|
||||
<Link>GlContexts\Wgl\PIXELFORMATDESCRIPTOR.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\RECT.cs">
|
||||
<Link>GlContexts\Wgl\RECT.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\User32.cs">
|
||||
<Link>GlContexts\Wgl\User32.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\Wgl.cs">
|
||||
<Link>GlContexts\Wgl\Wgl.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\WglContext.cs">
|
||||
<Link>GlContexts\Wgl\WglContext.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\WindowStyles.cs">
|
||||
<Link>GlContexts\Wgl\WindowStyles.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GlContexts\Wgl\WNDCLASS.cs">
|
||||
<Link>GlContexts\Wgl\WNDCLASS.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GRContextTest.cs">
|
||||
<Link>GRContextTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\GRGlInterfaceTest.cs">
|
||||
<Link>GRGlInterfaceTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKBasicTypesTest.cs">
|
||||
<Link>SKBasicTypesTest.cs</Link>
|
||||
|
@ -135,18 +160,46 @@
|
|||
<Compile Include="..\Tests\SKBitmapTest.cs">
|
||||
<Link>SKBitmapTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKDataTest.cs">
|
||||
<Link>SKDataTest.cs</Link>
|
||||
<Compile Include="..\Tests\SKCodecTest.cs">
|
||||
<Link>SKCodecTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKColorTableTest.cs">
|
||||
<Link>SKColorTableTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKColorTest.cs">
|
||||
<Link>SKColorTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKDataTest.cs">
|
||||
<Link>SKDataTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKManagedStreamTest.cs">
|
||||
<Link>SKManagedStreamTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKPaintTest.cs">
|
||||
<Link>SKPaintTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKPathTest.cs">
|
||||
<Link>SKPathTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKStringTest.cs">
|
||||
<Link>SKStringTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKSurfaceTest.cs">
|
||||
<Link>SKSurfaceTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKSvgTest.cs">
|
||||
<Link>SKSvgTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKGeometryTest.cs">
|
||||
<Link>SKGeometryTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKTest.cs">
|
||||
<Link>SKTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Tests\SKTypefaceTest.cs">
|
||||
<Link>SKTypefaceTest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="..\Content\fonts\content-font.ttf">
|
||||
|
@ -226,12 +279,6 @@
|
|||
</ItemGroup>
|
||||
<Import Project="..\..\binding\SkiaSharp.Desktop\bin\$(Configuration)\nuget\build\net45\SkiaSharp.Desktop.targets" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -15,6 +15,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharp.Svg", "..\..\sour
|
|||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SkiaSharp.Svg.Shared", "..\..\source\SkiaSharp.Svg\SkiaSharp.Svg.Shared\SkiaSharp.Svg.Shared.shproj", "{B201E760-DB91-485C-A99A-814BDED90BDB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SkiaSharp.Extended", "..\..\source\SkiaSharp.Extended\SkiaSharp.Extended\SkiaSharp.Extended.csproj", "{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}"
|
||||
EndProject
|
||||
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SkiaSharp.Extended.Shared", "..\..\source\SkiaSharp.Extended\SkiaSharp.Extended.Shared\SkiaSharp.Extended.Shared.shproj", "{E3290CE6-0ADA-486B-9BAB-8BCF07F9BE45}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
..\..\source\SkiaSharp.Svg\SkiaSharp.Svg.Shared\SkiaSharp.Svg.Shared.projitems*{04c4399a-6740-4733-b6b7-f968232a76c8}*SharedItemsImports = 4
|
||||
|
@ -79,6 +83,18 @@ Global
|
|||
{04C4399A-6740-4733-B6B7-F968232A76C8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{04C4399A-6740-4733-B6B7-F968232A76C8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{04C4399A-6740-4733-B6B7-F968232A76C8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|x64.Build.0 = Release|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{FEA1FEC9-950C-46C0-9EB0-A515E0AB8F19}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="xunit" version="2.1.0" targetFramework="net45" />
|
||||
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.assert" version="2.1.0" targetFramework="net45" />
|
||||
<package id="xunit.core" version="2.1.0" targetFramework="net45" />
|
||||
<package id="xunit.extensibility.core" version="2.1.0" targetFramework="net45" />
|
||||
<package id="xunit.extensibility.execution" version="2.1.0" targetFramework="net45" />
|
||||
<package id="xunit.runner.visualstudio" version="2.1.0" targetFramework="net45" />
|
||||
<package id="NUnit" version="3.6.0" targetFramework="net45" />
|
||||
<package id="NUnit3TestAdapter" version="3.7.0" targetFramework="net45" />
|
||||
</packages>
|
|
@ -7,7 +7,7 @@
|
|||
],
|
||||
"allowUnsafe": true,
|
||||
"compile": {
|
||||
"include": "../Tests/*.cs",
|
||||
"include": "../Tests/**/*.cs",
|
||||
"excludeFiles":[
|
||||
"../Tests/SKSurfaceTest.cs"
|
||||
]
|
||||
|
@ -20,14 +20,14 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"xunit": "2.2.0-beta5-build3474",
|
||||
"dotnet-test-xunit": "2.2.0-preview2-build1029",
|
||||
"NUnit": "3.6.0",
|
||||
"dotnet-test-nunit": "3.4.0-beta-3",
|
||||
|
||||
"SkiaSharp": "1.56.1",
|
||||
"SkiaSharp.Svg": "1.56.1",
|
||||
"SkiaSharp.Extended": "1.56.1-beta"
|
||||
},
|
||||
"testRunner": "xunit",
|
||||
"testRunner": "nunit",
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
"dependencies": {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.None)]
|
||||
public class GRContextTest : SKTest
|
||||
{
|
||||
[Test]
|
||||
public void CreateDefaultContextIsValid()
|
||||
{
|
||||
using (var ctx = CreateGlContext()) {
|
||||
ctx.MakeCurrent();
|
||||
|
||||
var grContext = GRContext.Create(GRBackend.OpenGL);
|
||||
|
||||
Assert.NotNull(grContext);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateSpecificContextIsValid()
|
||||
{
|
||||
using (var ctx = CreateGlContext()) {
|
||||
ctx.MakeCurrent();
|
||||
|
||||
var glInterface = GRGlInterface.CreateNativeGlInterface();
|
||||
|
||||
Assert.True(glInterface.Validate());
|
||||
|
||||
var grContext = GRContext.Create(GRBackend.OpenGL, glInterface);
|
||||
|
||||
Assert.NotNull(grContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
[Parallelizable(ParallelScope.None)]
|
||||
public class GRGlInterfaceTest : SKTest
|
||||
{
|
||||
[Test]
|
||||
public void CreateDefaultInterfaceIsValid()
|
||||
{
|
||||
using (var ctx = CreateGlContext()) {
|
||||
ctx.MakeCurrent();
|
||||
|
||||
var glInterface = GRGlInterface.CreateNativeGlInterface();
|
||||
|
||||
Assert.NotNull(glInterface);
|
||||
Assert.True(glInterface.Validate());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AssembleInterfaceIsValid()
|
||||
{
|
||||
using (var ctx = CreateGlContext()) {
|
||||
ctx.MakeCurrent();
|
||||
|
||||
if (IsMac) {
|
||||
var lib = MacDynamicLibraries.dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", 1);
|
||||
|
||||
var glInterface = GRGlInterface.AssembleGlInterface((context, name) => {
|
||||
return MacDynamicLibraries.dlsym(lib, name);
|
||||
});
|
||||
|
||||
Assert.NotNull(glInterface);
|
||||
Assert.True(glInterface.Validate());
|
||||
|
||||
MacDynamicLibraries.dlclose(lib);
|
||||
} else if (IsWindows) {
|
||||
var lib = WindowsDynamicLibraries.LoadLibrary("opengl32.dll");
|
||||
|
||||
var glInterface = GRGlInterface.AssembleGlInterface((context, name) => {
|
||||
var ptr = WindowsDynamicLibraries.GetProcAddress(lib, name);
|
||||
if (ptr == IntPtr.Zero) {
|
||||
ptr = wglGetProcAddress(name);
|
||||
}
|
||||
return ptr;
|
||||
});
|
||||
|
||||
Assert.NotNull(glInterface);
|
||||
Assert.True(glInterface.Validate());
|
||||
|
||||
WindowsDynamicLibraries.FreeLibrary(lib);
|
||||
} else if (IsLinux) {
|
||||
var glInterface = GRGlInterface.AssembleGlInterface((context, name) => {
|
||||
return glXGetProcAddress(name);
|
||||
});
|
||||
|
||||
Assert.NotNull(glInterface);
|
||||
Assert.True(glInterface.Validate());
|
||||
} else {
|
||||
// more platforms !!!
|
||||
throw new Exception("Some strange platform that is not Windows, macOS nor Linux...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("opengl32.dll", CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern IntPtr wglGetProcAddress([MarshalAs(UnmanagedType.LPStr)] string lpszProc);
|
||||
|
||||
[DllImport("libGL.so.1")]
|
||||
public static extern IntPtr glXGetProcAddress([MarshalAs(UnmanagedType.LPStr)] string lpszProc);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal enum CGLError {
|
||||
kCGLNoError = 0,
|
||||
kCGLBadAttribute = 10000,
|
||||
kCGLBadProperty = 10001,
|
||||
kCGLBadPixelFormat = 10002,
|
||||
kCGLBadRendererInfo = 10003,
|
||||
kCGLBadContext = 10004,
|
||||
kCGLBadDrawable = 10005,
|
||||
kCGLBadDisplay = 10006,
|
||||
kCGLBadState = 10007,
|
||||
kCGLBadValue = 10008,
|
||||
kCGLBadMatch = 10009,
|
||||
kCGLBadEnumeration = 10010,
|
||||
kCGLBadOffScreen = 10011,
|
||||
kCGLBadFullScreen = 10012,
|
||||
kCGLBadWindow = 10013,
|
||||
kCGLBadAddress = 10014,
|
||||
kCGLBadCodeModule = 10015,
|
||||
kCGLBadAlloc = 10016,
|
||||
kCGLBadConnection = 10017,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal enum CGLOpenGLProfile {
|
||||
kCGLOGLPVersion_Legacy = 0x1000,
|
||||
kCGLOGLPVersion_3_2_Core = 0x3200,
|
||||
kCGLOGLPVersion_GL3_Core = 0x3200,
|
||||
kCGLOGLPVersion_GL4_Core = 0x4100,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal enum CGLPixelFormatAttribute {
|
||||
kCGLPFANone = 0,
|
||||
kCGLPFAAllRenderers = 1,
|
||||
kCGLPFATripleBuffer = 3,
|
||||
kCGLPFADoubleBuffer = 5,
|
||||
kCGLPFAColorSize = 8,
|
||||
kCGLPFAAlphaSize = 11,
|
||||
kCGLPFADepthSize = 12,
|
||||
kCGLPFAStencilSize = 13,
|
||||
kCGLPFAMinimumPolicy = 51,
|
||||
kCGLPFAMaximumPolicy = 52,
|
||||
kCGLPFASampleBuffers = 55,
|
||||
kCGLPFASamples = 56,
|
||||
kCGLPFAColorFloat = 58,
|
||||
kCGLPFAMultisample = 59,
|
||||
kCGLPFASupersample = 60,
|
||||
kCGLPFASampleAlpha = 61,
|
||||
kCGLPFARendererID = 70,
|
||||
kCGLPFANoRecovery = 72,
|
||||
kCGLPFAAccelerated = 73,
|
||||
kCGLPFAClosestPolicy = 74,
|
||||
kCGLPFABackingStore = 76,
|
||||
kCGLPFABackingVolatile = 77,
|
||||
kCGLPFADisplayMask = 84,
|
||||
kCGLPFAAllowOfflineRenderers = 96,
|
||||
kCGLPFAAcceleratedCompute = 97,
|
||||
kCGLPFAOpenGLProfile = 99,
|
||||
kCGLPFASupportsAutomaticGraphicsSwitching = 101,
|
||||
kCGLPFAVirtualScreenCount = 128,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class Cgl
|
||||
{
|
||||
private const string libGL = "/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL";
|
||||
|
||||
[DllImport(libGL)]
|
||||
public extern static void CGLGetVersion(out int majorvers, out int minorvers);
|
||||
[DllImport(libGL)]
|
||||
public extern static CGLError CGLChoosePixelFormat([In] CGLPixelFormatAttribute[] attribs, out IntPtr pix, out int npix);
|
||||
[DllImport(libGL)]
|
||||
public extern static CGLError CGLCreateContext(IntPtr pix, IntPtr share, out IntPtr ctx);
|
||||
[DllImport(libGL)]
|
||||
public extern static CGLError CGLReleasePixelFormat(IntPtr pix);
|
||||
[DllImport(libGL)]
|
||||
public extern static CGLError CGLSetCurrentContext(IntPtr ctx);
|
||||
[DllImport(libGL)]
|
||||
public extern static void CGLReleaseContext(IntPtr ctx);
|
||||
[DllImport(libGL)]
|
||||
public extern static CGLError CGLFlushDrawable(IntPtr ctx);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class CglContext : GlContext
|
||||
{
|
||||
private IntPtr fContext;
|
||||
|
||||
public CglContext()
|
||||
{
|
||||
var attributes = new [] {
|
||||
CGLPixelFormatAttribute.kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)CGLOpenGLProfile.kCGLOGLPVersion_3_2_Core,
|
||||
CGLPixelFormatAttribute.kCGLPFADoubleBuffer,
|
||||
CGLPixelFormatAttribute.kCGLPFANone
|
||||
};
|
||||
|
||||
IntPtr pixFormat;
|
||||
int npix;
|
||||
|
||||
Cgl.CGLChoosePixelFormat(attributes, out pixFormat, out npix);
|
||||
|
||||
if (pixFormat == IntPtr.Zero) {
|
||||
throw new Exception("CGLChoosePixelFormat failed.");
|
||||
}
|
||||
|
||||
Cgl.CGLCreateContext(pixFormat, IntPtr.Zero, out fContext);
|
||||
Cgl.CGLReleasePixelFormat(pixFormat);
|
||||
|
||||
if (fContext == IntPtr.Zero) {
|
||||
throw new Exception("CGLCreateContext failed.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void MakeCurrent()
|
||||
{
|
||||
Cgl.CGLSetCurrentContext(fContext);
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
Cgl.CGLFlushDrawable(fContext);
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
if (fContext != IntPtr.Zero) {
|
||||
Cgl.CGLReleaseContext(fContext);
|
||||
fContext = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public abstract class GlContext : IDisposable
|
||||
{
|
||||
public abstract void MakeCurrent();
|
||||
public abstract void SwapBuffers();
|
||||
public abstract void Destroy();
|
||||
|
||||
void IDisposable.Dispose() => Destroy();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class Glx
|
||||
{
|
||||
private const string libGL = "libGL";
|
||||
|
||||
public const int GLX_USE_GL = 1;
|
||||
public const int GLX_BUFFER_SIZE = 2;
|
||||
public const int GLX_LEVEL = 3;
|
||||
public const int GLX_RGBA = 4;
|
||||
public const int GLX_DOUBLEBUFFER = 5;
|
||||
public const int GLX_STEREO = 6;
|
||||
public const int GLX_AUX_BUFFERS = 7;
|
||||
public const int GLX_RED_SIZE = 8;
|
||||
public const int GLX_GREEN_SIZE = 9;
|
||||
public const int GLX_BLUE_SIZE = 10;
|
||||
public const int GLX_ALPHA_SIZE = 11;
|
||||
public const int GLX_DEPTH_SIZE = 12;
|
||||
public const int GLX_STENCIL_SIZE = 13;
|
||||
public const int GLX_ACCUM_RED_SIZE = 14;
|
||||
public const int GLX_ACCUM_GREEN_SIZE = 15;
|
||||
public const int GLX_ACCUM_BLUE_SIZE = 16;
|
||||
public const int GLX_ACCUM_ALPHA_SIZE = 17;
|
||||
|
||||
public const int GLX_DRAWABLE_TYPE = 0x8010;
|
||||
public const int GLX_RENDER_TYPE = 0x8011;
|
||||
public const int GLX_X_RENDERABLE = 0x8012;
|
||||
public const int GLX_RGBA_TYPE = 0x8014;
|
||||
public const int GLX_COLOR_INDEX_TYPE = 0x8015;
|
||||
|
||||
public const int GLX_PIXMAP_BIT = 0x00000002;
|
||||
|
||||
public const int GLX_RGBA_BIT = 0x00000001;
|
||||
|
||||
public const int GLX_SAMPLE_BUFFERS = 0x186a0;
|
||||
public const int GLX_SAMPLES = 0x186a1;
|
||||
|
||||
public const int GLX_CONTEXT_DEBUG_BIT_ARB = 0x00000001;
|
||||
public const int GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x00000002;
|
||||
public const int GLX_CONTEXT_MAJOR_VERSION_ARB = 0x2091;
|
||||
public const int GLX_CONTEXT_MINOR_VERSION_ARB = 0x2092;
|
||||
public const int GLX_CONTEXT_FLAGS_ARB = 0x2094;
|
||||
|
||||
public const int GLX_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001;
|
||||
public const int GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002;
|
||||
public const int GLX_CONTEXT_PROFILE_MASK_ARB = 0x9126;
|
||||
|
||||
static Glx()
|
||||
{
|
||||
var ptr = glXGetProcAddressARB("glXCreateContextAttribsARB");
|
||||
if (ptr != IntPtr.Zero) {
|
||||
glXCreateContextAttribsARB = (glXCreateContextAttribsARBDelegate)Marshal.GetDelegateForFunctionPointer(ptr, typeof(glXCreateContextAttribsARBDelegate));
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(libGL)]
|
||||
public extern static bool glXQueryVersion(IntPtr dpy, out int maj, out int min);
|
||||
[DllImport(libGL)]
|
||||
public extern static IntPtr glXChooseFBConfig(IntPtr dpy, int screen, [In] int[] attribList, out int nitems);
|
||||
public static IntPtr[] ChooseFBConfig(IntPtr dpy, int screen, int[] attribList)
|
||||
{
|
||||
int nitems;
|
||||
var fbcArrayPtr = glXChooseFBConfig(dpy, screen, attribList, out nitems);
|
||||
|
||||
var fbcArray = new IntPtr[nitems];
|
||||
Marshal.Copy(fbcArrayPtr, fbcArray, 0, nitems);
|
||||
|
||||
Xlib.XFree(fbcArrayPtr);
|
||||
|
||||
return fbcArray;
|
||||
}
|
||||
[DllImport(libGL)]
|
||||
public extern static IntPtr glXGetVisualFromFBConfig(IntPtr dpy, IntPtr config);
|
||||
public static XVisualInfo GetVisualFromFBConfig(IntPtr dpy, IntPtr config)
|
||||
{
|
||||
var visualPtr = glXGetVisualFromFBConfig(dpy, config);
|
||||
if (visualPtr == IntPtr.Zero) {
|
||||
throw new Exception("Failed to retrieve visual from framebuffer config.");
|
||||
}
|
||||
|
||||
var visual = (XVisualInfo) Marshal.PtrToStructure(visualPtr, typeof(XVisualInfo));
|
||||
|
||||
Xlib.XFree(visualPtr);
|
||||
|
||||
return visual;
|
||||
}
|
||||
[DllImport(libGL)]
|
||||
public extern static bool glXMakeCurrent(IntPtr dpy, IntPtr drawable, IntPtr ctx);
|
||||
[DllImport(libGL)]
|
||||
public extern static bool glXSwapBuffers(IntPtr dpy, IntPtr drawable);
|
||||
[DllImport(libGL)]
|
||||
public extern static bool glXIsDirect(IntPtr dpy, IntPtr ctx);
|
||||
[DllImport(libGL)]
|
||||
public extern static int glXGetFBConfigAttrib(IntPtr dpy, IntPtr config, int attribute, out int value);
|
||||
[DllImport(libGL)]
|
||||
public extern static IntPtr glXCreateGLXPixmap(IntPtr dpy, ref XVisualInfo visual, IntPtr pixmap);
|
||||
[DllImport(libGL)]
|
||||
public extern static void glXDestroyGLXPixmap(IntPtr dpy, IntPtr pixmap);
|
||||
[DllImport(libGL)]
|
||||
public extern static void glXDestroyContext(IntPtr dpy, IntPtr ctx);
|
||||
[DllImport(libGL)]
|
||||
public extern static IntPtr glXQueryExtensionsString(IntPtr dpy, int screen);
|
||||
public static string QueryExtensionsString(IntPtr dpy, int screen)
|
||||
{
|
||||
return Marshal.PtrToStringAnsi(glXQueryExtensionsString(dpy, screen));
|
||||
}
|
||||
public static string[] QueryExtensions(IntPtr dpy, int screen)
|
||||
{
|
||||
var str = QueryExtensionsString(dpy, screen);
|
||||
if (string.IsNullOrEmpty(str)) {
|
||||
return new string[0];
|
||||
}
|
||||
return str.Split(' ');
|
||||
}
|
||||
[DllImport(libGL)]
|
||||
public extern static IntPtr glXGetProcAddressARB(string procname);
|
||||
[DllImport(libGL)]
|
||||
public extern static IntPtr glXCreateNewContext(IntPtr dpy, IntPtr config, int renderType, IntPtr shareList, int direct);
|
||||
public static readonly glXCreateContextAttribsARBDelegate glXCreateContextAttribsARB;
|
||||
public delegate IntPtr glXCreateContextAttribsARBDelegate(IntPtr dpy, IntPtr config, IntPtr share_context, int direct, int[] attrib_list);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class GlxContext : GlContext
|
||||
{
|
||||
private IntPtr fDisplay;
|
||||
private IntPtr fPixmap;
|
||||
private IntPtr fGlxPixmap;
|
||||
private IntPtr fContext;
|
||||
|
||||
public GlxContext()
|
||||
{
|
||||
fDisplay = Xlib.XOpenDisplay(null);
|
||||
if (fDisplay == IntPtr.Zero) {
|
||||
Destroy();
|
||||
throw new Exception("Failed to open X display.");
|
||||
}
|
||||
|
||||
var visualAttribs = new [] {
|
||||
Glx.GLX_X_RENDERABLE, Xlib.True,
|
||||
Glx.GLX_DRAWABLE_TYPE, Glx.GLX_PIXMAP_BIT,
|
||||
Glx.GLX_RENDER_TYPE, Glx.GLX_RGBA_BIT,
|
||||
// Glx.GLX_DOUBLEBUFFER, Xlib.True,
|
||||
Glx.GLX_RED_SIZE, 8,
|
||||
Glx.GLX_GREEN_SIZE, 8,
|
||||
Glx.GLX_BLUE_SIZE, 8,
|
||||
Glx.GLX_ALPHA_SIZE, 8,
|
||||
Glx.GLX_DEPTH_SIZE, 24,
|
||||
Glx.GLX_STENCIL_SIZE, 8,
|
||||
// Glx.GLX_SAMPLE_BUFFERS, 1,
|
||||
// Glx.GLX_SAMPLES, 4,
|
||||
Xlib.None
|
||||
};
|
||||
|
||||
int glxMajor, glxMinor;
|
||||
|
||||
if (!Glx.glXQueryVersion(fDisplay, out glxMajor, out glxMinor) ||
|
||||
(glxMajor < 1) ||
|
||||
(glxMajor == 1 && glxMinor < 3)) {
|
||||
Destroy();
|
||||
throw new Exception("GLX version 1.3 or higher required.");
|
||||
}
|
||||
|
||||
var fbc = Glx.ChooseFBConfig(fDisplay, Xlib.XDefaultScreen(fDisplay), visualAttribs);
|
||||
if (fbc.Length == 0) {
|
||||
Destroy();
|
||||
throw new Exception("Failed to retrieve a framebuffer config.");
|
||||
}
|
||||
|
||||
var bestFBC = IntPtr.Zero;
|
||||
var bestNumSamp = -1;
|
||||
for (int i = 0; i < fbc.Length; i++) {
|
||||
|
||||
int sampleBuf, samples;
|
||||
Glx.glXGetFBConfigAttrib(fDisplay, fbc[i], Glx.GLX_SAMPLE_BUFFERS, out sampleBuf);
|
||||
Glx.glXGetFBConfigAttrib(fDisplay, fbc[i], Glx.GLX_SAMPLES, out samples);
|
||||
|
||||
if (bestFBC == IntPtr.Zero || (sampleBuf > 0 && samples > bestNumSamp)) {
|
||||
bestFBC = fbc[i];
|
||||
bestNumSamp = samples;
|
||||
}
|
||||
}
|
||||
var vi = Glx.GetVisualFromFBConfig(fDisplay, bestFBC);
|
||||
|
||||
fPixmap = Xlib.XCreatePixmap(fDisplay, Xlib.XRootWindow(fDisplay, vi.screen), 10, 10, (uint)vi.depth);
|
||||
if (fPixmap == IntPtr.Zero) {
|
||||
Destroy();
|
||||
throw new Exception("Failed to create pixmap.");
|
||||
}
|
||||
|
||||
fGlxPixmap = Glx.glXCreateGLXPixmap(fDisplay, ref vi, fPixmap);
|
||||
|
||||
var glxExts = Glx.QueryExtensions(fDisplay, Xlib.XDefaultScreen(fDisplay));
|
||||
if (Array.IndexOf(glxExts, "GLX_ARB_create_context") == -1 ||
|
||||
Glx.glXCreateContextAttribsARB == null) {
|
||||
Console.WriteLine("OpenGL 3.0 doesn't seem to be available.");
|
||||
fContext = Glx.glXCreateNewContext(fDisplay, bestFBC, Glx.GLX_RGBA_TYPE, IntPtr.Zero, Xlib.True);
|
||||
} else {
|
||||
// Let's just use OpenGL 3.0, but we could try find the highest
|
||||
int major = 3, minor = 0;
|
||||
var flags = new List<int> {
|
||||
Glx.GLX_CONTEXT_MAJOR_VERSION_ARB, major,
|
||||
Glx.GLX_CONTEXT_MINOR_VERSION_ARB, minor,
|
||||
};
|
||||
if (major > 2) {
|
||||
flags.AddRange(new[] {
|
||||
Glx.GLX_CONTEXT_PROFILE_MASK_ARB, Glx.GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||
});
|
||||
}
|
||||
flags.Add(Xlib.None);
|
||||
|
||||
fContext = Glx.glXCreateContextAttribsARB(fDisplay, bestFBC, IntPtr.Zero, Xlib.True, flags.ToArray());
|
||||
}
|
||||
if (fContext == IntPtr.Zero) {
|
||||
Destroy();
|
||||
throw new Exception("Failed to create an OpenGL context.");
|
||||
}
|
||||
|
||||
if (!Glx.glXIsDirect(fDisplay, fContext)) {
|
||||
Console.WriteLine("Obtained indirect GLX rendering context.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void MakeCurrent()
|
||||
{
|
||||
if (!Glx.glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
|
||||
Destroy();
|
||||
throw new Exception("Failed to set the context.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
Glx.glXSwapBuffers(fDisplay, fGlxPixmap);
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
if (fDisplay != IntPtr.Zero) {
|
||||
Glx.glXMakeCurrent(fDisplay, IntPtr.Zero, IntPtr.Zero);
|
||||
|
||||
if (fContext != IntPtr.Zero) {
|
||||
Glx.glXDestroyContext(fDisplay, fContext);
|
||||
fContext = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (fGlxPixmap != IntPtr.Zero) {
|
||||
Glx.glXDestroyGLXPixmap(fDisplay, fGlxPixmap);
|
||||
fGlxPixmap = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (fPixmap != IntPtr.Zero) {
|
||||
Xlib.XFreePixmap(fDisplay, fPixmap);
|
||||
fPixmap = IntPtr.Zero;
|
||||
}
|
||||
|
||||
fDisplay = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal enum XVisualClass : int {
|
||||
StaticGray = 0,
|
||||
GrayScale = 1,
|
||||
StaticColor = 2,
|
||||
PseudoColor = 3,
|
||||
TrueColor = 4,
|
||||
DirectColor = 5
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct XVisualInfo
|
||||
{
|
||||
public IntPtr visual;
|
||||
public IntPtr visualid;
|
||||
public int screen;
|
||||
public int depth;
|
||||
public XVisualClass c_class;
|
||||
public ulong red_mask;
|
||||
public ulong green_mask;
|
||||
public ulong blue_mask;
|
||||
public int colormap_size;
|
||||
public int bits_per_rgb;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class Xlib
|
||||
{
|
||||
private const string libX11 = "libX11";
|
||||
|
||||
public const int None = 0;
|
||||
public const int True = 1;
|
||||
public const int False = 0;
|
||||
|
||||
[DllImport(libX11)]
|
||||
public extern static IntPtr XOpenDisplay(string display_name);
|
||||
[DllImport(libX11)]
|
||||
public extern static int XFree(IntPtr data);
|
||||
[DllImport(libX11)]
|
||||
public extern static int XDefaultScreen(IntPtr display);
|
||||
[DllImport(libX11)]
|
||||
public extern static IntPtr XRootWindow(IntPtr display, int screen);
|
||||
[DllImport(libX11)]
|
||||
public extern static IntPtr XCreatePixmap(IntPtr display, IntPtr d, uint width, uint height, uint depth);
|
||||
[DllImport(libX11)]
|
||||
public extern static IntPtr XFreePixmap(IntPtr display, IntPtr pixmap);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class Gdi32
|
||||
{
|
||||
private const string gdi32 = "gdi32.dll";
|
||||
|
||||
public const byte PFD_TYPE_RGBA = 0;
|
||||
|
||||
public const byte PFD_MAIN_PLANE = 0;
|
||||
|
||||
public const uint PFD_DRAW_TO_WINDOW = 0x00000004;
|
||||
public const uint PFD_SUPPORT_OPENGL = 0x00000020;
|
||||
|
||||
[DllImport(gdi32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool SetPixelFormat(IntPtr hdc, int iPixelFormat, [In] ref PIXELFORMATDESCRIPTOR ppfd);
|
||||
|
||||
[DllImport(gdi32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
public static extern int ChoosePixelFormat(IntPtr hdc, [In] ref PIXELFORMATDESCRIPTOR ppfd);
|
||||
|
||||
[DllImport(gdi32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool SwapBuffers(IntPtr hdc);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class Kernel32
|
||||
{
|
||||
private const string kernel32 = "kernel32.dll";
|
||||
|
||||
static Kernel32()
|
||||
{
|
||||
CurrentModuleHandle = Kernel32.GetModuleHandle(null);
|
||||
if (CurrentModuleHandle == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception("Could not get module handle.");
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr CurrentModuleHandle { get; }
|
||||
|
||||
[DllImport(kernel32, CallingConvention = CallingConvention.Winapi, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||||
public static extern IntPtr GetModuleHandle([MarshalAs(UnmanagedType.LPTStr)] string lpModuleName);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct PIXELFORMATDESCRIPTOR
|
||||
{
|
||||
public ushort nSize;
|
||||
public ushort nVersion;
|
||||
public uint dwFlags;
|
||||
public byte iPixelType;
|
||||
public byte cColorBits;
|
||||
public byte cRedBits;
|
||||
public byte cRedShift;
|
||||
public byte cGreenBits;
|
||||
public byte cGreenShift;
|
||||
public byte cBlueBits;
|
||||
public byte cBlueShift;
|
||||
public byte cAlphaBits;
|
||||
public byte cAlphaShift;
|
||||
public byte cAccumBits;
|
||||
public byte cAccumRedBits;
|
||||
public byte cAccumGreenBits;
|
||||
public byte cAccumBlueBits;
|
||||
public byte cAccumAlphaBits;
|
||||
public byte cDepthBits;
|
||||
public byte cStencilBits;
|
||||
public byte cAuxBuffers;
|
||||
public byte iLayerType;
|
||||
public byte bReserved;
|
||||
public int dwLayerMask;
|
||||
public int dwVisibleMask;
|
||||
public int dwDamageMask;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct RECT
|
||||
{
|
||||
public int left;
|
||||
public int top;
|
||||
public int right;
|
||||
public int bottom;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class User32
|
||||
{
|
||||
private const string user32 = "user32.dll";
|
||||
|
||||
public const uint IDC_ARROW = 32512;
|
||||
|
||||
public const uint IDI_APPLICATION = 32512;
|
||||
public const uint IDI_WINLOGO = 32517;
|
||||
|
||||
public const int SW_HIDE = 0;
|
||||
|
||||
public const uint CS_VREDRAW = 0x1;
|
||||
public const uint CS_HREDRAW = 0x2;
|
||||
public const uint CS_OWNDC = 0x20;
|
||||
|
||||
public const uint WS_EX_CLIENTEDGE = 0x00000200;
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||||
public static extern ushort RegisterClass(ref WNDCLASS lpWndClass);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||||
public static extern ushort UnregisterClass([MarshalAs(UnmanagedType.LPTStr)] string lpClassName, IntPtr hInstance);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
public static extern IntPtr LoadCursor(IntPtr hInstance, int lpCursorName);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
public static extern IntPtr LoadIcon(IntPtr hInstance, IntPtr lpIconName);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
|
||||
public static extern IntPtr CreateWindowEx(uint dwExStyle, [MarshalAs(UnmanagedType.LPTStr)] string lpClassName, [MarshalAs(UnmanagedType.LPTStr)] string lpWindowName, WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
|
||||
|
||||
public static IntPtr CreateWindow(string lpClassName, string lpWindowName, WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam)
|
||||
{
|
||||
return CreateWindowEx(0, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
|
||||
}
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
public static extern IntPtr GetDC(IntPtr hWnd);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool DestroyWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool AdjustWindowRectEx(ref RECT lpRect, WindowStyles dwStyle, bool bMenu, uint dwExStyle);
|
||||
|
||||
[DllImport(user32, CallingConvention = CallingConvention.Winapi, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal delegate IntPtr WNDPROC(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct WNDCLASS
|
||||
{
|
||||
public uint style;
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
public WNDPROC lpfnWndProc;
|
||||
public int cbClsExtra;
|
||||
public int cbWndExtra;
|
||||
public IntPtr hInstance;
|
||||
public IntPtr hIcon;
|
||||
public IntPtr hCursor;
|
||||
public IntPtr hbrBackground;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string lpszMenuName;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public string lpszClassName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,249 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class Wgl
|
||||
{
|
||||
private const string opengl32 = "opengl32.dll";
|
||||
|
||||
public const int NONE = 0;
|
||||
public const int FALSE = 0;
|
||||
public const int TRUE = 1;
|
||||
|
||||
public const int WGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000;
|
||||
public const int WGL_DRAW_TO_WINDOW_ARB = 0x2001;
|
||||
public const int WGL_DRAW_TO_BITMAP_ARB = 0x2002;
|
||||
public const int WGL_ACCELERATION_ARB = 0x2003;
|
||||
public const int WGL_NEED_PALETTE_ARB = 0x2004;
|
||||
public const int WGL_NEED_SYSTEM_PALETTE_ARB = 0x2005;
|
||||
public const int WGL_SWAP_LAYER_BUFFERS_ARB = 0x2006;
|
||||
public const int WGL_SWAP_METHOD_ARB = 0x2007;
|
||||
public const int WGL_NUMBER_OVERLAYS_ARB = 0x2008;
|
||||
public const int WGL_NUMBER_UNDERLAYS_ARB = 0x2009;
|
||||
public const int WGL_TRANSPARENT_ARB = 0x200A;
|
||||
public const int WGL_TRANSPARENT_RED_VALUE_ARB = 0x2037;
|
||||
public const int WGL_TRANSPARENT_GREEN_VALUE_ARB = 0x2038;
|
||||
public const int WGL_TRANSPARENT_BLUE_VALUE_ARB = 0x2039;
|
||||
public const int WGL_TRANSPARENT_ALPHA_VALUE_ARB = 0x203A;
|
||||
public const int WGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B;
|
||||
public const int WGL_SHARE_DEPTH_ARB = 0x200C;
|
||||
public const int WGL_SHARE_STENCIL_ARB = 0x200D;
|
||||
public const int WGL_SHARE_ACCUM_ARB = 0x200E;
|
||||
public const int WGL_SUPPORT_GDI_ARB = 0x200F;
|
||||
public const int WGL_SUPPORT_OPENGL_ARB = 0x2010;
|
||||
public const int WGL_DOUBLE_BUFFER_ARB = 0x2011;
|
||||
public const int WGL_STEREO_ARB = 0x2012;
|
||||
public const int WGL_PIXEL_TYPE_ARB = 0x2013;
|
||||
public const int WGL_COLOR_BITS_ARB = 0x2014;
|
||||
public const int WGL_RED_BITS_ARB = 0x2015;
|
||||
public const int WGL_RED_SHIFT_ARB = 0x2016;
|
||||
public const int WGL_GREEN_BITS_ARB = 0x2017;
|
||||
public const int WGL_GREEN_SHIFT_ARB = 0x2018;
|
||||
public const int WGL_BLUE_BITS_ARB = 0x2019;
|
||||
public const int WGL_BLUE_SHIFT_ARB = 0x201A;
|
||||
public const int WGL_ALPHA_BITS_ARB = 0x201B;
|
||||
public const int WGL_ALPHA_SHIFT_ARB = 0x201C;
|
||||
public const int WGL_ACCUM_BITS_ARB = 0x201D;
|
||||
public const int WGL_ACCUM_RED_BITS_ARB = 0x201E;
|
||||
public const int WGL_ACCUM_GREEN_BITS_ARB = 0x201F;
|
||||
public const int WGL_ACCUM_BLUE_BITS_ARB = 0x2020;
|
||||
public const int WGL_ACCUM_ALPHA_BITS_ARB = 0x2021;
|
||||
public const int WGL_DEPTH_BITS_ARB = 0x2022;
|
||||
public const int WGL_STENCIL_BITS_ARB = 0x2023;
|
||||
public const int WGL_AUX_BUFFERS_ARB = 0x2024;
|
||||
public const int WGL_NO_ACCELERATION_ARB = 0x2025;
|
||||
public const int WGL_GENERIC_ACCELERATION_ARB = 0x2026;
|
||||
public const int WGL_FULL_ACCELERATION_ARB = 0x2027;
|
||||
public const int WGL_SWAP_EXCHANGE_ARB = 0x2028;
|
||||
public const int WGL_SWAP_COPY_ARB = 0x2029;
|
||||
public const int WGL_SWAP_UNDEFINED_ARB = 0x202A;
|
||||
public const int WGL_TYPE_RGBA_ARB = 0x202B;
|
||||
public const int WGL_TYPE_COLORINDEX_ARB = 0x202C;
|
||||
|
||||
static Wgl()
|
||||
{
|
||||
// save the current GL context
|
||||
var prevDC = Wgl.wglGetCurrentDC();
|
||||
var prevGLRC = Wgl.wglGetCurrentContext();
|
||||
|
||||
// register the dummy window class
|
||||
var wc = new WNDCLASS
|
||||
{
|
||||
style = (User32.CS_HREDRAW | User32.CS_VREDRAW | User32.CS_OWNDC),
|
||||
lpfnWndProc = (WNDPROC)User32.DefWindowProc,
|
||||
cbClsExtra = 0,
|
||||
cbWndExtra = 0,
|
||||
hInstance = Kernel32.CurrentModuleHandle,
|
||||
hCursor = User32.LoadCursor(IntPtr.Zero, (int)User32.IDC_ARROW),
|
||||
hIcon = User32.LoadIcon(IntPtr.Zero, (IntPtr)User32.IDI_WINLOGO),
|
||||
hbrBackground = IntPtr.Zero,
|
||||
lpszMenuName = null,
|
||||
lpszClassName = "DummyClass"
|
||||
};
|
||||
if (User32.RegisterClass(ref wc) == 0)
|
||||
{
|
||||
throw new Exception("Could not register dummy class.");
|
||||
}
|
||||
|
||||
// get the the dummy window bounds
|
||||
var windowRect = new RECT { left = 0, right = 8, top = 0, bottom = 8 };
|
||||
User32.AdjustWindowRectEx(ref windowRect, WindowStyles.WS_SYSMENU, false, User32.WS_EX_CLIENTEDGE);
|
||||
|
||||
// create the dummy window
|
||||
var dummyWND = User32.CreateWindowEx(
|
||||
User32.WS_EX_CLIENTEDGE,
|
||||
"DummyClass",
|
||||
"DummyWindow",
|
||||
WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_SYSMENU,
|
||||
0, 0,
|
||||
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top,
|
||||
IntPtr.Zero, IntPtr.Zero, Kernel32.CurrentModuleHandle, IntPtr.Zero);
|
||||
if (dummyWND == IntPtr.Zero)
|
||||
{
|
||||
User32.UnregisterClass("DummyClass", Kernel32.CurrentModuleHandle);
|
||||
throw new Exception("Could not create dummy window.");
|
||||
}
|
||||
|
||||
// get the dummy DC
|
||||
var dummyDC = User32.GetDC(dummyWND);
|
||||
|
||||
// get the dummy pixel format
|
||||
var dummyPFD = new PIXELFORMATDESCRIPTOR();
|
||||
dummyPFD.nSize = (ushort)Marshal.SizeOf(dummyPFD);
|
||||
dummyPFD.nVersion = 1;
|
||||
dummyPFD.dwFlags = Gdi32.PFD_DRAW_TO_WINDOW | Gdi32.PFD_SUPPORT_OPENGL;
|
||||
dummyPFD.iPixelType = Gdi32.PFD_TYPE_RGBA;
|
||||
dummyPFD.cColorBits = 32;
|
||||
dummyPFD.cDepthBits = 24;
|
||||
dummyPFD.cStencilBits = 8;
|
||||
dummyPFD.iLayerType = Gdi32.PFD_MAIN_PLANE;
|
||||
var dummyFormat = Gdi32.ChoosePixelFormat(dummyDC, ref dummyPFD);
|
||||
Gdi32.SetPixelFormat(dummyDC, dummyFormat, ref dummyPFD);
|
||||
|
||||
// get the dummy GL context
|
||||
var dummyGLRC = Wgl.wglCreateContext(dummyDC);
|
||||
if (dummyGLRC == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception("Could not create dummy GL context.");
|
||||
}
|
||||
Wgl.wglMakeCurrent(dummyDC, dummyGLRC);
|
||||
|
||||
// get the extension methods using the dummy context
|
||||
wglGetExtensionsStringARB = Wgl.wglGetProcAddress<wglGetExtensionsStringARBDelegate>("wglGetExtensionsStringARB");
|
||||
wglChoosePixelFormatARB = Wgl.wglGetProcAddress<wglChoosePixelFormatARBDelegate>("wglChoosePixelFormatARB");
|
||||
wglCreatePbufferARB = Wgl.wglGetProcAddress<wglCreatePbufferARBDelegate>("wglCreatePbufferARB");
|
||||
wglDestroyPbufferARB = Wgl.wglGetProcAddress<wglDestroyPbufferARBDelegate>("wglDestroyPbufferARB");
|
||||
wglGetPbufferDCARB = Wgl.wglGetProcAddress<wglGetPbufferDCARBDelegate>("wglGetPbufferDCARB");
|
||||
wglReleasePbufferDCARB = Wgl.wglGetProcAddress<wglReleasePbufferDCARBDelegate>("wglReleasePbufferDCARB");
|
||||
wglSwapIntervalEXT = Wgl.wglGetProcAddress<wglSwapIntervalEXTDelegate>("wglSwapIntervalEXT");
|
||||
// GET_PROC(ChoosePixelFormat, ARB);
|
||||
// GET_PROC(GetPixelFormatAttribiv, ARB);
|
||||
// GET_PROC(GetPixelFormatAttribfv, ARB);
|
||||
// GET_PROC(CreateContextAttribs, ARB);
|
||||
|
||||
// destroy the dummy GL context
|
||||
Wgl.wglMakeCurrent(dummyDC, IntPtr.Zero);
|
||||
Wgl.wglDeleteContext(dummyGLRC);
|
||||
|
||||
// destroy the dummy window
|
||||
User32.DestroyWindow(dummyWND);
|
||||
User32.UnregisterClass("DummyClass", Kernel32.CurrentModuleHandle);
|
||||
|
||||
// reset the initial GL context
|
||||
Wgl.wglMakeCurrent(prevDC, prevGLRC);
|
||||
}
|
||||
|
||||
public static bool HasExtension(IntPtr dc, string ext)
|
||||
{
|
||||
if (ext == "WGL_ARB_extensions_string")
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Array.IndexOf(GetExtensionsARB(dc), ext) != -1;
|
||||
}
|
||||
|
||||
public static string GetExtensionsStringARB(IntPtr dc)
|
||||
{
|
||||
return Marshal.PtrToStringAnsi(wglGetExtensionsStringARB(dc));
|
||||
}
|
||||
|
||||
public static string[] GetExtensionsARB(IntPtr dc)
|
||||
{
|
||||
var str = GetExtensionsStringARB(dc);
|
||||
if (string.IsNullOrEmpty(str))
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
return str.Split(' ');
|
||||
}
|
||||
|
||||
public static readonly wglGetExtensionsStringARBDelegate wglGetExtensionsStringARB;
|
||||
public static readonly wglChoosePixelFormatARBDelegate wglChoosePixelFormatARB;
|
||||
public static readonly wglCreatePbufferARBDelegate wglCreatePbufferARB;
|
||||
public static readonly wglDestroyPbufferARBDelegate wglDestroyPbufferARB;
|
||||
public static readonly wglGetPbufferDCARBDelegate wglGetPbufferDCARB;
|
||||
public static readonly wglReleasePbufferDCARBDelegate wglReleasePbufferDCARB;
|
||||
public static readonly wglSwapIntervalEXTDelegate wglSwapIntervalEXT;
|
||||
|
||||
[DllImport(opengl32, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern IntPtr wglGetCurrentDC();
|
||||
|
||||
[DllImport(opengl32, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern IntPtr wglGetCurrentContext();
|
||||
|
||||
[DllImport(opengl32, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern IntPtr wglCreateContext(IntPtr hDC);
|
||||
|
||||
[DllImport(opengl32, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern bool wglMakeCurrent(IntPtr hDC, IntPtr hRC);
|
||||
|
||||
[DllImport(opengl32, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern bool wglDeleteContext(IntPtr hRC);
|
||||
|
||||
[DllImport(opengl32, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern IntPtr wglGetProcAddress([MarshalAs(UnmanagedType.LPStr)] string lpszProc);
|
||||
|
||||
public static T wglGetProcAddress<T>(string lpszProc)
|
||||
{
|
||||
var ptr = wglGetProcAddress(lpszProc);
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception("Unable to load proc: " + lpszProc);
|
||||
}
|
||||
return (T)(object)Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
public delegate IntPtr wglGetExtensionsStringARBDelegate(IntPtr dc);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public delegate bool wglChoosePixelFormatARBDelegate(
|
||||
IntPtr dc,
|
||||
[In] int[] attribIList,
|
||||
[In] float[] attribFList,
|
||||
uint maxFormats,
|
||||
[Out] int[] pixelFormats,
|
||||
out uint numFormats);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
public delegate IntPtr wglCreatePbufferARBDelegate(IntPtr dc, int pixelFormat, int width, int height, [In] int[] attribList);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public delegate bool wglDestroyPbufferARBDelegate(IntPtr pbuffer);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
public delegate IntPtr wglGetPbufferDCARBDelegate(IntPtr pbuffer);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
public delegate int wglReleasePbufferDCARBDelegate(IntPtr pbuffer, IntPtr dc);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public delegate bool wglSwapIntervalEXTDelegate(int interval);
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
internal class WglContext : GlContext
|
||||
{
|
||||
private ushort gWC;
|
||||
|
||||
private IntPtr fWindow;
|
||||
private IntPtr fDeviceContext;
|
||||
|
||||
private IntPtr fPbuffer;
|
||||
private IntPtr fPbufferDC;
|
||||
private IntPtr fPbufferGlContext;
|
||||
|
||||
public WglContext()
|
||||
{
|
||||
var wc = new WNDCLASS
|
||||
{
|
||||
cbClsExtra = 0,
|
||||
cbWndExtra = 0,
|
||||
hbrBackground = IntPtr.Zero,
|
||||
hCursor = User32.LoadCursor(IntPtr.Zero, (int)User32.IDC_ARROW),
|
||||
hIcon = User32.LoadIcon(IntPtr.Zero, (IntPtr)User32.IDI_APPLICATION),
|
||||
hInstance = Kernel32.CurrentModuleHandle,
|
||||
lpfnWndProc = (WNDPROC)User32.DefWindowProc,
|
||||
lpszClassName = "Griffin",
|
||||
lpszMenuName = null,
|
||||
style = User32.CS_HREDRAW | User32.CS_VREDRAW | User32.CS_OWNDC
|
||||
};
|
||||
|
||||
gWC = User32.RegisterClass(ref wc);
|
||||
if (gWC == 0)
|
||||
{
|
||||
throw new Exception("Could not register window class.");
|
||||
}
|
||||
|
||||
fWindow = User32.CreateWindow(
|
||||
"Griffin",
|
||||
"The Invisible Man",
|
||||
WindowStyles.WS_OVERLAPPEDWINDOW,
|
||||
0, 0,
|
||||
1, 1,
|
||||
IntPtr.Zero, IntPtr.Zero, Kernel32.CurrentModuleHandle, IntPtr.Zero);
|
||||
if (fWindow == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception($"Could not create window.");
|
||||
}
|
||||
|
||||
fDeviceContext = User32.GetDC(fWindow);
|
||||
if (fDeviceContext == IntPtr.Zero)
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("Could not get device context.");
|
||||
}
|
||||
|
||||
if (!Wgl.HasExtension(fDeviceContext, "WGL_ARB_pixel_format") ||
|
||||
!Wgl.HasExtension(fDeviceContext, "WGL_ARB_pbuffer"))
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("DC does not have extensions.");
|
||||
}
|
||||
|
||||
var iAttrs = new int[]
|
||||
{
|
||||
Wgl.WGL_ACCELERATION_ARB, Wgl.WGL_FULL_ACCELERATION_ARB,
|
||||
Wgl.WGL_DRAW_TO_WINDOW_ARB, Wgl.TRUE,
|
||||
//Wgl.WGL_DOUBLE_BUFFER_ARB, (doubleBuffered ? TRUE : FALSE),
|
||||
Wgl.WGL_SUPPORT_OPENGL_ARB, Wgl.TRUE,
|
||||
Wgl.WGL_RED_BITS_ARB, 8,
|
||||
Wgl.WGL_GREEN_BITS_ARB, 8,
|
||||
Wgl.WGL_BLUE_BITS_ARB, 8,
|
||||
Wgl.WGL_ALPHA_BITS_ARB, 8,
|
||||
Wgl.WGL_STENCIL_BITS_ARB, 8,
|
||||
Wgl.NONE, Wgl.NONE
|
||||
};
|
||||
var piFormats = new int[1];
|
||||
uint nFormats;
|
||||
Wgl.wglChoosePixelFormatARB(fDeviceContext, iAttrs, null, (uint)piFormats.Length, piFormats, out nFormats);
|
||||
if (nFormats == 0)
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("Could not get pixel formats.");
|
||||
}
|
||||
|
||||
fPbuffer = Wgl.wglCreatePbufferARB(fDeviceContext, piFormats[0], 1, 1, null);
|
||||
if (fPbuffer == IntPtr.Zero)
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("Could not create Pbuffer.");
|
||||
}
|
||||
|
||||
fPbufferDC = Wgl.wglGetPbufferDCARB(fPbuffer);
|
||||
if (fPbufferDC == IntPtr.Zero)
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("Could not get Pbuffer DC.");
|
||||
}
|
||||
|
||||
var prevDC = Wgl.wglGetCurrentDC();
|
||||
var prevGLRC = Wgl.wglGetCurrentContext();
|
||||
|
||||
fPbufferGlContext = Wgl.wglCreateContext(fPbufferDC);
|
||||
|
||||
Wgl.wglMakeCurrent(prevDC, prevGLRC);
|
||||
|
||||
if (fPbufferGlContext == IntPtr.Zero)
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("Could not creeate Pbuffer GL context.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void MakeCurrent()
|
||||
{
|
||||
if (!Wgl.wglMakeCurrent(fPbufferDC, fPbufferGlContext))
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("Could not set the context.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
if (!Gdi32.SwapBuffers(fPbufferDC))
|
||||
{
|
||||
Destroy();
|
||||
throw new Exception("Could not complete SwapBuffers.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
{
|
||||
if (!Wgl.HasExtension(fPbufferDC, "WGL_ARB_pbuffer"))
|
||||
{
|
||||
// ASSERT
|
||||
}
|
||||
|
||||
Wgl.wglDeleteContext(fPbufferGlContext);
|
||||
|
||||
Wgl.wglReleasePbufferDCARB(fPbuffer, fPbufferDC);
|
||||
|
||||
Wgl.wglDestroyPbufferARB(fPbuffer);
|
||||
|
||||
if (fWindow != IntPtr.Zero)
|
||||
{
|
||||
if (fDeviceContext != IntPtr.Zero)
|
||||
{
|
||||
User32.ReleaseDC(fWindow, fDeviceContext);
|
||||
fDeviceContext = IntPtr.Zero;
|
||||
}
|
||||
|
||||
User32.DestroyWindow(fWindow);
|
||||
fWindow = IntPtr.Zero;
|
||||
}
|
||||
|
||||
User32.UnregisterClass("Griffin", Kernel32.CurrentModuleHandle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
[Flags]
|
||||
internal enum WindowStyles : uint
|
||||
{
|
||||
WS_BORDER = 0x800000,
|
||||
WS_CAPTION = 0xc00000,
|
||||
WS_CHILD = 0x40000000,
|
||||
WS_CLIPCHILDREN = 0x2000000,
|
||||
WS_CLIPSIBLINGS = 0x4000000,
|
||||
WS_DISABLED = 0x8000000,
|
||||
WS_DLGFRAME = 0x400000,
|
||||
WS_GROUP = 0x20000,
|
||||
WS_HSCROLL = 0x100000,
|
||||
WS_MAXIMIZE = 0x1000000,
|
||||
WS_MAXIMIZEBOX = 0x10000,
|
||||
WS_MINIMIZE = 0x20000000,
|
||||
WS_MINIMIZEBOX = 0x20000,
|
||||
WS_OVERLAPPED = 0x0,
|
||||
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
|
||||
WS_POPUP = 0x80000000u,
|
||||
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
|
||||
WS_SIZEFRAME = 0x40000,
|
||||
WS_SYSMENU = 0x80000,
|
||||
WS_TABSTOP = 0x10000,
|
||||
WS_VISIBLE = 0x10000000,
|
||||
WS_VSCROLL = 0x200000
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
|
@ -10,24 +10,24 @@ namespace SkiaSharp.Tests
|
|||
private const float EPSILON = 0.0001f;
|
||||
private const int PRECISION = 4;
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void RectanlgeHasCorrectProperties()
|
||||
{
|
||||
var rect = new SKRect(15, 25, 55, 75);
|
||||
|
||||
Assert.Equal(15f, rect.Left);
|
||||
Assert.Equal(25f, rect.Top);
|
||||
Assert.Equal(55f, rect.Right);
|
||||
Assert.Equal(75f, rect.Bottom);
|
||||
Assert.AreEqual(15f, rect.Left);
|
||||
Assert.AreEqual(25f, rect.Top);
|
||||
Assert.AreEqual(55f, rect.Right);
|
||||
Assert.AreEqual(75f, rect.Bottom);
|
||||
|
||||
Assert.Equal(40f, rect.Width);
|
||||
Assert.Equal(50f, rect.Height);
|
||||
Assert.AreEqual(40f, rect.Width);
|
||||
Assert.AreEqual(50f, rect.Height);
|
||||
|
||||
Assert.Equal(35f, rect.MidX);
|
||||
Assert.Equal(50f, rect.MidY);
|
||||
Assert.AreEqual(35f, rect.MidX);
|
||||
Assert.AreEqual(50f, rect.MidY);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void RectanlgeOffsetsCorrectly()
|
||||
{
|
||||
var expected = new SKRect(25, 30, 65, 80);
|
||||
|
@ -38,54 +38,54 @@ namespace SkiaSharp.Tests
|
|||
var rect2 = new SKRect(15, 25, 55, 75);
|
||||
rect2.Offset (10, 5);
|
||||
|
||||
Assert.Equal(expected, rect1);
|
||||
Assert.Equal(expected, rect2);
|
||||
Assert.AreEqual(expected, rect1);
|
||||
Assert.AreEqual(expected, rect2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void RectanlgeInflatesCorrectly()
|
||||
{
|
||||
var rect = new SKRect(15, 25, 55, 75);
|
||||
|
||||
Assert.Equal(15f, rect.Left);
|
||||
Assert.Equal(25f, rect.Top);
|
||||
Assert.Equal(55f, rect.Right);
|
||||
Assert.Equal(75f, rect.Bottom);
|
||||
Assert.AreEqual(15f, rect.Left);
|
||||
Assert.AreEqual(25f, rect.Top);
|
||||
Assert.AreEqual(55f, rect.Right);
|
||||
Assert.AreEqual(75f, rect.Bottom);
|
||||
|
||||
rect.Inflate(10, 20);
|
||||
|
||||
Assert.Equal(5f, rect.Left);
|
||||
Assert.Equal(5f, rect.Top);
|
||||
Assert.Equal(65f, rect.Right);
|
||||
Assert.Equal(95f, rect.Bottom);
|
||||
Assert.AreEqual(5f, rect.Left);
|
||||
Assert.AreEqual(5f, rect.Top);
|
||||
Assert.AreEqual(65f, rect.Right);
|
||||
Assert.AreEqual(95f, rect.Bottom);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void RectanlgeStandardizeCorrectly()
|
||||
{
|
||||
var rect = new SKRect(5, 5, 15, 15);
|
||||
Assert.Equal(10, rect.Width);
|
||||
Assert.Equal(10, rect.Height);
|
||||
Assert.AreEqual(10, rect.Width);
|
||||
Assert.AreEqual(10, rect.Height);
|
||||
|
||||
Assert.Equal(rect, rect.Standardized);
|
||||
Assert.AreEqual(rect, rect.Standardized);
|
||||
|
||||
var negW = new SKRect(15, 5, 5, 15);
|
||||
Assert.Equal(-10, negW.Width);
|
||||
Assert.Equal(10, negW.Height);
|
||||
Assert.Equal(rect, negW.Standardized);
|
||||
Assert.AreEqual(-10, negW.Width);
|
||||
Assert.AreEqual(10, negW.Height);
|
||||
Assert.AreEqual(rect, negW.Standardized);
|
||||
|
||||
var negH = new SKRect(5, 15, 15, 5);
|
||||
Assert.Equal(10, negH.Width);
|
||||
Assert.Equal(-10, negH.Height);
|
||||
Assert.Equal(rect, negH.Standardized);
|
||||
Assert.AreEqual(10, negH.Width);
|
||||
Assert.AreEqual(-10, negH.Height);
|
||||
Assert.AreEqual(rect, negH.Standardized);
|
||||
|
||||
var negWH = new SKRect(15, 15, 5, 5);
|
||||
Assert.Equal(-10, negWH.Width);
|
||||
Assert.Equal(-10, negWH.Height);
|
||||
Assert.Equal(rect, negWH.Standardized);
|
||||
Assert.AreEqual(-10, negWH.Width);
|
||||
Assert.AreEqual(-10, negWH.Height);
|
||||
Assert.AreEqual(rect, negWH.Standardized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void RectanlgeAspectFitIsCorrect()
|
||||
{
|
||||
var bigRect = SKRect.Create(5, 5, 20, 20);
|
||||
|
@ -93,19 +93,19 @@ namespace SkiaSharp.Tests
|
|||
var wideSize = new SKSize(10, 5);
|
||||
|
||||
var fitTall = bigRect.AspectFit(tallSize);
|
||||
Assert.Equal(5 + 5, fitTall.Left);
|
||||
Assert.Equal(5 + 0, fitTall.Top);
|
||||
Assert.Equal(10, fitTall.Width);
|
||||
Assert.Equal(20, fitTall.Height);
|
||||
Assert.AreEqual(5 + 5, fitTall.Left);
|
||||
Assert.AreEqual(5 + 0, fitTall.Top);
|
||||
Assert.AreEqual(10, fitTall.Width);
|
||||
Assert.AreEqual(20, fitTall.Height);
|
||||
|
||||
var fitWide = bigRect.AspectFit(wideSize);
|
||||
Assert.Equal(5 + 0, fitWide.Left);
|
||||
Assert.Equal(5 + 5, fitWide.Top);
|
||||
Assert.Equal(20, fitWide.Width);
|
||||
Assert.Equal(10, fitWide.Height);
|
||||
Assert.AreEqual(5 + 0, fitWide.Left);
|
||||
Assert.AreEqual(5 + 5, fitWide.Top);
|
||||
Assert.AreEqual(20, fitWide.Width);
|
||||
Assert.AreEqual(10, fitWide.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void RectanlgeAspectFillIsCorrect()
|
||||
{
|
||||
var bigRect = SKRect.Create(5, 5, 20, 20);
|
||||
|
@ -113,19 +113,19 @@ namespace SkiaSharp.Tests
|
|||
var wideSize = new SKSize(10, 5);
|
||||
|
||||
var fitTall = bigRect.AspectFill(tallSize);
|
||||
Assert.Equal(5 + 0, fitTall.Left);
|
||||
Assert.Equal(5 - 10, fitTall.Top);
|
||||
Assert.Equal(20, fitTall.Width);
|
||||
Assert.Equal(40, fitTall.Height);
|
||||
Assert.AreEqual(5 + 0, fitTall.Left);
|
||||
Assert.AreEqual(5 - 10, fitTall.Top);
|
||||
Assert.AreEqual(20, fitTall.Width);
|
||||
Assert.AreEqual(40, fitTall.Height);
|
||||
|
||||
var fitWide = bigRect.AspectFill(wideSize);
|
||||
Assert.Equal(5 - 10, fitWide.Left);
|
||||
Assert.Equal(5 + 0, fitWide.Top);
|
||||
Assert.Equal(40, fitWide.Width);
|
||||
Assert.Equal(20, fitWide.Height);
|
||||
Assert.AreEqual(5 - 10, fitWide.Left);
|
||||
Assert.AreEqual(5 + 0, fitWide.Top);
|
||||
Assert.AreEqual(40, fitWide.Width);
|
||||
Assert.AreEqual(20, fitWide.Height);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public unsafe void FixedImageMaskIsHandledCorrectly()
|
||||
{
|
||||
byte rawMask = 1 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1;
|
||||
|
@ -138,11 +138,11 @@ namespace SkiaSharp.Tests
|
|||
{
|
||||
var mask = SKMask.Create(buffer, bounds, rowBytes, format);
|
||||
|
||||
Assert.Equal(rawMask, mask.GetAddr1(0, 0));
|
||||
Assert.AreEqual(rawMask, mask.GetAddr1(0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void MonochromeMaskBufferIsCopied()
|
||||
{
|
||||
byte rawMask = 1 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 1 << 3 | 0 << 2 | 1 << 1 | 1;
|
||||
|
@ -153,12 +153,12 @@ namespace SkiaSharp.Tests
|
|||
|
||||
var mask = SKMask.Create(buffer, bounds, rowBytes, format);
|
||||
|
||||
Assert.Equal(rawMask, mask.GetAddr1(0, 0));
|
||||
Assert.AreEqual(rawMask, mask.GetAddr1(0, 0));
|
||||
|
||||
mask.FreeImage();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void Alpha8MaskBufferIsCopied()
|
||||
{
|
||||
var buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
|
@ -168,19 +168,19 @@ namespace SkiaSharp.Tests
|
|||
|
||||
var mask = SKMask.Create(buffer, bounds, rowBytes, format);
|
||||
|
||||
Assert.Equal(buffer[0], mask.GetAddr8(0, 0));
|
||||
Assert.Equal(buffer[1], mask.GetAddr8(1, 0));
|
||||
Assert.Equal(buffer[2], mask.GetAddr8(2, 0));
|
||||
Assert.Equal(buffer[3], mask.GetAddr8(3, 0));
|
||||
Assert.Equal(buffer[4], mask.GetAddr8(0, 1));
|
||||
Assert.Equal(buffer[5], mask.GetAddr8(1, 1));
|
||||
Assert.Equal(buffer[6], mask.GetAddr8(2, 1));
|
||||
Assert.Equal(buffer[7], mask.GetAddr8(3, 1));
|
||||
Assert.AreEqual(buffer[0], mask.GetAddr8(0, 0));
|
||||
Assert.AreEqual(buffer[1], mask.GetAddr8(1, 0));
|
||||
Assert.AreEqual(buffer[2], mask.GetAddr8(2, 0));
|
||||
Assert.AreEqual(buffer[3], mask.GetAddr8(3, 0));
|
||||
Assert.AreEqual(buffer[4], mask.GetAddr8(0, 1));
|
||||
Assert.AreEqual(buffer[5], mask.GetAddr8(1, 1));
|
||||
Assert.AreEqual(buffer[6], mask.GetAddr8(2, 1));
|
||||
Assert.AreEqual(buffer[7], mask.GetAddr8(3, 1));
|
||||
|
||||
mask.FreeImage();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ThirtyTwoBitMaskBufferIsCopied()
|
||||
{
|
||||
var buffer = new byte[]
|
||||
|
@ -202,19 +202,19 @@ namespace SkiaSharp.Tests
|
|||
|
||||
var red = SKColors.Red;
|
||||
var blue = SKColors.Blue;
|
||||
Assert.Equal((uint)red, mask.GetAddr32(0, 0));
|
||||
Assert.Equal((uint)blue, mask.GetAddr32(1, 0));
|
||||
Assert.Equal((uint)red, mask.GetAddr32(2, 0));
|
||||
Assert.Equal((uint)blue, mask.GetAddr32(3, 0));
|
||||
Assert.Equal((uint)red, mask.GetAddr32(0, 1));
|
||||
Assert.Equal((uint)blue, mask.GetAddr32(1, 1));
|
||||
Assert.Equal((uint)red, mask.GetAddr32(2, 1));
|
||||
Assert.Equal((uint)blue, mask.GetAddr32(3, 1));
|
||||
Assert.AreEqual((uint)red, mask.GetAddr32(0, 0));
|
||||
Assert.AreEqual((uint)blue, mask.GetAddr32(1, 0));
|
||||
Assert.AreEqual((uint)red, mask.GetAddr32(2, 0));
|
||||
Assert.AreEqual((uint)blue, mask.GetAddr32(3, 0));
|
||||
Assert.AreEqual((uint)red, mask.GetAddr32(0, 1));
|
||||
Assert.AreEqual((uint)blue, mask.GetAddr32(1, 1));
|
||||
Assert.AreEqual((uint)red, mask.GetAddr32(2, 1));
|
||||
Assert.AreEqual((uint)blue, mask.GetAddr32(3, 1));
|
||||
|
||||
mask.FreeImage();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void Matrix44CreatesIdentity()
|
||||
{
|
||||
var matrix = SKMatrix44.MakeIdentity();
|
||||
|
@ -227,10 +227,10 @@ namespace SkiaSharp.Tests
|
|||
};
|
||||
var rowMajor = matrix.ToRowMajor();
|
||||
|
||||
Assert.Equal(expectedRowMajor, rowMajor);
|
||||
Assert.AreEqual(expectedRowMajor, rowMajor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void Matrix44Inverts()
|
||||
{
|
||||
var rowMajor = new float[] {
|
||||
|
@ -249,18 +249,18 @@ namespace SkiaSharp.Tests
|
|||
|
||||
var matrix = SKMatrix44.MakeFromRowMajor(rowMajor);
|
||||
|
||||
Assert.Equal(rowMajor, matrix.ToRowMajor());
|
||||
Assert.Equal(determinant, matrix.Determinant());
|
||||
Assert.AreEqual(rowMajor, matrix.ToRowMajor());
|
||||
Assert.AreEqual(determinant, matrix.Determinant());
|
||||
|
||||
var inverted = matrix.Invert();
|
||||
|
||||
Assert.Equal(1f / determinant, inverted.Determinant());
|
||||
Assert.AreEqual(1f / determinant, inverted.Determinant());
|
||||
|
||||
var actualRowMajor = inverted.ToRowMajor();
|
||||
Assert.Equal(expectedRowMajor, actualRowMajor);
|
||||
Assert.AreEqual(expectedRowMajor, actualRowMajor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void Matrix44ConvertsToMatrix()
|
||||
{
|
||||
var rowMajor44 = new float[] {
|
||||
|
@ -277,13 +277,13 @@ namespace SkiaSharp.Tests
|
|||
|
||||
var matrix44 = SKMatrix44.MakeFromRowMajor(rowMajor44);
|
||||
|
||||
Assert.Equal(rowMajor, matrix44.Matrix.Values);
|
||||
Assert.AreEqual(rowMajor, matrix44.Matrix.Values);
|
||||
|
||||
matrix44 = SKMatrix44.MakeRotationDegrees(0, 0, 1, 45);
|
||||
Assert.Equal(SKMatrix.MakeRotationDegrees(45).Values, matrix44.Matrix.Values);
|
||||
Assert.AreEqual(SKMatrix.MakeRotationDegrees(45).Values, matrix44.Matrix.Values);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void Matrix44MapsScalars()
|
||||
{
|
||||
// translate
|
||||
|
@ -292,8 +292,8 @@ namespace SkiaSharp.Tests
|
|||
var resultTranslateZero = matrixTranslate.MapScalars(0, 0, 0, 1);
|
||||
var resultTranslateValue = matrixTranslate.MapScalars(5, 25, 0, 1);
|
||||
|
||||
Assert.Equal(new[] { 10f, 20f, 0f, 1f }, resultTranslateZero);
|
||||
Assert.Equal(new[] { 15f, 45f, 0f, 1f }, resultTranslateValue);
|
||||
Assert.AreEqual(new[] { 10f, 20f, 0f, 1f }, resultTranslateZero);
|
||||
Assert.AreEqual(new[] { 15f, 45f, 0f, 1f }, resultTranslateValue);
|
||||
|
||||
// rotate
|
||||
var matrixRotate = SKMatrix44.MakeRotationDegrees(0, 1, 0, 90);
|
||||
|
@ -301,11 +301,11 @@ namespace SkiaSharp.Tests
|
|||
var resultRotateZero = matrixRotate.MapScalars(0, 0, 0, 1);
|
||||
var resultRotateValue = matrixRotate.MapScalars(5, 25, 0, 1);
|
||||
|
||||
Assert.Equal(new[] { 0f, 0f, 0f, 1f }, resultRotateZero);
|
||||
Assert.Equal(new[] { 0f, 25f, -5f, 1f }, resultRotateValue.Select(v => (int)(v / EPSILON) * EPSILON));
|
||||
Assert.AreEqual(new[] { 0f, 0f, 0f, 1f }, resultRotateZero);
|
||||
Assert.AreEqual(new[] { 0f, 25f, -5f, 1f }, resultRotateValue.Select(v => (int)(v / EPSILON) * EPSILON));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void Matrix44MapsPoints()
|
||||
{
|
||||
// translate
|
||||
|
@ -314,8 +314,8 @@ namespace SkiaSharp.Tests
|
|||
var resultTranslateZero = matrixTranslate.MapPoint(SKPoint.Empty);
|
||||
var resultTranslateValue = matrixTranslate.MapPoint(new SKPoint(5, 25));
|
||||
|
||||
Assert.Equal(new SKPoint(10f, 20f), resultTranslateZero);
|
||||
Assert.Equal(new SKPoint(15f, 45f), resultTranslateValue);
|
||||
Assert.AreEqual(new SKPoint(10f, 20f), resultTranslateZero);
|
||||
Assert.AreEqual(new SKPoint(15f, 45f), resultTranslateValue);
|
||||
|
||||
// rotate
|
||||
var matrixRotate = SKMatrix44.MakeRotationDegrees(0, 1, 0, 90);
|
||||
|
@ -323,12 +323,12 @@ namespace SkiaSharp.Tests
|
|||
var resultRotateZero = matrixRotate.MapPoint(SKPoint.Empty);
|
||||
var resultRotateValue = matrixRotate.MapPoint(new SKPoint(5, 25));
|
||||
|
||||
Assert.Equal(new SKPoint(0f, 0f), resultRotateZero);
|
||||
Assert.Equal(0, resultRotateValue.X, PRECISION);
|
||||
Assert.Equal(25, resultRotateValue.Y, PRECISION);
|
||||
Assert.AreEqual(new SKPoint(0f, 0f), resultRotateZero);
|
||||
Assert.AreEqual(0, resultRotateValue.X, PRECISION);
|
||||
Assert.AreEqual(25, resultRotateValue.Y, PRECISION);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void Matrix44MapsPointsBulk()
|
||||
{
|
||||
var rnd = new Random();
|
||||
|
@ -346,7 +346,7 @@ namespace SkiaSharp.Tests
|
|||
|
||||
var actualResults = matrixTranslate.MapPoints(points);
|
||||
|
||||
Assert.Equal(results, actualResults);
|
||||
Assert.AreEqual(results, actualResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public class SKBitmapTest : SKTest
|
||||
{
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ReleaseBitmapPixelsWasInvoked()
|
||||
{
|
||||
bool released = false;
|
||||
|
@ -27,7 +27,7 @@ namespace SkiaSharp.Tests
|
|||
Assert.True(released, "The SKBitmapReleaseDelegate was not called.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ReleaseBitmapPixelsWithNullDelegate()
|
||||
{
|
||||
var info = new SKImageInfo(1, 1);
|
||||
|
@ -40,7 +40,7 @@ namespace SkiaSharp.Tests
|
|||
Marshal.FreeCoTaskMem(pixels);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void TestExtractAlpha()
|
||||
{
|
||||
var path = Path.Combine(PathToImages, "color-wheel.png");
|
||||
|
@ -55,30 +55,30 @@ namespace SkiaSharp.Tests
|
|||
|
||||
Assert.True(bitmap.ExtractAlpha(alpha, paint, out offset));
|
||||
|
||||
Assert.Equal(new SKPointI(-7, -7), offset);
|
||||
Assert.AreEqual(new SKPointI(-7, -7), offset);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void BitmapAndPixmapAreValid()
|
||||
{
|
||||
var info = new SKImageInfo(10, 10);
|
||||
using (var bitmap = new SKBitmap(info)) {
|
||||
Assert.Equal(10, bitmap.Width);
|
||||
Assert.Equal(10, bitmap.Height);
|
||||
Assert.AreEqual(10, bitmap.Width);
|
||||
Assert.AreEqual(10, bitmap.Height);
|
||||
|
||||
var pixmap = bitmap.PeekPixels();
|
||||
Assert.NotNull(pixmap);
|
||||
|
||||
Assert.Equal(10, pixmap.Width);
|
||||
Assert.Equal(10, pixmap.Height);
|
||||
Assert.AreEqual(10, pixmap.Width);
|
||||
Assert.AreEqual(10, pixmap.Height);
|
||||
|
||||
Assert.True(bitmap.GetPixels() != IntPtr.Zero);
|
||||
Assert.True(pixmap.GetPixels() != IntPtr.Zero);
|
||||
Assert.Equal(bitmap.GetPixels(), pixmap.GetPixels());
|
||||
Assert.AreEqual(bitmap.GetPixels(), pixmap.GetPixels());
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void BitmapResizes()
|
||||
{
|
||||
var srcInfo = new SKImageInfo(200, 200);
|
||||
|
@ -92,17 +92,17 @@ namespace SkiaSharp.Tests
|
|||
canvas.DrawRect(new SKRect(0, 0, 100, 200), paint);
|
||||
}
|
||||
|
||||
Assert.Equal(SKColors.Green, srcBmp.GetPixel(75, 75));
|
||||
Assert.Equal(SKColors.Blue, srcBmp.GetPixel(175, 175));
|
||||
Assert.AreEqual(SKColors.Green, srcBmp.GetPixel(75, 75));
|
||||
Assert.AreEqual(SKColors.Blue, srcBmp.GetPixel(175, 175));
|
||||
|
||||
var dstBmp = srcBmp.Resize(dstInfo, SKBitmapResizeMethod.Mitchell);
|
||||
Assert.NotNull(dstBmp);
|
||||
|
||||
Assert.Equal(SKColors.Green, dstBmp.GetPixel(25, 25));
|
||||
Assert.Equal(SKColors.Blue, dstBmp.GetPixel(75, 75));
|
||||
Assert.AreEqual(SKColors.Green, dstBmp.GetPixel(25, 25));
|
||||
Assert.AreEqual(SKColors.Blue, dstBmp.GetPixel(75, 75));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void AlphaMaskIsApplied()
|
||||
{
|
||||
var srcInfo = new SKImageInfo(4, 4);
|
||||
|
@ -112,7 +112,7 @@ namespace SkiaSharp.Tests
|
|||
|
||||
foreach (var pixel in pixels)
|
||||
{
|
||||
Assert.Equal(255, pixel.Alpha);
|
||||
Assert.AreEqual(255, pixel.Alpha);
|
||||
}
|
||||
|
||||
var maskBuffer = new byte[]
|
||||
|
@ -130,22 +130,22 @@ namespace SkiaSharp.Tests
|
|||
srcBmp.InstallMaskPixels(mask);
|
||||
|
||||
pixels = srcBmp.Pixels;
|
||||
Assert.Equal(128, pixels[0].Alpha);
|
||||
Assert.Equal(127, pixels[1].Alpha);
|
||||
Assert.Equal(126, pixels[2].Alpha);
|
||||
Assert.Equal(125, pixels[3].Alpha);
|
||||
Assert.Equal(101, pixels[4].Alpha);
|
||||
Assert.Equal(102, pixels[5].Alpha);
|
||||
Assert.Equal(103, pixels[6].Alpha);
|
||||
Assert.Equal(104, pixels[7].Alpha);
|
||||
Assert.Equal(96, pixels[8].Alpha);
|
||||
Assert.Equal(95, pixels[9].Alpha);
|
||||
Assert.Equal(94, pixels[10].Alpha);
|
||||
Assert.Equal(93, pixels[11].Alpha);
|
||||
Assert.Equal(72, pixels[12].Alpha);
|
||||
Assert.Equal(73, pixels[13].Alpha);
|
||||
Assert.Equal(74, pixels[14].Alpha);
|
||||
Assert.Equal(75, pixels[15].Alpha);
|
||||
Assert.AreEqual(128, pixels[0].Alpha);
|
||||
Assert.AreEqual(127, pixels[1].Alpha);
|
||||
Assert.AreEqual(126, pixels[2].Alpha);
|
||||
Assert.AreEqual(125, pixels[3].Alpha);
|
||||
Assert.AreEqual(101, pixels[4].Alpha);
|
||||
Assert.AreEqual(102, pixels[5].Alpha);
|
||||
Assert.AreEqual(103, pixels[6].Alpha);
|
||||
Assert.AreEqual(104, pixels[7].Alpha);
|
||||
Assert.AreEqual(96, pixels[8].Alpha);
|
||||
Assert.AreEqual(95, pixels[9].Alpha);
|
||||
Assert.AreEqual(94, pixels[10].Alpha);
|
||||
Assert.AreEqual(93, pixels[11].Alpha);
|
||||
Assert.AreEqual(72, pixels[12].Alpha);
|
||||
Assert.AreEqual(73, pixels[13].Alpha);
|
||||
Assert.AreEqual(74, pixels[14].Alpha);
|
||||
Assert.AreEqual(75, pixels[15].Alpha);
|
||||
|
||||
mask.FreeImage();
|
||||
}
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public class SKCodecTest : SKTest
|
||||
{
|
||||
[Fact]
|
||||
[Test]
|
||||
public void MinBufferedBytesNeededHasAValue ()
|
||||
{
|
||||
Assert.True (SKCodec.MinBufferedBytesNeeded > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void CanCreateStreamCodec ()
|
||||
{
|
||||
var stream = new SKFileStream (Path.Combine (PathToImages, "color-wheel.png"));
|
||||
using (var codec = SKCodec.Create (stream)) {
|
||||
Assert.Equal (SKEncodedFormat.Png, codec.EncodedFormat);
|
||||
Assert.Equal (128, codec.Info.Width);
|
||||
Assert.Equal (128, codec.Info.Height);
|
||||
Assert.Equal (SKAlphaType.Unpremul, codec.Info.AlphaType);
|
||||
Assert.Equal (SKImageInfo.PlatformColorType, codec.Info.ColorType);
|
||||
Assert.AreEqual (SKEncodedFormat.Png, codec.EncodedFormat);
|
||||
Assert.AreEqual (128, codec.Info.Width);
|
||||
Assert.AreEqual (128, codec.Info.Height);
|
||||
Assert.AreEqual (SKAlphaType.Unpremul, codec.Info.AlphaType);
|
||||
Assert.AreEqual (SKImageInfo.PlatformColorType, codec.Info.ColorType);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void GetGifFrames ()
|
||||
{
|
||||
const int FrameCount = 16;
|
||||
|
||||
var stream = new SKFileStream (Path.Combine (PathToImages, "animated-heart.gif"));
|
||||
using (var codec = SKCodec.Create (stream)) {
|
||||
Assert.Equal (-1, codec.RepetitionCount);
|
||||
Assert.AreEqual (-1, codec.RepetitionCount);
|
||||
|
||||
var frameInfos = codec.FrameInfo;
|
||||
Assert.Equal (FrameCount, frameInfos.Length);
|
||||
Assert.AreEqual (FrameCount, frameInfos.Length);
|
||||
|
||||
Assert.Equal (-1, frameInfos [0].RequiredFrame);
|
||||
Assert.AreEqual (-1, frameInfos [0].RequiredFrame);
|
||||
|
||||
var cachedFrames = new SKBitmap [FrameCount];
|
||||
var info = new SKImageInfo (codec.Info.Width, codec.Info.Height);
|
||||
|
@ -52,7 +52,7 @@ namespace SkiaSharp.Tests
|
|||
}
|
||||
var opts = new SKCodecOptions (index, cached);
|
||||
var result = codec.GetPixels (info, bm.GetPixels (), opts);
|
||||
Assert.Equal (SKCodecResult.Success, result);
|
||||
Assert.AreEqual (SKCodecResult.Success, result);
|
||||
});
|
||||
|
||||
for (var i = 0; i < FrameCount; i++) {
|
||||
|
@ -62,33 +62,33 @@ namespace SkiaSharp.Tests
|
|||
var uncachedFrame = new SKBitmap (info);
|
||||
decode (uncachedFrame, false, i);
|
||||
|
||||
Assert.Equal (cachedFrame.Bytes, uncachedFrame.Bytes);
|
||||
Assert.AreEqual (cachedFrame.Bytes, uncachedFrame.Bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void GetEncodedInfo ()
|
||||
{
|
||||
var stream = new SKFileStream (Path.Combine (PathToImages, "color-wheel.png"));
|
||||
using (var codec = SKCodec.Create (stream)) {
|
||||
Assert.Equal (SKEncodedInfoColor.Rgba, codec.EncodedInfo.Color);
|
||||
Assert.Equal (SKEncodedInfoAlpha.Unpremul, codec.EncodedInfo.Alpha);
|
||||
Assert.Equal (8, codec.EncodedInfo.BitsPerComponent);
|
||||
Assert.AreEqual (SKEncodedInfoColor.Rgba, codec.EncodedInfo.Color);
|
||||
Assert.AreEqual (SKEncodedInfoAlpha.Unpremul, codec.EncodedInfo.Alpha);
|
||||
Assert.AreEqual (8, codec.EncodedInfo.BitsPerComponent);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void CanGetPixels ()
|
||||
{
|
||||
var stream = new SKFileStream (Path.Combine (PathToImages, "baboon.png"));
|
||||
using (var codec = SKCodec.Create (stream)) {
|
||||
var pixels = codec.Pixels;
|
||||
Assert.Equal (codec.Info.BytesSize, pixels.Length);
|
||||
Assert.AreEqual (codec.Info.BytesSize, pixels.Length);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void DecodeImageScanlines ()
|
||||
{
|
||||
var path = Path.Combine (PathToImages, "CMYK.jpg");
|
||||
|
@ -104,37 +104,37 @@ namespace SkiaSharp.Tests
|
|||
scanlineBitmap.Erase (SKColors.Fuchsia);
|
||||
|
||||
var result = codec.StartScanlineDecode (info);
|
||||
Assert.Equal (SKCodecResult.Success, result);
|
||||
Assert.AreEqual (SKCodecResult.Success, result);
|
||||
|
||||
Assert.Equal (SKCodecScanlineOrder.TopDown, codec.ScanlineOrder);
|
||||
Assert.Equal (0, codec.NextScanline);
|
||||
Assert.AreEqual (SKCodecScanlineOrder.TopDown, codec.ScanlineOrder);
|
||||
Assert.AreEqual (0, codec.NextScanline);
|
||||
|
||||
// only decode every second line
|
||||
for (int y = 0; y < info.Height; y += 2) {
|
||||
Assert.Equal (1, codec.GetScanlines (scanlineBitmap.GetAddr (0, y), 1, info.RowBytes));
|
||||
Assert.Equal (y + 1, codec.NextScanline);
|
||||
Assert.AreEqual (1, codec.GetScanlines (scanlineBitmap.GetAddr (0, y), 1, info.RowBytes));
|
||||
Assert.AreEqual (y + 1, codec.NextScanline);
|
||||
if (codec.SkipScanlines (1))
|
||||
Assert.Equal (y + 2, codec.NextScanline);
|
||||
Assert.AreEqual (y + 2, codec.NextScanline);
|
||||
else
|
||||
Assert.Equal (imageHeight, codec.NextScanline); // reached the end
|
||||
Assert.AreEqual (imageHeight, codec.NextScanline); // reached the end
|
||||
}
|
||||
|
||||
Assert.False (codec.SkipScanlines (1));
|
||||
Assert.Equal (imageHeight, codec.NextScanline);
|
||||
Assert.AreEqual (imageHeight, codec.NextScanline);
|
||||
|
||||
for (var x = 0; x < info.Width; x++) {
|
||||
for (var y = 0; y < info.Height; y++) {
|
||||
if (y % 2 == 0)
|
||||
Assert.Equal (correctBitmap.GetPixel (x, y), scanlineBitmap.GetPixel (x, y));
|
||||
Assert.AreEqual (correctBitmap.GetPixel (x, y), scanlineBitmap.GetPixel (x, y));
|
||||
else
|
||||
Assert.Equal (SKColors.Fuchsia, scanlineBitmap.GetPixel (x, y));
|
||||
Assert.AreEqual (SKColors.Fuchsia, scanlineBitmap.GetPixel (x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void DecodePartialImage ()
|
||||
{
|
||||
// read the data here, so we can fake a throttle/download
|
||||
|
@ -166,7 +166,7 @@ namespace SkiaSharp.Tests
|
|||
var result = codec.StartIncrementalDecode (info, pixels, info.RowBytes);
|
||||
|
||||
// make sure the start was successful
|
||||
Assert.Equal (SKCodecResult.Success, result);
|
||||
Assert.AreEqual (SKCodecResult.Success, result);
|
||||
result = SKCodecResult.IncompleteInput;
|
||||
|
||||
while (result == SKCodecResult.IncompleteInput) {
|
||||
|
@ -182,12 +182,12 @@ namespace SkiaSharp.Tests
|
|||
}
|
||||
|
||||
// compare to original
|
||||
Assert.Equal (correctBytes, incremental.Pixels);
|
||||
Assert.AreEqual (correctBytes, incremental.Pixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void BitmapDecodesCorrectly ()
|
||||
{
|
||||
byte[] codecPixels;
|
||||
|
@ -201,10 +201,10 @@ namespace SkiaSharp.Tests
|
|||
bitmapPixels = bitmap.Bytes;
|
||||
}
|
||||
|
||||
Assert.Equal (codecPixels, bitmapPixels);
|
||||
Assert.AreEqual (codecPixels, bitmapPixels);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void BitmapDecodesCorrectlyWithManagedStream ()
|
||||
{
|
||||
byte[] codecPixels;
|
||||
|
@ -219,7 +219,7 @@ namespace SkiaSharp.Tests
|
|||
bitmapPixels = bitmap.Bytes;
|
||||
}
|
||||
|
||||
Assert.Equal (codecPixels, bitmapPixels);
|
||||
Assert.AreEqual (codecPixels, bitmapPixels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
|
@ -15,23 +15,23 @@ namespace SkiaSharp.Tests
|
|||
SKColors.Blue
|
||||
};
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void MembersRetrieveColors()
|
||||
{
|
||||
var colorTable = new SKColorTable(Colors);
|
||||
|
||||
Assert.Equal(Colors.Length, colorTable.Count);
|
||||
Assert.AreEqual(Colors.Length, colorTable.Count);
|
||||
|
||||
Assert.Equal(Colors, colorTable.Colors);
|
||||
Assert.AreEqual(Colors, colorTable.Colors);
|
||||
|
||||
Assert.Equal(Colors[0], colorTable[0]);
|
||||
Assert.Equal(Colors[1], colorTable[1]);
|
||||
Assert.Equal(Colors[2], colorTable[2]);
|
||||
Assert.Equal(Colors[3], colorTable[3]);
|
||||
Assert.Equal(Colors[4], colorTable[4]);
|
||||
Assert.AreEqual(Colors[0], colorTable[0]);
|
||||
Assert.AreEqual(Colors[1], colorTable[1]);
|
||||
Assert.AreEqual(Colors[2], colorTable[2]);
|
||||
Assert.AreEqual(Colors[3], colorTable[3]);
|
||||
Assert.AreEqual(Colors[4], colorTable[4]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void IndexerOutOfRangeBelow()
|
||||
{
|
||||
var colorTable = new SKColorTable(Colors);
|
||||
|
@ -42,7 +42,7 @@ namespace SkiaSharp.Tests
|
|||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void IndexerOutOfRangeAbove()
|
||||
{
|
||||
var colorTable = new SKColorTable(Colors);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
using SKOtherColor = System.Tuple<float, float, float>;
|
||||
using ToOtherColor = System.Tuple<SkiaSharp.SKColor, System.Tuple<float, float, float>, string>;
|
||||
|
@ -11,41 +11,41 @@ namespace SkiaSharp.Tests
|
|||
{
|
||||
private const int Precision = 2;
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ColorWithComponent()
|
||||
{
|
||||
var color = new SKColor();
|
||||
Assert.Equal(0, color.Red);
|
||||
Assert.Equal(0, color.Green);
|
||||
Assert.Equal(0, color.Blue);
|
||||
Assert.Equal(0, color.Alpha);
|
||||
Assert.AreEqual(0, color.Red);
|
||||
Assert.AreEqual(0, color.Green);
|
||||
Assert.AreEqual(0, color.Blue);
|
||||
Assert.AreEqual(0, color.Alpha);
|
||||
|
||||
var red = color.WithRed(255);
|
||||
Assert.Equal(255, red.Red);
|
||||
Assert.Equal(0, red.Green);
|
||||
Assert.Equal(0, red.Blue);
|
||||
Assert.Equal(0, red.Alpha);
|
||||
Assert.AreEqual(255, red.Red);
|
||||
Assert.AreEqual(0, red.Green);
|
||||
Assert.AreEqual(0, red.Blue);
|
||||
Assert.AreEqual(0, red.Alpha);
|
||||
|
||||
var green = color.WithGreen(255);
|
||||
Assert.Equal(0, green.Red);
|
||||
Assert.Equal(255, green.Green);
|
||||
Assert.Equal(0, green.Blue);
|
||||
Assert.Equal(0, green.Alpha);
|
||||
Assert.AreEqual(0, green.Red);
|
||||
Assert.AreEqual(255, green.Green);
|
||||
Assert.AreEqual(0, green.Blue);
|
||||
Assert.AreEqual(0, green.Alpha);
|
||||
|
||||
var blue = color.WithBlue(255);
|
||||
Assert.Equal(0, blue.Red);
|
||||
Assert.Equal(0, blue.Green);
|
||||
Assert.Equal(255, blue.Blue);
|
||||
Assert.Equal(0, blue.Alpha);
|
||||
Assert.AreEqual(0, blue.Red);
|
||||
Assert.AreEqual(0, blue.Green);
|
||||
Assert.AreEqual(255, blue.Blue);
|
||||
Assert.AreEqual(0, blue.Alpha);
|
||||
|
||||
var alpha = color.WithAlpha(255);
|
||||
Assert.Equal(0, alpha.Red);
|
||||
Assert.Equal(0, alpha.Green);
|
||||
Assert.Equal(0, alpha.Blue);
|
||||
Assert.Equal(255, alpha.Alpha);
|
||||
Assert.AreEqual(0, alpha.Red);
|
||||
Assert.AreEqual(0, alpha.Green);
|
||||
Assert.AreEqual(0, alpha.Blue);
|
||||
Assert.AreEqual(255, alpha.Alpha);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ColorRgbToHsl()
|
||||
{
|
||||
var tuples = new List<ToOtherColor> {
|
||||
|
@ -69,21 +69,21 @@ namespace SkiaSharp.Tests
|
|||
float h, s, l;
|
||||
rgb.ToHsl(out h, out s, out l);
|
||||
|
||||
Assert.Equal(other.Item1, h, Precision);
|
||||
Assert.Equal(other.Item2, s, Precision);
|
||||
Assert.Equal(other.Item3, l, Precision);
|
||||
Assert.AreEqual(other.Item1, h, Precision);
|
||||
Assert.AreEqual(other.Item2, s, Precision);
|
||||
Assert.AreEqual(other.Item3, l, Precision);
|
||||
|
||||
// to RGB
|
||||
SKColor back = SKColor.FromHsl(other.Item1, other.Item2, other.Item3);
|
||||
|
||||
Assert.Equal(rgb.Red, back.Red);
|
||||
Assert.Equal(rgb.Green, back.Green);
|
||||
Assert.Equal(rgb.Blue, back.Blue);
|
||||
Assert.Equal(rgb.Alpha, back.Alpha);
|
||||
Assert.AreEqual(rgb.Red, back.Red);
|
||||
Assert.AreEqual(rgb.Green, back.Green);
|
||||
Assert.AreEqual(rgb.Blue, back.Blue);
|
||||
Assert.AreEqual(rgb.Alpha, back.Alpha);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ColorRgbToHsv()
|
||||
{
|
||||
var tuples = new List<ToOtherColor> {
|
||||
|
@ -107,21 +107,21 @@ namespace SkiaSharp.Tests
|
|||
float h, s, v;
|
||||
rgb.ToHsv(out h, out s, out v);
|
||||
|
||||
Assert.Equal(other.Item1, h, Precision);
|
||||
Assert.Equal(other.Item2, s, Precision);
|
||||
Assert.Equal(other.Item3, v, Precision);
|
||||
Assert.AreEqual(other.Item1, h, Precision);
|
||||
Assert.AreEqual(other.Item2, s, Precision);
|
||||
Assert.AreEqual(other.Item3, v, Precision);
|
||||
|
||||
// to RGB
|
||||
SKColor back = SKColor.FromHsv(other.Item1, other.Item2, other.Item3);
|
||||
|
||||
Assert.Equal(rgb.Red, back.Red);
|
||||
Assert.Equal(rgb.Green, back.Green);
|
||||
Assert.Equal(rgb.Blue, back.Blue);
|
||||
Assert.Equal(rgb.Alpha, back.Alpha);
|
||||
Assert.AreEqual(rgb.Red, back.Red);
|
||||
Assert.AreEqual(rgb.Green, back.Green);
|
||||
Assert.AreEqual(rgb.Blue, back.Blue);
|
||||
Assert.AreEqual(rgb.Alpha, back.Alpha);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void HexToColor()
|
||||
{
|
||||
var tuples = new List<Tuple<string, SKColor>> {
|
||||
|
@ -151,11 +151,11 @@ namespace SkiaSharp.Tests
|
|||
|
||||
SKColor color = SKColor.Parse(hex);
|
||||
|
||||
Assert.Equal(other, color);
|
||||
Assert.AreEqual(other, color);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void InvalidHexToColor()
|
||||
{
|
||||
var tuples = new List<string> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
|
@ -8,16 +8,17 @@ namespace SkiaSharp.Tests
|
|||
{
|
||||
private readonly static byte[] OddData = new byte[] { 1, 3, 5, 7, 9 };
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ValidDataProperties()
|
||||
{
|
||||
var data = new SKData(OddData);
|
||||
|
||||
Assert.Equal(OddData.Length, data.Size);
|
||||
Assert.Equal(OddData, data.ToArray());
|
||||
Assert.AreEqual(OddData.Length, data.Size);
|
||||
Assert.AreEqual(OddData, data.ToArray());
|
||||
}
|
||||
|
||||
[Fact(Skip = "Doesn't work as it relies on memory being overwritten by an external process.")]
|
||||
[Test]
|
||||
[Ignore("Doesn't work as it relies on memory being overwritten by an external process.")]
|
||||
public void DataDisposedReturnsInvalidStream()
|
||||
{
|
||||
// create data
|
||||
|
@ -28,14 +29,14 @@ namespace SkiaSharp.Tests
|
|||
|
||||
// nuke the data
|
||||
data.Dispose();
|
||||
Assert.Equal(IntPtr.Zero, data.Handle);
|
||||
Assert.AreEqual(IntPtr.Zero, data.Handle);
|
||||
|
||||
// read the stream
|
||||
var buffer = new byte[OddData.Length];
|
||||
stream.Read(buffer, 0, buffer.Length);
|
||||
|
||||
// since the data was nuked, they will differ
|
||||
Assert.NotEqual(OddData, buffer);
|
||||
Assert.AreNotEqual(OddData, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
using SkiaSharp.Extended;
|
||||
|
||||
|
@ -9,12 +9,12 @@ namespace SkiaSharp.Tests
|
|||
{
|
||||
public class SKGeometryTest : SKTest
|
||||
{
|
||||
[Fact]
|
||||
[Test]
|
||||
public void GeometryGeneratesRectPath()
|
||||
{
|
||||
var rectPath = SKGeometry.CreateTrianglePath(100);
|
||||
|
||||
Assert.Equal(3, rectPath.PointCount);
|
||||
Assert.AreEqual(3, rectPath.PointCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public class SKManagedStreamTest : SKTest
|
||||
{
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ManagedStreamReadsByteCorrectly()
|
||||
{
|
||||
var data = new byte[1024];
|
||||
|
@ -20,25 +20,25 @@ namespace SkiaSharp.Tests
|
|||
var skManagedStream = new SKManagedStream(stream);
|
||||
|
||||
skManagedStream.Rewind();
|
||||
Assert.Equal(0, stream.Position);
|
||||
Assert.Equal(0, skManagedStream.Position);
|
||||
Assert.AreEqual(0, stream.Position);
|
||||
Assert.AreEqual(0, skManagedStream.Position);
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
skManagedStream.Position = i;
|
||||
|
||||
Assert.Equal(i, stream.Position);
|
||||
Assert.Equal(i, skManagedStream.Position);
|
||||
Assert.AreEqual(i, stream.Position);
|
||||
Assert.AreEqual(i, skManagedStream.Position);
|
||||
|
||||
Assert.Equal((byte)(i % byte.MaxValue), data[i]);
|
||||
Assert.Equal((byte)(i % byte.MaxValue), skManagedStream.ReadByte());
|
||||
Assert.AreEqual((byte)(i % byte.MaxValue), data[i]);
|
||||
Assert.AreEqual((byte)(i % byte.MaxValue), skManagedStream.ReadByte());
|
||||
|
||||
Assert.Equal(i + 1, stream.Position);
|
||||
Assert.Equal(i + 1, skManagedStream.Position);
|
||||
Assert.AreEqual(i + 1, stream.Position);
|
||||
Assert.AreEqual(i + 1, skManagedStream.Position);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ManagedStreamReadsChunkCorrectly()
|
||||
{
|
||||
var data = new byte[1024];
|
||||
|
@ -51,16 +51,16 @@ namespace SkiaSharp.Tests
|
|||
var skManagedStream = new SKManagedStream(stream);
|
||||
|
||||
skManagedStream.Rewind();
|
||||
Assert.Equal(0, stream.Position);
|
||||
Assert.Equal(0, skManagedStream.Position);
|
||||
Assert.AreEqual(0, stream.Position);
|
||||
Assert.AreEqual(0, skManagedStream.Position);
|
||||
|
||||
var buffer = new byte[data.Length / 2];
|
||||
skManagedStream.Read(buffer, buffer.Length);
|
||||
|
||||
Assert.Equal(data.Take(buffer.Length), buffer);
|
||||
Assert.AreEqual(data.Take(buffer.Length), buffer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ManagedStreamReadsOffsetChunkCorrectly()
|
||||
{
|
||||
var data = new byte[1024];
|
||||
|
@ -79,11 +79,11 @@ namespace SkiaSharp.Tests
|
|||
var buffer = new byte[data.Length];
|
||||
var taken = skManagedStream.Read(buffer, buffer.Length);
|
||||
|
||||
Assert.Equal(data.Length - offset, taken);
|
||||
Assert.AreEqual(data.Length - offset, taken);
|
||||
|
||||
var resultData = data.Skip(offset).Take(buffer.Length).ToArray();
|
||||
resultData = resultData.Concat(Enumerable.Repeat<byte>(0, offset)).ToArray();
|
||||
Assert.Equal(resultData, buffer);
|
||||
Assert.AreEqual(resultData, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public class SKPaintTest : SKTest
|
||||
{
|
||||
[Fact]
|
||||
[Test]
|
||||
public void StrokePropertyValuesAreCorrect()
|
||||
{
|
||||
var paint = new SKPaint();
|
||||
|
@ -18,7 +18,7 @@ namespace SkiaSharp.Tests
|
|||
Assert.False(paint.IsStroke);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void GetFillPathIsWorking()
|
||||
{
|
||||
var paint = new SKPaint();
|
||||
|
@ -32,11 +32,11 @@ namespace SkiaSharp.Tests
|
|||
var isFilled = paint.GetFillPath(path, fillPath);
|
||||
|
||||
Assert.True(isFilled);
|
||||
Assert.Equal(rect, fillPath.Bounds);
|
||||
Assert.Equal(4, fillPath.PointCount);
|
||||
Assert.AreEqual(rect, fillPath.Bounds);
|
||||
Assert.AreEqual(4, fillPath.PointCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void GetFillPathIsWorkingWithLine()
|
||||
{
|
||||
var paint = new SKPaint();
|
||||
|
@ -52,17 +52,17 @@ namespace SkiaSharp.Tests
|
|||
var isFilled = paint.GetFillPath(path, fillPath);
|
||||
|
||||
Assert.True(isFilled);
|
||||
Assert.Equal(thinRect, fillPath.Bounds);
|
||||
Assert.Equal(2, fillPath.PointCount);
|
||||
Assert.AreEqual(thinRect, fillPath.Bounds);
|
||||
Assert.AreEqual(2, fillPath.PointCount);
|
||||
|
||||
paint.StrokeWidth = 20;
|
||||
paint.IsStroke = true;
|
||||
isFilled = paint.GetFillPath(path, fillPath);
|
||||
|
||||
Assert.True(isFilled);
|
||||
Assert.Equal(rect, fillPath.Bounds);
|
||||
Assert.Equal(4 + 1, fillPath.PointCount); // +1 becuase the last point is the same as the first
|
||||
Assert.Equal(4, fillPath.Points.Distinct().Count());
|
||||
Assert.AreEqual(rect, fillPath.Bounds);
|
||||
Assert.AreEqual(4 + 1, fillPath.PointCount); // +1 becuase the last point is the same as the first
|
||||
Assert.AreEqual(4, fillPath.Points.Distinct().Count());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
using ParsePathTest = System.Tuple<System.String, SkiaSharp.SKRect>;
|
||||
|
||||
|
@ -34,10 +34,10 @@ namespace SkiaSharp.Tests
|
|||
var str2 = path2.ToSvgPathData ();
|
||||
Assert.NotNull (str2);
|
||||
|
||||
Assert.Equal (str, str2);
|
||||
Assert.AreEqual (str, str2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void PathPointsAreCorrect()
|
||||
{
|
||||
using (var path = new SKPath ()) {
|
||||
|
@ -58,19 +58,19 @@ namespace SkiaSharp.Tests
|
|||
path.Close ();
|
||||
|
||||
// the right number/count
|
||||
Assert.Equal (25, path.PointCount);
|
||||
Assert.Equal (25, path.Points.Length);
|
||||
Assert.AreEqual (25, path.PointCount);
|
||||
Assert.AreEqual (25, path.Points.Length);
|
||||
|
||||
// the right value
|
||||
Assert.Equal (new SKPoint (68.6763107f, 56.0058575f), path.GetPoint (1));
|
||||
Assert.Equal (new SKPoint (68.6763107f, 56.0058575f), path.Points [1]);
|
||||
Assert.AreEqual (new SKPoint (68.6763107f, 56.0058575f), path.GetPoint (1));
|
||||
Assert.AreEqual (new SKPoint (68.6763107f, 56.0058575f), path.Points [1]);
|
||||
|
||||
// the right segment masks
|
||||
Assert.Equal (SKPathSegmentMask.Cubic | SKPathSegmentMask.Line, path.SegmentMasks);
|
||||
Assert.AreEqual (SKPathSegmentMask.Cubic | SKPathSegmentMask.Line, path.SegmentMasks);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void PathContainsPoint()
|
||||
{
|
||||
using (var path = new SKPath ()) {
|
||||
|
@ -81,18 +81,18 @@ namespace SkiaSharp.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void GetLastPoint()
|
||||
{
|
||||
using (var path = new SKPath ()) {
|
||||
path.MoveTo (0, 0);
|
||||
path.LineTo (10, 20);
|
||||
|
||||
Assert.Equal (new SKPoint(10, 20), path.LastPoint);
|
||||
Assert.AreEqual (new SKPoint(10, 20), path.LastPoint);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ThumbtackShapeIsConcave ()
|
||||
{
|
||||
// based on test_skbug_3469
|
||||
|
@ -102,11 +102,11 @@ namespace SkiaSharp.Tests
|
|||
path.QuadTo (20, 50, 80, 50);
|
||||
path.QuadTo (20, 50, 20, 80);
|
||||
|
||||
Assert.Equal (SKPathConvexity.Concave, path.Convexity);
|
||||
Assert.AreEqual (SKPathConvexity.Concave, path.Convexity);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void PathConsistentAfterClose ()
|
||||
{
|
||||
// based on test_path_close_issue1474
|
||||
|
@ -123,8 +123,8 @@ namespace SkiaSharp.Tests
|
|||
path.RLineTo (50, 50); // This should go to 50,50.
|
||||
|
||||
last = path.LastPoint;
|
||||
Assert.Equal (50, last.X);
|
||||
Assert.Equal (50, last.Y);
|
||||
Assert.AreEqual (50, last.X);
|
||||
Assert.AreEqual (50, last.Y);
|
||||
|
||||
// Test rQuadTo().
|
||||
path.Rewind ();
|
||||
|
@ -134,8 +134,8 @@ namespace SkiaSharp.Tests
|
|||
path.RQuadTo (50, 50, 75, 75);
|
||||
|
||||
last = path.LastPoint;
|
||||
Assert.Equal (75, last.X);
|
||||
Assert.Equal (75, last.Y);
|
||||
Assert.AreEqual (75, last.X);
|
||||
Assert.AreEqual (75, last.Y);
|
||||
|
||||
// Test rConicTo().
|
||||
path.Rewind ();
|
||||
|
@ -145,8 +145,8 @@ namespace SkiaSharp.Tests
|
|||
path.RConicTo (50, 50, 85, 85, 2);
|
||||
|
||||
last = path.LastPoint;
|
||||
Assert.Equal (85, last.X);
|
||||
Assert.Equal (85, last.Y);
|
||||
Assert.AreEqual (85, last.X);
|
||||
Assert.AreEqual (85, last.Y);
|
||||
|
||||
// Test rCubicTo().
|
||||
path.Rewind ();
|
||||
|
@ -156,12 +156,12 @@ namespace SkiaSharp.Tests
|
|||
path.RCubicTo (50, 50, 85, 85, 95, 95);
|
||||
|
||||
last = path.LastPoint;
|
||||
Assert.Equal (95, last.X);
|
||||
Assert.Equal (95, last.Y);
|
||||
Assert.AreEqual (95, last.X);
|
||||
Assert.AreEqual (95, last.Y);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ParsePathReturnsValidPath ()
|
||||
{
|
||||
// based on ParsePath
|
||||
|
@ -170,7 +170,7 @@ namespace SkiaSharp.Tests
|
|||
var path = SKPath.ParseSvgPathData (test.Item1);
|
||||
|
||||
Assert.NotNull (path);
|
||||
Assert.Equal (test.Item2, path.Bounds);
|
||||
Assert.AreEqual (test.Item2, path.Bounds);
|
||||
|
||||
TestToFromSvgPath (path);
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ namespace SkiaSharp.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void PathBoundsAndRegionBoundsMatch ()
|
||||
{
|
||||
var path = new SKPath ();
|
||||
|
@ -196,22 +196,22 @@ namespace SkiaSharp.Tests
|
|||
path.LineTo (90, 90);
|
||||
|
||||
var bounds = path.Bounds;
|
||||
Assert.Equal (10f, bounds.Left);
|
||||
Assert.Equal (10f, bounds.Top);
|
||||
Assert.Equal (90f, bounds.Right);
|
||||
Assert.Equal (90f, bounds.Bottom);
|
||||
Assert.AreEqual (10f, bounds.Left);
|
||||
Assert.AreEqual (10f, bounds.Top);
|
||||
Assert.AreEqual (90f, bounds.Right);
|
||||
Assert.AreEqual (90f, bounds.Bottom);
|
||||
|
||||
var region = new SKRegion ();
|
||||
region.SetRect (new SKRectI (10, 10, 90, 90));
|
||||
|
||||
var regionBounds = region.Bounds;
|
||||
Assert.Equal (10f, regionBounds.Left);
|
||||
Assert.Equal (10f, regionBounds.Top);
|
||||
Assert.Equal (90f, regionBounds.Right);
|
||||
Assert.Equal (90f, regionBounds.Bottom);
|
||||
Assert.AreEqual (10f, regionBounds.Left);
|
||||
Assert.AreEqual (10f, regionBounds.Top);
|
||||
Assert.AreEqual (90f, regionBounds.Right);
|
||||
Assert.AreEqual (90f, regionBounds.Bottom);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void BoundsAndTightBoundAreCorrect ()
|
||||
{
|
||||
const int Precision = 6;
|
||||
|
@ -222,20 +222,20 @@ namespace SkiaSharp.Tests
|
|||
path.RCubicTo (-34.64102137842175f, 19.9999998f, 0f, 40f, 0f, 40f);
|
||||
|
||||
var bounds = path.Bounds;
|
||||
Assert.Equal (-34.641022f, bounds.Left, Precision);
|
||||
Assert.Equal (-25.814698f, bounds.Top, Precision);
|
||||
Assert.Equal (-6.215782e-07f, bounds.Right, Precision);
|
||||
Assert.Equal (14.185303f, bounds.Bottom, Precision);
|
||||
Assert.AreEqual (-34.641022f, bounds.Left, Precision);
|
||||
Assert.AreEqual (-25.814698f, bounds.Top, Precision);
|
||||
Assert.AreEqual (-6.215782e-07f, bounds.Right, Precision);
|
||||
Assert.AreEqual (14.185303f, bounds.Bottom, Precision);
|
||||
|
||||
var tightBounds = path.TightBounds;
|
||||
Assert.Equal (-15.396009f, tightBounds.Left, Precision);
|
||||
Assert.Equal (-25.814698f, tightBounds.Top, Precision);
|
||||
Assert.Equal (0f, tightBounds.Right, Precision);
|
||||
Assert.Equal (14.185303f, tightBounds.Bottom, Precision);
|
||||
Assert.AreEqual (-15.396009f, tightBounds.Left, Precision);
|
||||
Assert.AreEqual (-25.814698f, tightBounds.Top, Precision);
|
||||
Assert.AreEqual (0f, tightBounds.Right, Precision);
|
||||
Assert.AreEqual (14.185303f, tightBounds.Bottom, Precision);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void MeasuringSegementsWorks ()
|
||||
{
|
||||
using (SKPath path = new SKPath ())
|
||||
|
@ -243,18 +243,18 @@ namespace SkiaSharp.Tests
|
|||
path.MoveTo (10f, 10f);
|
||||
path.LineTo (110f, 10f);
|
||||
|
||||
Assert.Equal (SKPathSegmentMask.Line, path.SegmentMasks);
|
||||
Assert.AreEqual (SKPathSegmentMask.Line, path.SegmentMasks);
|
||||
|
||||
var measure = new SKPathMeasure (path);
|
||||
|
||||
Assert.Equal (100f, measure.Length);
|
||||
Assert.AreEqual (100f, measure.Length);
|
||||
|
||||
var segment = new SKPath ();
|
||||
var result = measure.GetSegment (20, 50, segment, true);
|
||||
Assert.True (result);
|
||||
Assert.Equal (2, segment.PointCount);
|
||||
Assert.Equal (new SKPoint (30, 10), segment.Points [0]);
|
||||
Assert.Equal (new SKPoint (60, 10), segment.Points [1]);
|
||||
Assert.AreEqual (2, segment.PointCount);
|
||||
Assert.AreEqual (new SKPoint (30, 10), segment.Points [0]);
|
||||
Assert.AreEqual (new SKPoint (60, 10), segment.Points [1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public class SKStringTest : SKTest
|
||||
{
|
||||
[Fact]
|
||||
[Test]
|
||||
public void StringIsMarshaledCorrectly ()
|
||||
{
|
||||
using (var typeface = SKTypeface.FromFile (Path.Combine (PathToFonts, "SpiderSymbol.ttf")))
|
||||
{
|
||||
if (IsLinux) // see issue #225
|
||||
Assert.Equal("", typeface.FamilyName);
|
||||
Assert.AreEqual("", typeface.FamilyName);
|
||||
else
|
||||
Assert.Equal ("SpiderSymbol", typeface.FamilyName);
|
||||
Assert.AreEqual ("SpiderSymbol", typeface.FamilyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ namespace SkiaSharp.Tests
|
|||
bitmap.UnlockBits(data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void SurfaceCanvasReturnTheSameInstance()
|
||||
{
|
||||
Draw(surface =>
|
||||
|
@ -46,14 +46,14 @@ namespace SkiaSharp.Tests
|
|||
Assert.NotNull(skcanvas1);
|
||||
Assert.NotNull(skcanvas2);
|
||||
|
||||
Assert.Equal(skcanvas1, skcanvas2);
|
||||
Assert.AreEqual(skcanvas1, skcanvas2);
|
||||
Assert.True(skcanvas1 == skcanvas2);
|
||||
|
||||
Assert.Same(skcanvas1, skcanvas2);
|
||||
Assert.AreSame(skcanvas1, skcanvas2);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void SecondSurfaceWasCreatedDifferent()
|
||||
{
|
||||
var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
|
||||
|
@ -64,8 +64,8 @@ namespace SkiaSharp.Tests
|
|||
Assert.NotNull(surface1);
|
||||
Assert.NotNull(surface2);
|
||||
|
||||
Assert.NotEqual(surface1, surface2);
|
||||
Assert.NotEqual(surface1.Handle, surface2.Handle);
|
||||
Assert.AreNotEqual(surface1, surface2);
|
||||
Assert.AreNotEqual(surface1.Handle, surface2.Handle);
|
||||
|
||||
surface1.Dispose();
|
||||
surface2.Dispose();
|
||||
|
@ -73,7 +73,7 @@ namespace SkiaSharp.Tests
|
|||
bitmap.UnlockBits(data);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void SurfaceWasCreated()
|
||||
{
|
||||
var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
|
||||
|
@ -81,11 +81,11 @@ namespace SkiaSharp.Tests
|
|||
var surface = SKSurface.Create(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Premul, data.Scan0, data.Stride);
|
||||
|
||||
Assert.NotNull(surface);
|
||||
Assert.NotEqual(IntPtr.Zero, surface.Handle);
|
||||
Assert.AreNotEqual(IntPtr.Zero, surface.Handle);
|
||||
|
||||
surface.Dispose();
|
||||
|
||||
Assert.Equal(IntPtr.Zero, surface.Handle);
|
||||
Assert.AreEqual(IntPtr.Zero, surface.Handle);
|
||||
|
||||
bitmap.UnlockBits(data);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public class SKSvgTest : SKTest
|
||||
{
|
||||
[Fact]
|
||||
[Test]
|
||||
public void LoadSvgCanvasSize()
|
||||
{
|
||||
var path = Path.Combine(PathToImages, "logos.svg");
|
||||
|
@ -15,10 +15,10 @@ namespace SkiaSharp.Tests
|
|||
var svg = new SKSvg();
|
||||
svg.Load(path);
|
||||
|
||||
Assert.Equal(new SKSize(300, 300), svg.CanvasSize);
|
||||
Assert.AreEqual(new SKSize(300, 300), svg.CanvasSize);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void LoadSvgCustomCanvasSize()
|
||||
{
|
||||
var path = Path.Combine(PathToImages, "logos.svg");
|
||||
|
@ -26,10 +26,10 @@ namespace SkiaSharp.Tests
|
|||
var svg = new SKSvg(new SKSize(150, 150));
|
||||
svg.Load(path);
|
||||
|
||||
Assert.Equal(new SKSize(150, 150), svg.CanvasSize);
|
||||
Assert.AreEqual(new SKSize(150, 150), svg.CanvasSize);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void SvgLoadsToBitmap()
|
||||
{
|
||||
var path = Path.Combine(PathToImages, "logos.svg");
|
||||
|
@ -43,10 +43,10 @@ namespace SkiaSharp.Tests
|
|||
canvas.DrawPicture(svg.Picture);
|
||||
canvas.Flush();
|
||||
|
||||
Assert.Equal(background, bmp.GetPixel(0, 0));
|
||||
Assert.AreEqual(background, bmp.GetPixel(0, 0));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void SvgCanvasCreatesValidDrawing()
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
|
@ -74,23 +74,23 @@ namespace SkiaSharp.Tests
|
|||
|
||||
var ns = (XNamespace)"http://www.w3.org/2000/svg";
|
||||
|
||||
Assert.Equal(ns, svg.GetDefaultNamespace());
|
||||
Assert.Equal("200", svg.Attribute("width").Value);
|
||||
Assert.Equal("150", svg.Attribute("height").Value);
|
||||
Assert.AreEqual(ns, svg.GetDefaultNamespace());
|
||||
Assert.AreEqual("200", svg.Attribute("width").Value);
|
||||
Assert.AreEqual("150", svg.Attribute("height").Value);
|
||||
|
||||
var rect = svg.Element(ns + "rect");
|
||||
Assert.Equal("rgb(0,0,255)", rect.Attribute("fill").Value);
|
||||
Assert.Equal("50", rect.Attribute("x").Value);
|
||||
Assert.Equal("70", rect.Attribute("y").Value);
|
||||
Assert.Equal("100", rect.Attribute("width").Value);
|
||||
Assert.Equal("30", rect.Attribute("height").Value);
|
||||
Assert.AreEqual("rgb(0,0,255)", rect.Attribute("fill").Value);
|
||||
Assert.AreEqual("50", rect.Attribute("x").Value);
|
||||
Assert.AreEqual("70", rect.Attribute("y").Value);
|
||||
Assert.AreEqual("100", rect.Attribute("width").Value);
|
||||
Assert.AreEqual("30", rect.Attribute("height").Value);
|
||||
|
||||
var ellipse = svg.Element(ns + "ellipse");
|
||||
Assert.Equal("rgb(255,0,0)", ellipse.Attribute("fill").Value);
|
||||
Assert.Equal("100", ellipse.Attribute("cx").Value);
|
||||
Assert.Equal("85", ellipse.Attribute("cy").Value);
|
||||
Assert.Equal("50", ellipse.Attribute("rx").Value);
|
||||
Assert.Equal("15", ellipse.Attribute("ry").Value);
|
||||
Assert.AreEqual("rgb(255,0,0)", ellipse.Attribute("fill").Value);
|
||||
Assert.AreEqual("100", ellipse.Attribute("cx").Value);
|
||||
Assert.AreEqual("85", ellipse.Attribute("cy").Value);
|
||||
Assert.AreEqual("50", ellipse.Attribute("rx").Value);
|
||||
Assert.AreEqual("15", ellipse.Attribute("ry").Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
|
||||
[assembly: Parallelizable(ParallelScope.Fixtures)]
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
{
|
||||
public abstract class SKTest
|
||||
{
|
||||
#if NET_STANDARD
|
||||
protected static readonly string PathToAssembly = Path.GetDirectoryName(typeof(SKTest).GetTypeInfo().Assembly.Location);
|
||||
protected static readonly string PathToFonts = Path.Combine(PathToAssembly, "fonts");
|
||||
protected static readonly string PathToImages = Path.Combine(PathToAssembly, "images");
|
||||
|
||||
#if NET_STANDARD
|
||||
protected static bool IsLinux => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
protected static bool IsMac => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||
protected static bool IsUnix => IsLinux || IsMac;
|
||||
|
@ -45,13 +47,56 @@ namespace SkiaSharp.Tests
|
|||
}
|
||||
}
|
||||
|
||||
protected const string PathToFonts = "fonts";
|
||||
protected const string PathToImages = "images";
|
||||
|
||||
protected static bool IsMac => MacPlatformDetector.IsMac.Value;
|
||||
protected static bool IsUnix => Environment.OSVersion.Platform == PlatformID.Unix || IsMac;
|
||||
protected static bool IsLinux => IsUnix && !IsMac;
|
||||
protected static bool IsWindows => !IsUnix;
|
||||
#endif
|
||||
|
||||
public static class MacDynamicLibraries
|
||||
{
|
||||
private const string SystemLibrary = "/usr/lib/libSystem.dylib";
|
||||
[DllImport(SystemLibrary)]
|
||||
public static extern IntPtr dlopen(string path, int mode);
|
||||
[DllImport(SystemLibrary)]
|
||||
public static extern IntPtr dlsym(IntPtr handle, string symbol);
|
||||
[DllImport(SystemLibrary)]
|
||||
public static extern void dlclose(IntPtr handle);
|
||||
}
|
||||
|
||||
public static class LinuxDynamicLibraries
|
||||
{
|
||||
private const string SystemLibrary = "libdl.so";
|
||||
[DllImport(SystemLibrary)]
|
||||
public static extern IntPtr dlopen(string path, int mode);
|
||||
[DllImport(SystemLibrary)]
|
||||
public static extern IntPtr dlsym(IntPtr handle, string symbol);
|
||||
[DllImport(SystemLibrary)]
|
||||
public static extern void dlclose(IntPtr handle);
|
||||
}
|
||||
|
||||
public static class WindowsDynamicLibraries
|
||||
{
|
||||
private const string SystemLibrary = "Kernel32.dll";
|
||||
[DllImport (SystemLibrary, SetLastError = true, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr LoadLibrary(string lpFileName);
|
||||
[DllImport (SystemLibrary, SetLastError = true, CharSet = CharSet.Ansi)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
|
||||
[DllImport (SystemLibrary, SetLastError = true, CharSet = CharSet.Ansi)]
|
||||
public static extern void FreeLibrary(IntPtr hModule);
|
||||
}
|
||||
|
||||
protected GlContext CreateGlContext()
|
||||
{
|
||||
if (IsLinux) {
|
||||
return new GlxContext();
|
||||
} else if (IsMac) {
|
||||
return new CglContext();
|
||||
} else if (IsWindows) {
|
||||
return new WglContext();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using System;
|
||||
using Xunit;
|
||||
using NUnit.Framework;
|
||||
using System.IO;
|
||||
|
||||
namespace SkiaSharp.Tests
|
||||
|
@ -22,21 +22,21 @@ namespace SkiaSharp.Tests
|
|||
0x02, 0x00, 0x24, 0x00, 0x44,
|
||||
};
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void NullInWrongFileName()
|
||||
{
|
||||
Assert.Null(SKTypeface.FromFile(Path.Combine(PathToFonts, "font that doesn't exist.ttf")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void TestFamilyName()
|
||||
{
|
||||
using (var typeface = SKTypeface.FromFile(Path.Combine(PathToFonts, "Roboto2-Regular_NoEmbed.ttf")))
|
||||
{
|
||||
if (IsLinux) // see issue #225
|
||||
Assert.Equal("", typeface.FamilyName);
|
||||
Assert.AreEqual("", typeface.FamilyName);
|
||||
else
|
||||
Assert.Equal("Roboto2", typeface.FamilyName);
|
||||
Assert.AreEqual("Roboto2", typeface.FamilyName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,46 +58,46 @@ namespace SkiaSharp.Tests
|
|||
(UInt32)(v[3]) << 00;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void TestGetTableTags()
|
||||
{
|
||||
using (var typeface = SKTypeface.FromFile(Path.Combine(PathToFonts, "SpiderSymbol.ttf")))
|
||||
{
|
||||
if (IsLinux) // see issue #225
|
||||
Assert.Equal("", typeface.FamilyName);
|
||||
Assert.AreEqual("", typeface.FamilyName);
|
||||
else
|
||||
Assert.Equal("SpiderSymbol", typeface.FamilyName);
|
||||
Assert.AreEqual("SpiderSymbol", typeface.FamilyName);
|
||||
var tables = typeface.GetTableTags();
|
||||
Assert.Equal(ExpectedTablesSpiderFont.Length, tables.Length);
|
||||
Assert.AreEqual(ExpectedTablesSpiderFont.Length, tables.Length);
|
||||
|
||||
for (int i = 0; i < tables.Length; i++) {
|
||||
Assert.Equal(ExpectedTablesSpiderFont[i], GetReadableTag(tables[i]));
|
||||
Assert.AreEqual(ExpectedTablesSpiderFont[i], GetReadableTag(tables[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void TestGetTableData()
|
||||
{
|
||||
using (var typeface = SKTypeface.FromFile(Path.Combine(PathToFonts, "ReallyBigA.ttf")))
|
||||
{
|
||||
if (IsLinux) // see issue #225
|
||||
Assert.Equal("", typeface.FamilyName);
|
||||
Assert.AreEqual("", typeface.FamilyName);
|
||||
else
|
||||
Assert.Equal("ReallyBigA", typeface.FamilyName);
|
||||
Assert.AreEqual("ReallyBigA", typeface.FamilyName);
|
||||
var tables = typeface.GetTableTags();
|
||||
|
||||
for (int i = 0; i < tables.Length; i++) {
|
||||
byte[] tableData = typeface.GetTableData(tables[i]);
|
||||
Assert.Equal(ExpectedTableLengthsReallyBigAFont[i], tableData.Length);
|
||||
Assert.AreEqual(ExpectedTableLengthsReallyBigAFont[i], tableData.Length);
|
||||
}
|
||||
|
||||
Assert.Equal(ExpectedTableDataPostReallyBigAFont, typeface.GetTableData(GetIntTag("post")));
|
||||
Assert.AreEqual(ExpectedTableDataPostReallyBigAFont, typeface.GetTableData(GetIntTag("post")));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void TestFontManagerMatchCharacter()
|
||||
{
|
||||
var fonts = SKFontManager.Default;
|
||||
|
@ -106,15 +106,15 @@ namespace SkiaSharp.Tests
|
|||
using (var typeface = fonts.MatchCharacter(emojiChar))
|
||||
{
|
||||
if (IsLinux)
|
||||
Assert.Equal("", typeface.FamilyName); // see issue #225
|
||||
Assert.AreEqual("Symbola", typeface.FamilyName);
|
||||
else if (IsMac)
|
||||
Assert.Equal("Apple Color Emoji", typeface.FamilyName);
|
||||
Assert.AreEqual("Apple Color Emoji", typeface.FamilyName);
|
||||
else if (IsWindows)
|
||||
Assert.Equal("Segoe UI Emoji", typeface.FamilyName);
|
||||
Assert.AreEqual("Segoe UI Emoji", typeface.FamilyName);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void ExceptionInInvalidGetTableData()
|
||||
{
|
||||
using (var typeface = SKTypeface.FromFile(Path.Combine(PathToFonts, "Distortable.ttf")))
|
||||
|
@ -123,7 +123,7 @@ namespace SkiaSharp.Tests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void TestTryGetTableData()
|
||||
{
|
||||
using (var typeface = SKTypeface.FromFile(Path.Combine(PathToFonts, "ReallyBigA.ttf")))
|
||||
|
@ -132,15 +132,15 @@ namespace SkiaSharp.Tests
|
|||
for (int i = 0; i < tables.Length; i++) {
|
||||
byte[] tableData;
|
||||
Assert.True(typeface.TryGetTableData(tables[i], out tableData));
|
||||
Assert.Equal(ExpectedTableLengthsReallyBigAFont[i], tableData.Length);
|
||||
Assert.AreEqual(ExpectedTableLengthsReallyBigAFont[i], tableData.Length);
|
||||
}
|
||||
|
||||
Assert.Equal(ExpectedTableDataPostReallyBigAFont, typeface.GetTableData(GetIntTag("post")));
|
||||
Assert.AreEqual(ExpectedTableDataPostReallyBigAFont, typeface.GetTableData(GetIntTag("post")));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Test]
|
||||
public void InvalidTryGetTableData()
|
||||
{
|
||||
using (var typeface = SKTypeface.FromFile(Path.Combine(PathToFonts, "Distortable.ttf")))
|
||||
|
|
|
@ -2,6 +2,7 @@ __MACOSX/
|
|||
Addins/
|
||||
Cake/
|
||||
NUnit.Console/
|
||||
NUnit.ConsoleRunner/
|
||||
xunit.runner.console/
|
||||
Microsoft.DotNet.BuildTools.GenAPI/
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Cake" version="0.17.0" />
|
||||
<package id="XUnit.Runner.Console" version="2.1.0" />
|
||||
<package id="NUnit.ConsoleRunner" version="3.6.0" />
|
||||
<package id="Microsoft.DotNet.BuildTools.GenAPI" version="1.0.0-beta-00081" />
|
||||
</packages>
|
||||
|
|
Загрузка…
Ссылка в новой задаче