Added support for one SKObject to belong to another:

- used when ownership is transferred in native code
 - fixed instance where stream was disposed when in use by typeface
This commit is contained in:
Matthew Leibowitz 2016-06-08 02:58:12 +02:00
Родитель 444517c1d3
Коммит 8a6384bd8a
3 изменённых файлов: 32 добавлений и 16 удалений

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

@ -92,7 +92,12 @@ namespace SkiaSharp
}
public SKManagedStream (Stream managedStream, bool disposeManagedStream)
: base (SkiaApi.sk_managedstream_new (), true)
: this (managedStream, disposeManagedStream, true)
{
}
private SKManagedStream (Stream managedStream, bool disposeManagedStream, bool owns)
: base (SkiaApi.sk_managedstream_new (), owns)
{
if (Handle == IntPtr.Zero) {
throw new InvalidOperationException ("Unable to create a new SKManagedStream instance.");
@ -240,7 +245,8 @@ namespace SkiaSharp
private static IntPtr CreateNewInternal (IntPtr managedStreamPtr)
{
var managedStream = AsManagedStream (managedStreamPtr);
var newStream = new SKManagedStream (managedStream.stream);
var newStream = new SKManagedStream (managedStream.stream, false, false);
managedStream.TakeOwnership (newStream);
return newStream.Handle;
}
#if __IOS__

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

@ -19,6 +19,7 @@ namespace SkiaSharp
{
private static readonly Dictionary<IntPtr, WeakReference> instances = new Dictionary<IntPtr, WeakReference>();
private readonly List<SKObject> ownedObjects = new List<SKObject>();
private IntPtr handle;
[Preserve]
@ -37,11 +38,7 @@ namespace SkiaSharp
~SKObject()
{
var h = handle;
Dispose(false);
DeregisterHandle(h, this);
}
protected bool OwnsHandle { get; private set; }
@ -58,21 +55,23 @@ namespace SkiaSharp
public void Dispose()
{
var h = handle;
Dispose(true);
if (h != IntPtr.Zero)
{
DeregisterHandle(h, this);
handle = IntPtr.Zero;
}
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
lock (ownedObjects)
{
foreach (var child in ownedObjects)
{
child.Dispose();
}
ownedObjects.Clear();
}
DeregisterHandle(handle, this);
handle = IntPtr.Zero;
}
internal static TSkiaObject GetObject<TSkiaObject>(IntPtr handle)
@ -170,5 +169,14 @@ namespace SkiaSharp
}
}
}
internal void TakeOwnership(SKObject obj)
{
lock (ownedObjects)
{
ownedObjects.Add(obj);
}
obj.OwnsHandle = false;
}
}
}

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

@ -53,7 +53,9 @@ namespace SkiaSharp
{
if (stream == null)
throw new ArgumentNullException ("stream");
return GetObject<SKTypeface> (SkiaApi.sk_typeface_create_from_stream (stream.Handle, index));
var typeface = GetObject<SKTypeface> (SkiaApi.sk_typeface_create_from_stream (stream.Handle, index));
typeface?.TakeOwnership (stream);
return typeface;
}
public int CountGlyphs (string str)