* Correct company name
* Fix targets file
* Hide native files from project tree
* Add benchmark project
* Add a feature to skip the object registration
   - ISKSkipObjectRegistration
   - objects implementing this interface will not be registered in the global dictionary
   - major perf boos (2.84x) due to not having to look up in a dictionary
   - use direct constructor instead of object factory
* Throw an exception in "debug" builds
This commit is contained in:
Matthew Leibowitz 2020-05-10 16:56:12 +02:00 коммит произвёл GitHub
Родитель 887da1d5f4
Коммит 5ea66f2a4a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
38 изменённых файлов: 264 добавлений и 69 удалений

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

@ -0,0 +1,5 @@
<Project>
<Import Project="$(MSBuildThisFileDirectory)..\source\SkiaSharp.Build.props" />
</Project>

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

@ -0,0 +1,5 @@
<Project>
<Import Project="$(MSBuildThisFileDirectory)..\source\SkiaSharp.Build.targets" />
</Project>

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

@ -0,0 +1,32 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
namespace SkiaSharp.Benchmarks
{
//[SimpleJob(RuntimeMoniker.CoreRt31)]
[SimpleJob(RuntimeMoniker.Mono)]
[SimpleJob(RuntimeMoniker.Net472)]
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
public class Benchmark
{
public Benchmark()
{
// setup
}
[Benchmark]
public void TheBenchmark()
{
// benchmark
}
}
public class Program
{
public static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<Benchmark>();
}
}
}

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

@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
<RootNamespace>SkiaSharp.Benchmarks</RootNamespace>
<AssemblyName>SkiaSharp.Benchmarks</AssemblyName>
<SkipGenerateAssemblyVersionInfo>true</SkipGenerateAssemblyVersionInfo>
<SkipMDocGenerateDocs>true</SkipMDocGenerateDocs>
<SkipCopyToOutputDirectory>true</SkipCopyToOutputDirectory>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\binding\HarfBuzzSharp\HarfBuzzSharp.csproj" />
<ProjectReference Include="..\..\binding\SkiaSharp\SkiaSharp.csproj" />
<ProjectReference Include="..\..\source\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.dll" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.dll') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.pdb') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.dll" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.dll') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.pdb') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\osx\libSkiaSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\osx\libSkiaSharp.dylib') or '$(IsMacOS)' == 'true' " />
<Content Include="..\..\output\native\osx\libHarfBuzzSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\osx\libHarfBuzzSharp.dylib') or '$(IsMacOS)' == 'true' " />
<Content Include="..\..\output\native\linux\x64\libSkiaSharp.so" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\linux\x64\libSkiaSharp.so') or '$(IsLinux)' == 'true' " />
<Content Include="..\..\output\native\linux\x64\libHarfBuzzSharp.so" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\linux\x64\libHarfBuzzSharp.so') or '$(IsLinux)' == 'true' " />
</ItemGroup>
</Project>

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

@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.215
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp", "..\..\binding\SkiaSharp\SkiaSharp.csproj", "{3E1B158B-6C3B-4340-9F01-28E77D24F31D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp", "..\..\binding\HarfBuzzSharp\HarfBuzzSharp.csproj", "{38FFD397-8A5E-421A-8649-24FE463E1DE9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.HarfBuzz", "..\..\source\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz.csproj", "{0DE402FA-A101-438E-8528-6EA82E0FF803}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Benchmarks", "SkiaSharp.Benchmarks.csproj", "{8E5284C3-5AAF-4902-B12F-84E9172F20E0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E1B158B-6C3B-4340-9F01-28E77D24F31D}.Release|Any CPU.Build.0 = Release|Any CPU
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38FFD397-8A5E-421A-8649-24FE463E1DE9}.Release|Any CPU.Build.0 = Release|Any CPU
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0DE402FA-A101-438E-8528-6EA82E0FF803}.Release|Any CPU.Build.0 = Release|Any CPU
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E5284C3-5AAF-4902-B12F-84E9172F20E0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8355B800-A642-459B-8675-B545839DE6C7}
EndGlobalSection
EndGlobal

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

@ -3,7 +3,7 @@ using System.ComponentModel;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class GRBackendRenderTarget : SKObject public unsafe class GRBackendRenderTarget : SKObject, ISKSkipObjectRegistration
{ {
internal GRBackendRenderTarget (IntPtr handle, bool owns) internal GRBackendRenderTarget (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)

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

@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class GRBackendTexture : SKObject public unsafe class GRBackendTexture : SKObject, ISKSkipObjectRegistration
{ {
internal GRBackendTexture (IntPtr handle, bool owns) internal GRBackendTexture (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)

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

@ -3,7 +3,7 @@ using System.ComponentModel;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class GRContext : SKObject, ISKReferenceCounted public unsafe class GRContext : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
{ {
internal GRContext (IntPtr h, bool owns) internal GRContext (IntPtr h, bool owns)
: base (h, owns) : base (h, owns)
@ -105,6 +105,6 @@ namespace SkiaSharp
public int GetRecommendedSampleCount (GRPixelConfig config, float dpi) => 0; public int GetRecommendedSampleCount (GRPixelConfig config, float dpi) => 0;
internal static GRContext GetObject (IntPtr handle) => internal static GRContext GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new GRContext (h, o)); handle == IntPtr.Zero ? null : new GRContext (handle, true);
} }
} }

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

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class GRGlInterface : SKObject, ISKReferenceCounted public unsafe class GRGlInterface : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
{ {
internal GRGlInterface (IntPtr h, bool owns) internal GRGlInterface (IntPtr h, bool owns)
: base (h, owns) : base (h, owns)
@ -132,7 +132,7 @@ namespace SkiaSharp
} }
internal static GRGlInterface GetObject (IntPtr handle) => internal static GRGlInterface GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new GRGlInterface (h, o)); handle == IntPtr.Zero ? null : new GRGlInterface (handle, true);
private static class AngleLoader private static class AngleLoader
{ {

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

@ -1,12 +1,15 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
#if THROW_OBJECT_EXCEPTIONS
using System.Collections.Concurrent;
#endif
namespace SkiaSharp namespace SkiaSharp
{ {
internal static class HandleDictionary internal static class HandleDictionary
{ {
private static readonly Type SkipObjectRegistrationType = typeof (ISKSkipObjectRegistration);
#if THROW_OBJECT_EXCEPTIONS #if THROW_OBJECT_EXCEPTIONS
internal static readonly ConcurrentBag<Exception> exceptions = new ConcurrentBag<Exception> (); internal static readonly ConcurrentBag<Exception> exceptions = new ConcurrentBag<Exception> ();
@ -27,6 +30,11 @@ namespace SkiaSharp
return false; return false;
} }
if (SkipObjectRegistrationType.IsAssignableFrom (typeof (TSkiaObject))) {
instance = null;
return false;
}
instancesLock.EnterReadLock (); instancesLock.EnterReadLock ();
try { try {
return GetInstanceNoLocks (handle, out instance); return GetInstanceNoLocks (handle, out instance);
@ -45,6 +53,16 @@ namespace SkiaSharp
if (handle == IntPtr.Zero) if (handle == IntPtr.Zero)
return null; return null;
if (SkipObjectRegistrationType.IsAssignableFrom (typeof (TSkiaObject))) {
#if THROW_OBJECT_EXCEPTIONS
throw new InvalidOperationException (
$"For some reason, the object was constructed using a factory function instead of the constructor. " +
$"H: {handle.ToString ("x")} Type: {typeof (TSkiaObject)}");
#else
return objectFactory.Invoke (handle, owns);
#endif
}
instancesLock.EnterUpgradeableReadLock (); instancesLock.EnterUpgradeableReadLock ();
try { try {
if (GetInstanceNoLocks<TSkiaObject> (handle, out var instance)) { if (GetInstanceNoLocks<TSkiaObject> (handle, out var instance)) {
@ -111,6 +129,9 @@ namespace SkiaSharp
if (handle == IntPtr.Zero || instance == null) if (handle == IntPtr.Zero || instance == null)
return; return;
if (instance is ISKSkipObjectRegistration)
return;
SKObject objectToDispose = null; SKObject objectToDispose = null;
instancesLock.EnterWriteLock (); instancesLock.EnterWriteLock ();
@ -146,6 +167,9 @@ namespace SkiaSharp
if (handle == IntPtr.Zero) if (handle == IntPtr.Zero)
return; return;
if (instance is ISKSkipObjectRegistration)
return;
instancesLock.EnterWriteLock (); instancesLock.EnterWriteLock ();
try { try {
var existed = instances.TryGetValue (handle, out var weak); var existed = instances.TryGetValue (handle, out var weak);

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

@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyTitle("SkiaSharp")] [assembly: AssemblyTitle("SkiaSharp")]
[assembly: AssemblyDescription("SkiaSharp is a cross-platform 2D graphics API for .NET platforms that can be used across mobile, server and desktop models to render images.")] [assembly: AssemblyDescription("SkiaSharp is a cross-platform 2D graphics API for .NET platforms that can be used across mobile, server and desktop models to render images.")]
[assembly: AssemblyCompany("Xamarin Inc.")] [assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("SkiaSharp")] [assembly: AssemblyProduct("SkiaSharp")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: NeutralResourcesLanguage("en")] [assembly: NeutralResourcesLanguage("en")]
@ -23,6 +23,13 @@ using System.Runtime.CompilerServices;
"dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" + "dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" +
"65d016df")] "65d016df")]
[assembly: InternalsVisibleTo("SkiaSharp.Benchmarks, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" +
"8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" +
"3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fd" +
"dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" +
"65d016df")]
[assembly: InternalsVisibleTo("SkiaSharp.HarfBuzz, PublicKey=" + [assembly: InternalsVisibleTo("SkiaSharp.HarfBuzz, PublicKey=" +
"002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" + "002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" +
"8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" + "8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" +

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SK3dView : SKObject public unsafe class SK3dView : SKObject, ISKSkipObjectRegistration
{ {
internal SK3dView (IntPtr x, bool owns) internal SK3dView (IntPtr x, bool owns)
: base (x, owns) : base (x, owns)

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

@ -41,7 +41,7 @@ namespace SkiaSharp
// TODO: `GenerationID` may be useful // TODO: `GenerationID` may be useful
// TODO: `GetAddr` and `GetPixel` are confusing // TODO: `GetAddr` and `GetPixel` are confusing
public unsafe class SKBitmap : SKObject public unsafe class SKBitmap : SKObject, ISKSkipObjectRegistration
{ {
private const string UnsupportedColorTypeMessage = "Setting the ColorTable is only supported for bitmaps with ColorTypes of Index8."; private const string UnsupportedColorTypeMessage = "Setting the ColorTable is only supported for bitmaps with ColorTypes of Index8.";
private const string UnableToAllocatePixelsMessage = "Unable to allocate pixels for the bitmap."; private const string UnableToAllocatePixelsMessage = "Unable to allocate pixels for the bitmap.";

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

@ -7,7 +7,7 @@ namespace SkiaSharp
// TODO: `Create(...)` should have overloads that accept a SKPngChunkReader // TODO: `Create(...)` should have overloads that accept a SKPngChunkReader
// TODO: missing the `QueryYuv8` and `GetYuv8Planes` members // TODO: missing the `QueryYuv8` and `GetYuv8Planes` members
public unsafe class SKCodec : SKObject public unsafe class SKCodec : SKObject, ISKSkipObjectRegistration
{ {
internal SKCodec (IntPtr handle, bool owns) internal SKCodec (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)
@ -344,6 +344,6 @@ namespace SkiaSharp
} }
internal static SKCodec GetObject (IntPtr handle) => internal static SKCodec GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKCodec (h, o)); handle == IntPtr.Zero ? null : new SKCodec (handle, true);
} }
} }

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

@ -5,7 +5,7 @@ namespace SkiaSharp
{ {
[EditorBrowsable (EditorBrowsableState.Never)] [EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("The Index8 color type and color table is no longer supported.")] [Obsolete ("The Index8 color type and color table is no longer supported.")]
public unsafe class SKColorTable : SKObject, ISKReferenceCounted public unsafe class SKColorTable : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
{ {
public const int MaxLength = 256; public const int MaxLength = 256;

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

@ -4,7 +4,7 @@ using System.IO;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKDocument : SKObject, ISKReferenceCounted public unsafe class SKDocument : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
{ {
public const float DefaultRasterDpi = 72.0f; public const float DefaultRasterDpi = 72.0f;
@ -179,6 +179,6 @@ namespace SkiaSharp
} }
internal static SKDocument GetObject (IntPtr handle) => internal static SKDocument GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKDocument (h, o)); handle == IntPtr.Zero ? null : new SKDocument (handle, true);
} }
} }

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public class SKFontStyle : SKObject public class SKFontStyle : SKObject, ISKSkipObjectRegistration
{ {
private static readonly SKFontStyle normal; private static readonly SKFontStyle normal;
private static readonly SKFontStyle bold; private static readonly SKFontStyle bold;
@ -60,7 +60,7 @@ namespace SkiaSharp
// //
internal static SKFontStyle GetObject (IntPtr handle) => internal static SKFontStyle GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKFontStyle (h, o)); handle == IntPtr.Zero ? null : new SKFontStyle (handle, true);
private sealed class SKFontStyleStatic : SKFontStyle private sealed class SKFontStyleStatic : SKFontStyle
{ {

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

@ -349,4 +349,8 @@ namespace SkiaSharp
void UnreferenceNative (); void UnreferenceNative ();
} }
internal interface ISKSkipObjectRegistration
{
}
} }

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKPaint : SKObject public unsafe class SKPaint : SKObject, ISKSkipObjectRegistration
{ {
internal SKPaint (IntPtr handle, bool owns) internal SKPaint (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)
@ -818,6 +818,6 @@ namespace SkiaSharp
// //
internal static SKPaint GetObject (IntPtr handle) => internal static SKPaint GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKPaint (h, o)); handle == IntPtr.Zero ? null : new SKPaint (handle, true);
} }
} }

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

@ -3,7 +3,7 @@ using System.ComponentModel;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKPath : SKObject public unsafe class SKPath : SKObject, ISKSkipObjectRegistration
{ {
internal SKPath (IntPtr handle, bool owns) internal SKPath (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)
@ -482,11 +482,11 @@ namespace SkiaSharp
// //
internal static SKPath GetObject (IntPtr handle) => internal static SKPath GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKPath (h, o)); handle == IntPtr.Zero ? null : new SKPath (handle, true);
// //
public class Iterator : SKObject public class Iterator : SKObject, ISKSkipObjectRegistration
{ {
private readonly SKPath path; private readonly SKPath path;
@ -521,7 +521,7 @@ namespace SkiaSharp
SkiaApi.sk_path_iter_is_closed_contour (Handle) != 0; SkiaApi.sk_path_iter_is_closed_contour (Handle) != 0;
} }
public class RawIterator : SKObject public class RawIterator : SKObject, ISKSkipObjectRegistration
{ {
private readonly SKPath path; private readonly SKPath path;
@ -554,7 +554,7 @@ namespace SkiaSharp
SkiaApi.sk_path_rawiter_peek (Handle); SkiaApi.sk_path_rawiter_peek (Handle);
} }
public class OpBuilder : SKObject public class OpBuilder : SKObject, ISKSkipObjectRegistration
{ {
public OpBuilder () public OpBuilder ()
: base (SkiaApi.sk_opbuilder_new (), true) : base (SkiaApi.sk_opbuilder_new (), true)

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKPathMeasure : SKObject public unsafe class SKPathMeasure : SKObject, ISKSkipObjectRegistration
{ {
internal SKPathMeasure (IntPtr handle, bool owns) internal SKPathMeasure (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKPictureRecorder : SKObject public unsafe class SKPictureRecorder : SKObject, ISKSkipObjectRegistration
{ {
internal SKPictureRecorder (IntPtr handle, bool owns) internal SKPictureRecorder (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)

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

@ -5,7 +5,7 @@ namespace SkiaSharp
{ {
[EditorBrowsable (EditorBrowsableState.Never)] [EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete] [Obsolete]
public abstract class SKPixelSerializer : SKObject public abstract class SKPixelSerializer : SKObject, ISKSkipObjectRegistration
{ {
protected SKPixelSerializer () protected SKPixelSerializer ()
: base (IntPtr.Zero, false) : base (IntPtr.Zero, false)

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKRegion : SKObject public unsafe class SKRegion : SKObject, ISKSkipObjectRegistration
{ {
internal SKRegion (IntPtr handle, bool owns) internal SKRegion (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)
@ -230,7 +230,7 @@ namespace SkiaSharp
// classes // classes
public class RectIterator : SKObject public class RectIterator : SKObject, ISKSkipObjectRegistration
{ {
private readonly SKRegion region; private readonly SKRegion region;
@ -260,7 +260,7 @@ namespace SkiaSharp
} }
} }
public class ClipIterator : SKObject public class ClipIterator : SKObject, ISKSkipObjectRegistration
{ {
private readonly SKRegion region; private readonly SKRegion region;
private readonly SKRectI clip; private readonly SKRectI clip;
@ -292,20 +292,11 @@ namespace SkiaSharp
} }
} }
public class SpanIterator : SKObject public class SpanIterator : SKObject, ISKSkipObjectRegistration
{ {
private readonly SKRegion region;
private readonly int y;
private readonly int left;
private readonly int right;
internal SpanIterator (SKRegion region, int y, int left, int right) internal SpanIterator (SKRegion region, int y, int left, int right)
: base (SkiaApi.sk_region_spanerator_new (region.Handle, y, left, right), true) : base (SkiaApi.sk_region_spanerator_new (region.Handle, y, left, right), true)
{ {
this.region = region;
this.y = y;
this.left = left;
this.right = right;
} }
protected override void DisposeNative () => protected override void DisposeNative () =>

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKRoundRect : SKObject public unsafe class SKRoundRect : SKObject, ISKSkipObjectRegistration
{ {
internal SKRoundRect (IntPtr handle, bool owns) internal SKRoundRect (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)

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

@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
namespace SkiaSharp namespace SkiaSharp
{ {
internal unsafe class SKString : SKObject internal unsafe class SKString : SKObject, ISKSkipObjectRegistration
{ {
internal SKString (IntPtr handle, bool owns) internal SKString (IntPtr handle, bool owns)
: base (handle, owns) : base (handle, owns)
@ -70,7 +70,7 @@ namespace SkiaSharp
SkiaApi.sk_string_destructor (Handle); SkiaApi.sk_string_destructor (Handle);
internal static SKString GetObject (IntPtr handle) => internal static SKString GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKString (h, o)); handle == IntPtr.Zero ? null : new SKString (handle, true);
} }
} }

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

@ -3,7 +3,7 @@ using System.ComponentModel;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKSurface : SKObject, ISKReferenceCounted public unsafe class SKSurface : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration
{ {
[EditorBrowsable (EditorBrowsableState.Never)] [EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use Create(SKImageInfo) instead.")] [Obsolete ("Use Create(SKImageInfo) instead.")]
@ -352,6 +352,6 @@ namespace SkiaSharp
} }
internal static SKSurface GetObject (IntPtr handle) => internal static SKSurface GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKSurface (h, o)); handle == IntPtr.Zero ? null : new SKSurface (handle, true);
} }
} }

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

@ -2,7 +2,7 @@
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKTextBlob : SKObject, ISKNonVirtualReferenceCounted public unsafe class SKTextBlob : SKObject, ISKNonVirtualReferenceCounted, ISKSkipObjectRegistration
{ {
internal SKTextBlob (IntPtr x, bool owns) internal SKTextBlob (IntPtr x, bool owns)
: base (x, owns) : base (x, owns)
@ -27,10 +27,10 @@ namespace SkiaSharp
public uint UniqueId => SkiaApi.sk_textblob_get_unique_id (Handle); public uint UniqueId => SkiaApi.sk_textblob_get_unique_id (Handle);
internal static SKTextBlob GetObject (IntPtr handle) => internal static SKTextBlob GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKTextBlob (h, o)); handle == IntPtr.Zero ? null : new SKTextBlob (handle, true);
} }
public unsafe class SKTextBlobBuilder : SKObject public unsafe class SKTextBlobBuilder : SKObject, ISKSkipObjectRegistration
{ {
internal SKTextBlobBuilder (IntPtr x, bool owns) internal SKTextBlobBuilder (IntPtr x, bool owns)
: base (x, owns) : base (x, owns)

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

@ -6,7 +6,7 @@ using System.ComponentModel;
namespace SkiaSharp namespace SkiaSharp
{ {
public unsafe class SKVertices : SKObject, ISKNonVirtualReferenceCounted public unsafe class SKVertices : SKObject, ISKNonVirtualReferenceCounted, ISKSkipObjectRegistration
{ {
internal SKVertices (IntPtr x, bool owns) internal SKVertices (IntPtr x, bool owns)
: base (x, owns) : base (x, owns)
@ -52,6 +52,6 @@ namespace SkiaSharp
} }
internal static SKVertices GetObject (IntPtr handle) => internal static SKVertices GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKVertices (h, o)); handle == IntPtr.Zero ? null : new SKVertices (handle, true);
} }
} }

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

@ -1,6 +1,9 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Text; using System.Text;
#if NETSTANDARD1_3 || WINDOWS_UWP
using System.Reflection;
#endif
namespace SkiaSharp namespace SkiaSharp
{ {
@ -34,6 +37,11 @@ namespace SkiaSharp
return bytes; return bytes;
} }
} }
#if NETSTANDARD1_3 || WINDOWS_UWP
internal static bool IsAssignableFrom (this Type type, Type c) =>
type.GetTypeInfo ().IsAssignableFrom (c.GetTypeInfo ());
#endif
} }
public unsafe static class StringUtilities public unsafe static class StringUtilities

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

@ -5,7 +5,7 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyTitle("HarfBuzzSharp")] [assembly: AssemblyTitle("HarfBuzzSharp")]
[assembly: AssemblyDescription("HarfBuzzSharp is a cross-platform OpenType text shaping engine for .NET platforms.")] [assembly: AssemblyDescription("HarfBuzzSharp is a cross-platform OpenType text shaping engine for .NET platforms.")]
[assembly: AssemblyCompany("Xamarin Inc.")] [assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("HarfBuzzSharp")] [assembly: AssemblyProduct("HarfBuzzSharp")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: NeutralResourcesLanguage("en")] [assembly: NeutralResourcesLanguage("en")]

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

@ -48,7 +48,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="netstandard" />
<PackageReference Include="mdoc" Version="5.7.4.10" PrivateAssets="All" /> <PackageReference Include="mdoc" Version="5.7.4.10" PrivateAssets="All" />
<PackageReference Include="Xamarin.Build.TypeRedirector" Version="0.1.2-preview" PrivateAssets="All" /> <PackageReference Include="Xamarin.Build.TypeRedirector" Version="0.1.2-preview" PrivateAssets="All" />
</ItemGroup> </ItemGroup>
@ -60,7 +59,12 @@
Generate the assembly versioning attributes from the VERSIONS.txt file. Generate the assembly versioning attributes from the VERSIONS.txt file.
=================================================================================================================== ===================================================================================================================
--> -->
<Target Name="_GenerateAssemblyVersionInfo" BeforeTargets="CoreCompile" Condition=" '$(SkipGenerateAssemblyVersionInfo)' != 'true' "> <PropertyGroup Condition=" '$(SkipGenerateAssemblyVersionInfo)' != 'true' ">
<_GenerateAssemblyVersionInfoBeforeTargets>
CoreCompile
</_GenerateAssemblyVersionInfoBeforeTargets>
</PropertyGroup>
<Target Name="_GenerateAssemblyVersionInfo" BeforeTargets="$(_GenerateAssemblyVersionInfoBeforeTargets)" Condition=" '$(SkipGenerateAssemblyVersionInfo)' != 'true' ">
<PropertyGroup> <PropertyGroup>
<_VersionSourceFile>$(IntermediateOutputPath)\$(AssemblyName).Version.cs</_VersionSourceFile> <_VersionSourceFile>$(IntermediateOutputPath)\$(AssemblyName).Version.cs</_VersionSourceFile>
<_VersionTxtFile>$(MSBuildThisFileDirectory)..\VERSIONS.txt</_VersionTxtFile> <_VersionTxtFile>$(MSBuildThisFileDirectory)..\VERSIONS.txt</_VersionTxtFile>
@ -94,7 +98,15 @@
Sign the assembly using sn. Sign the assembly using sn.
=================================================================================================================== ===================================================================================================================
--> -->
<Target Name="_SignAssembly" AfterTargets="CoreCompile" DependsOnTargets="_RedirectMovedTypes" Condition=" '$(SignAssembly)' == 'true' "> <PropertyGroup Condition=" '$(SignAssembly)' == 'true' and '$(TargetPath)' != '' ">
<_SignAssemblyDependsOn Condition=" '$(TypeRedirectorSkip)' == 'false'">
_RedirectMovedTypes
</_SignAssemblyDependsOn>
<_SignAssemblyAfterTargets>
CoreCompile
</_SignAssemblyAfterTargets>
</PropertyGroup>
<Target Name="_SignAssembly" AfterTargets="$(_SignAssemblyAfterTargets)" DependsOnTargets="$(_SignAssemblyDependsOn)" Condition=" '$(SignAssembly)' == 'true' and '$(TargetPath)' != '' ">
<Exec Command="&quot;$(_SnExePath)&quot; -q -R @(IntermediateAssembly -> '&quot;%(Identity)&quot;') &quot;$(AssemblyOriginatorKeyFile)&quot;" /> <Exec Command="&quot;$(_SnExePath)&quot; -q -R @(IntermediateAssembly -> '&quot;%(Identity)&quot;') &quot;$(AssemblyOriginatorKeyFile)&quot;" />
</Target> </Target>
@ -105,7 +117,12 @@
Verify that the output assembly is signed correctly for release. Verify that the output assembly is signed correctly for release.
=================================================================================================================== ===================================================================================================================
--> -->
<Target Name="_SignAssemblyVerify" AfterTargets="Build" Condition=" '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' "> <PropertyGroup Condition=" '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' ">
<_SignAssemblyVerifyAfterTargets>
Build
</_SignAssemblyVerifyAfterTargets>
</PropertyGroup>
<Target Name="_SignAssemblyVerify" AfterTargets="$(_SignAssemblyVerifyAfterTargets)" Condition=" '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' ">
<Exec Command="&quot;$(_SnExePath)&quot; -vf &quot;$(TargetPath)&quot;" /> <Exec Command="&quot;$(_SnExePath)&quot; -vf &quot;$(TargetPath)&quot;" />
</Target> </Target>
@ -127,6 +144,11 @@
Copy the project output into the root output folder. Copy the project output into the root output folder.
=================================================================================================================== ===================================================================================================================
--> -->
<PropertyGroup Condition=" '$(SkipCopyToOutputDirectory)' != 'true' and '$(TargetPath)' != '' ">
<_CopyToOutputDirectoryAfterTargets>
Build
</_CopyToOutputDirectoryAfterTargets>
</PropertyGroup>
<Target Name="_CopyToOutputDirectoryDep"> <Target Name="_CopyToOutputDirectoryDep">
<ItemGroup Condition=" '$(PackagingLocation)' == '' "> <ItemGroup Condition=" '$(PackagingLocation)' == '' ">
<_CopyItems Include="$(TargetPath)" Dest="nuget\lib\$(PackagingPlatform)\$(TargetFileName)" /> <_CopyItems Include="$(TargetPath)" Dest="nuget\lib\$(PackagingPlatform)\$(TargetFileName)" />
@ -143,7 +165,7 @@
</ItemGroup> </ItemGroup>
</Target> </Target>
<Target Name="_CopyToOutputDirectory" Condition=" '$(SkipCopyToOutputDirectory)' != 'true' and '$(TargetPath)' != '' " <Target Name="_CopyToOutputDirectory" Condition=" '$(SkipCopyToOutputDirectory)' != 'true' and '$(TargetPath)' != '' "
AfterTargets="Build" DependsOnTargets="_CopyToOutputDirectoryDep" AfterTargets="$(_CopyToOutputDirectoryAfterTargets)" DependsOnTargets="_CopyToOutputDirectoryDep"
Inputs="@(_CopyItems)" Outputs="@(_CopyItems -> '$(MSBuildThisFileDirectory)..\output\$(PackagingGroup)\%(Dest)')"> Inputs="@(_CopyItems)" Outputs="@(_CopyItems -> '$(MSBuildThisFileDirectory)..\output\$(PackagingGroup)\%(Dest)')">
<Copy Condition=" '@(_CopyItems)' != '' " <Copy Condition=" '@(_CopyItems)' != '' "
SourceFiles="@(_CopyItems)" SourceFiles="@(_CopyItems)"
@ -160,6 +182,11 @@
This runs during the build phase. This runs during the build phase.
=================================================================================================================== ===================================================================================================================
--> -->
<PropertyGroup Condition=" '$(SkipMDocGenerateDocs)' != 'true' ">
<MDocGenerateDocsAfterTargets>
CoreCompile
</MDocGenerateDocsAfterTargets>
</PropertyGroup>
<Target Name="_MDocGenerateDocsDep"> <Target Name="_MDocGenerateDocsDep">
<PropertyGroup> <PropertyGroup>
<MDocVersion Condition=" '%(Identity)' == 'mdoc' ">@(PackageReference -> '%(Version)')</MDocVersion> <MDocVersion Condition=" '%(Identity)' == 'mdoc' ">@(PackageReference -> '%(Version)')</MDocVersion>
@ -176,7 +203,7 @@
</ItemGroup> </ItemGroup>
</Target> </Target>
<Target Name="MDocGenerateDocs" Condition=" '$(SkipMDocGenerateDocs)' != 'true' " <Target Name="MDocGenerateDocs" Condition=" '$(SkipMDocGenerateDocs)' != 'true' "
AfterTargets="CoreCompile" DependsOnTargets="_MDocGenerateDocsDep" AfterTargets="$(MDocGenerateDocsAfterTargets)" DependsOnTargets="_MDocGenerateDocsDep"
Inputs="@(_MDocInputs)" Outputs="$(MDocOutputPath)"> Inputs="@(_MDocInputs)" Outputs="$(MDocOutputPath)">
<MakeDir Directories="$(MDocIntermediateOutputPath)" /> <MakeDir Directories="$(MDocIntermediateOutputPath)" />
<Exec Condition=" '$(_ShouldGenerateDocs)' == 'true' " <Exec Condition=" '$(_ShouldGenerateDocs)' == 'true' "

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

@ -4,7 +4,7 @@ using System.Resources;
[assembly: AssemblyTitle("SkiaSharp.HarfBuzz")] [assembly: AssemblyTitle("SkiaSharp.HarfBuzz")]
[assembly: AssemblyDescription("This package adds text shaping support to SkiaSharp via HarfBuzz.")] [assembly: AssemblyDescription("This package adds text shaping support to SkiaSharp via HarfBuzz.")]
[assembly: AssemblyCompany("Xamarin Inc.")] [assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("SkiaSharp.HarfBuzz")] [assembly: AssemblyProduct("SkiaSharp.HarfBuzz")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: NeutralResourcesLanguage("en")] [assembly: NeutralResourcesLanguage("en")]

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

@ -4,7 +4,7 @@ using System.Resources;
[assembly: AssemblyTitle("SkiaSharp.Views.Forms")] [assembly: AssemblyTitle("SkiaSharp.Views.Forms")]
[assembly: AssemblyDescription("SkiaSharp for Xamarin.Forms is a set of views that can be used to draw on the screen.")] [assembly: AssemblyDescription("SkiaSharp for Xamarin.Forms is a set of views that can be used to draw on the screen.")]
[assembly: AssemblyCompany("Xamarin Inc.")] [assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("SkiaSharp.Views.Forms")] [assembly: AssemblyProduct("SkiaSharp.Views.Forms")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: NeutralResourcesLanguage("en")] [assembly: NeutralResourcesLanguage("en")]

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

@ -4,7 +4,7 @@ using System.Resources;
[assembly: AssemblyTitle("SkiaSharp.Views")] [assembly: AssemblyTitle("SkiaSharp.Views")]
[assembly: AssemblyDescription("SkiaSharp Views & Layers are a set of platform-specific views and containers that can be used to draw on the screen.")] [assembly: AssemblyDescription("SkiaSharp Views & Layers are a set of platform-specific views and containers that can be used to draw on the screen.")]
[assembly: AssemblyCompany("Xamarin Inc.")] [assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("SkiaSharp.Views")] [assembly: AssemblyProduct("SkiaSharp.Views")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: NeutralResourcesLanguage("en")] [assembly: NeutralResourcesLanguage("en")]

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

@ -4,7 +4,7 @@ using System.Resources;
[assembly: AssemblyTitle("SkiaSharp.Workbooks")] [assembly: AssemblyTitle("SkiaSharp.Workbooks")]
[assembly: AssemblyDescription("SkiaSharp.Workbooks adds functionality for SkiaSharp to Xamarin.Workbooks.")] [assembly: AssemblyDescription("SkiaSharp.Workbooks adds functionality for SkiaSharp to Xamarin.Workbooks.")]
[assembly: AssemblyCompany("Xamarin Inc.")] [assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("SkiaSharp.Workbooks")] [assembly: AssemblyProduct("SkiaSharp.Workbooks")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] [assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: NeutralResourcesLanguage("en")] [assembly: NeutralResourcesLanguage("en")]

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

@ -26,21 +26,21 @@
<Content Include="..\Content\**\*" Link="%(RecursiveDir)%(FileName)%(Extension)" CopyToOutputDirectory="Always" /> <Content Include="..\Content\**\*" Link="%(RecursiveDir)%(FileName)%(Extension)" CopyToOutputDirectory="Always" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.dll" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\windows\x64\libSkiaSharp.dll" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.dll') or '$(IsWindows)' == 'true' " /> Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.dll') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\windows\x64\libSkiaSharp.pdb" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\windows\x64\libSkiaSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.pdb') or '$(IsWindows)' == 'true' " /> Condition=" Exists('..\..\output\native\windows\x64\libSkiaSharp.pdb') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.dll" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.dll" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.dll') or '$(IsWindows)' == 'true' " /> Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.dll') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.pdb" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\windows\x64\libHarfBuzzSharp.pdb" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.pdb') or '$(IsWindows)' == 'true' " /> Condition=" Exists('..\..\output\native\windows\x64\libHarfBuzzSharp.pdb') or '$(IsWindows)' == 'true' " />
<Content Include="..\..\output\native\osx\libSkiaSharp.dylib" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\osx\libSkiaSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\osx\libSkiaSharp.dylib') or '$(IsMacOS)' == 'true' " /> Condition=" Exists('..\..\output\native\osx\libSkiaSharp.dylib') or '$(IsMacOS)' == 'true' " />
<Content Include="..\..\output\native\osx\libHarfBuzzSharp.dylib" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\osx\libHarfBuzzSharp.dylib" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\osx\libHarfBuzzSharp.dylib') or '$(IsMacOS)' == 'true' " /> Condition=" Exists('..\..\output\native\osx\libHarfBuzzSharp.dylib') or '$(IsMacOS)' == 'true' " />
<Content Include="..\..\output\native\linux\x64\libSkiaSharp.so" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\linux\x64\libSkiaSharp.so" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\linux\x64\libSkiaSharp.so') or '$(IsLinux)' == 'true' " /> Condition=" Exists('..\..\output\native\linux\x64\libSkiaSharp.so') or '$(IsLinux)' == 'true' " />
<Content Include="..\..\output\native\linux\x64\libHarfBuzzSharp.so" CopyToOutputDirectory="Always" <Content Include="..\..\output\native\linux\x64\libHarfBuzzSharp.so" CopyToOutputDirectory="Always" Visible="false"
Condition=" Exists('..\..\output\native\linux\x64\libHarfBuzzSharp.so') or '$(IsLinux)' == 'true' " /> Condition=" Exists('..\..\output\native\linux\x64\libHarfBuzzSharp.so') or '$(IsLinux)' == 'true' " />
</ItemGroup> </ItemGroup>
</Project> </Project>

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

@ -506,6 +506,18 @@ namespace SkiaSharp.Tests
Assert.Same(tf1, tf2); Assert.Same(tf1, tf2);
} }
[SkippableFact]
public unsafe void FontStyleIsNotTheSame()
{
var tf = SKTypeface.FromFamilyName(DefaultFontFamily);
var fs1 = tf.FontStyle;
var fs2 = tf.FontStyle;
Assert.NotSame(fs1, fs2);
Assert.NotEqual(fs1.Handle, fs2.Handle);
}
[SkippableFact] [SkippableFact]
public unsafe void FromFamilyDisposeDoesNotDispose() public unsafe void FromFamilyDisposeDoesNotDispose()
{ {