Browse Source

Deleted a bunch of obsolete files, addressed all of the code styling comments, etc.

pull/506/head
Jason Jarvis 11 years ago
parent
commit
2c7d457057
  1. 42
      samples/TestApplicationShared/App.cs
  2. 53
      src/Skia/Perspex.Skia.Android/AndroidRenderTarget.cs
  3. 26
      src/Skia/Perspex.Skia.iOS/SkiaView.cs
  4. 23
      src/Skia/Perspex.Skia.iOS/iOSMethodTable.cs
  5. 27
      src/Skia/Perspex.Skia/DrawingContextImpl.cs
  6. 72
      src/Skia/Perspex.Skia/FormattedTextImpl.cs
  7. 240
      src/Skia/Perspex.Skia/MethodTable.cs
  8. 115
      src/Skia/Perspex.Skia/NativeBrush.cs
  9. 12
      src/Skia/Perspex.Skia/NativeDrawingContextSettings.cs
  10. 27
      src/Skia/Perspex.Skia/NativeFormattedText.cs
  11. 1
      src/Skia/Perspex.Skia/Perspex.Skia.projitems
  12. 110
      src/Skia/Perspex.Skia/PerspexHandleHolder.cs
  13. 24
      src/Skia/Perspex.Skia/PlatformRenderInterface.cs
  14. 13
      src/Skia/Perspex.Skia/RenderTarget.cs
  15. 31
      src/Skia/Perspex.Skia/SkRect.cs
  16. 5
      src/Skia/Perspex.Skia/SkiaPlatform.cs
  17. 33
      src/Skia/Perspex.Skia/SkiaPoint.cs
  18. 11
      src/Skia/Perspex.Skia/StreamGeometryImpl.cs
  19. 21
      src/Skia/Perspex.Skia/WindowDrawingContextImpl.cs
  20. 7
      src/Skia/Perspex.Skia/readme.md
  21. 18
      src/Windows/Perspex.Win32/SystemDialogImpl.cs
  22. 2
      src/iOS/Perspex.iOS/Perspex.iOS.csproj
  23. 77
      src/iOS/Perspex.iOS/PerspexAppDelegate.cs
  24. 30
      src/iOS/Perspex.iOS/PerspexView.cs
  25. 33
      src/iOS/Perspex.iOS/WindowingPlatformImpl.cs
  26. 41
      src/iOS/Perspex.iOS/iOSPlatform.cs
  27. 56
      src/iOS/Perspex.iOSTestApplication/AppDelegate.cs

42
samples/TestApplicationShared/App.cs

@ -11,6 +11,7 @@ using Perspex.Themes.Default;
using Perspex.Diagnostics;
using Perspex.Platform;
using Perspex.Shared.PlatformSupport;
using Perspex.Media;
namespace TestApplication
{
@ -43,10 +44,49 @@ namespace TestApplication
};
MainWindow.RootNamespace = "TestApplication";
var wnd = MainWindow.Create();
var wnd = MainWindow.Create();
wnd.AttachDevTools();
Run(wnd);
}
// This provides a simple UI tree for testing input handling, drawing, etc
public static Window CreateSimpleWindow()
{
Window window = new Window
{
Title = "Perspex Test Application",
Background = Brushes.Red,
Content = new StackPanel
{
Margin = new Thickness(30),
Background = Brushes.Yellow,
Children = new Controls
{
new TextBlock
{
Text = "TEXT BLOCK",
Width = 300,
Height = 40,
Background = Brushes.White,
Foreground = Brushes.Black
},
new Button
{
Content = "BUTTON",
Width = 150,
Height = 40,
Background = Brushes.LightGreen,
Foreground = Brushes.Black
}
}
}
};
return window;
}
}
}

53
src/Skia/Perspex.Skia.Android/AndroidRenderTarget.cs

@ -14,54 +14,11 @@ using Perspex.Platform;
namespace Perspex.Skia
{
/* This lives in shared project now, but we may need an android specific implementation anyways
*
class RenderTarget : IRenderTarget
/// <summary>
/// We will likely need platform specific pieces to support HW acceleration
/// so leaving this class here for now as placeholder.
/// </summary>
internal partial class RenderTarget : IRenderTarget
{
private IntPtr _currentRenderTarget = IntPtr.Zero;
private Surface _currentSurface = null;
private SurfaceView _view = null;
public RenderTarget(IPlatformHandle handle)
{
_view = (SurfaceView) handle;
}
public void Dispose()
{
if (_currentRenderTarget != IntPtr.Zero)
{
MethodTable.Instance.DisposeRenderTarget(_currentRenderTarget);
_currentRenderTarget = IntPtr.Zero;
GC.SuppressFinalize(this);
}
}
~RenderTarget()
{
Dispose();
}
public DrawingContext CreateDrawingContext()
{
var surface = _view.Holder.Surface;
if (surface == null)
throw new InvalidOperationException("Surface isn't available");
if (_currentSurface != surface)
{
_currentSurface = null;
if (_currentRenderTarget != IntPtr.Zero)
{
MethodTable.Instance.DisposeRenderTarget(_currentRenderTarget);
_currentRenderTarget = IntPtr.Zero;
}
_currentRenderTarget = MethodTable.Instance.CreateWindowRenderTarget(surface.Handle);
_currentSurface = surface;
}
return new DrawingContext(
new DrawingContextImpl(MethodTable.Instance.RenderTargetCreateRenderingContext(_currentRenderTarget)));
}
}
*/
}

26
src/Skia/Perspex.Skia.iOS/SkiaView.cs

@ -15,35 +15,25 @@ using UIKit;
namespace Perspex.Skia.iOS
{
public abstract class SkiaView : UIView //GLKView
// TODO: This implementation will be revised as part of HW acceleration work
// and we may use the GLKView as a base for the implementation.
//
public abstract class SkiaView : UIView
{
//[DllImport("__Internal")]
//static extern IntPtr GetPerspexEAGLContext();
bool _drawQueued;
//CADisplayLink _link;
static EAGLContext GetContext()
{
/* No longer needed with SkiaSharp, but require a variant for HW accel
//Ensure initialization
MethodTable.Instance.SetOption((MethodTable.Option)0x10009999, IntPtr.Zero);
var ctx = GetPerspexEAGLContext();
var rv = Runtime.GetNSObject<EAGLContext>(ctx);
rv.DangerousRetain();
return rv;
*/
return null;
}
protected SkiaView(Action<Action> registerFrame) : base(UIScreen.MainScreen.ApplicationFrame) //, GetContext())
protected SkiaView(Action<Action> registerFrame) : base(UIScreen.MainScreen.ApplicationFrame)
{
registerFrame(OnFrame);
}
protected SkiaView() : base(UIScreen.MainScreen.ApplicationFrame) //, GetContext())
protected SkiaView() : base(UIScreen.MainScreen.ApplicationFrame)
{
//(_link = CADisplayLink.Create(() => OnFrame())).AddToRunLoop(NSRunLoop.Main, NSRunLoop.NSDefaultRunLoopMode);
}
protected void OnFrame()
@ -51,10 +41,6 @@ namespace Perspex.Skia.iOS
if (_drawQueued)
{
_drawQueued = false;
// GLKView
//Display();
this.SetNeedsDisplay();
}
}

23
src/Skia/Perspex.Skia.iOS/iOSMethodTable.cs

@ -1,23 +0,0 @@
using System;
using System.Runtime.InteropServices;
using ObjCRuntime;
/* No longer needed with SkiaSharp
[assembly: LinkWith("Perspex.Skia.iOS.libperspesk_standalone.a", ForceLoad = true, SmartLink = true, IsCxx = true, Frameworks = "ImageIO MobileCoreServices CoreText")]
namespace Perspex.Skia
{
class MethodTableImpl : MethodTable
{
[DllImport("__Internal")]
static extern IntPtr GetPerspexMethodTable();
public MethodTableImpl() : base(GetPerspexMethodTable())
{
}
}
}
*/

27
src/Skia/Perspex.Skia/DrawingContextImpl.cs

@ -2,13 +2,12 @@
using System.Collections.Generic;
using Perspex.Media;
using Perspex.Media.Imaging;
using Perspex.RenderHelpers;
using SkiaSharp;
using System.Linq;
namespace Perspex.Skia
{
unsafe class DrawingContextImpl : IDrawingContextImpl
internal class DrawingContextImpl : IDrawingContextImpl
{
public SKCanvas Canvas { get; private set; }
@ -160,6 +159,8 @@ namespace Perspex.Skia
paint.StrokeMiter = (float)pen.MiterLimit;
// TODO: Implement Dash Style support
//
//if (pen.DashStyle?.Dashes != null)
//{
// var dashes = pen.DashStyle.Dashes;
@ -191,7 +192,7 @@ namespace Perspex.Skia
}
else
{
// DrawRRect is not accesible in SkiaSharp yet. We should add that
// TODO: DrawRRect (ore DrawRoundedRect) is not accesible in SkiaSharp yet. We should add that
// to SkiaSharp and initiate a PR....
Canvas.DrawRect(rc, paint);
//Canvas.DrawRoundedRect(rc, cornerRadius, cornerRadius, paint);
@ -210,7 +211,7 @@ namespace Perspex.Skia
}
else
{
// this does not appear to exist in SkiaSharp?
// TODO: this does not exist in SkiaSharp yet
//throw new NotImplementedException();
//Canvas.DrawRoundedRect(rc, cornerRadius, cornerRadius, paint);
Canvas.DrawRect(rc, paint);
@ -271,22 +272,4 @@ namespace Perspex.Skia
}
}
}
// not sure we need this yet
internal class WindowDrawingContextImpl : DrawingContextImpl
{
WindowRenderTarget _target;
public WindowDrawingContextImpl(WindowRenderTarget target)
: base(target.Surface.Canvas)
{
_target = target;
}
public override void Dispose()
{
base.Dispose();
_target.Present();
}
}
}

72
src/Skia/Perspex.Skia/FormattedTextImpl.cs

@ -22,7 +22,7 @@ namespace Perspex.Skia
Paint.IsAntialias = true;
LineOffset = 0;
//Replace 0 characters with zero-width spaces (200B)
// Replace 0 characters with zero-width spaces (200B)
_text = _text.Replace((char)0, (char)0x200B);
}
@ -108,16 +108,9 @@ namespace Perspex.Skia
public void SetForegroundBrush(IBrush brush, int startIndex, int length)
{
// Is this method even relevant now???
//
//var scb = brush as SolidColorBrush;
//if (scb != null)
//{
// Layout.Attributes.Insert(brushAttr);
//}
// TODO: we need an implementation here to properly support FormattedText
}
void Rebuild()
{
var length = _text.Length;
@ -164,20 +157,13 @@ namespace Perspex.Skia
subString = _text.Substring(curOff);
// TODO: This method is not linking into SkiaSharp so we must use the RAW buffer version
// TODO: This method is not linking into SkiaSharp so we must use the RAW buffer version for now
//measured = (int)Paint.BreakText(subString, constraint, out lineWidth) / 2;
bytes = Encoding.UTF8.GetBytes(subString);
pinnedArray = GCHandle.Alloc(bytes, GCHandleType.Pinned);
pointer = pinnedArray.AddrOfPinnedObject();
// for some reason I have to pass nBytes * 2
// for some reason I have to pass nBytes * 2. I assume under the hood it expects Unicode/WChar??
measured = (int)Paint.BreakText(pointer, (IntPtr)(bytes.Length * 2), constraint, out lineWidth) / 2;
// some weird unicode byte issue again
//if(subString.Length % 2 == 1)
//{
// measured -= 1;
//}
pinnedArray.Free();
if (measured == 0)
@ -192,20 +178,17 @@ namespace Perspex.Skia
if (nextChar != ' ')
{
//Perform scan for the last space and end the line there
// Perform scan for the last space and end the line there
for (int si = curOff + measured - 1; si > curOff; si--)
{
if (_text[si] == ' ')
{
measured = si - curOff;
extraSkip = 1;
//Rects[si] = SkRect();
break;
}
}
}
}
PerspexFormattedTextLine line = new PerspexFormattedTextLine();
@ -218,7 +201,7 @@ namespace Perspex.Skia
if (line.Width < 0)
line.Width = _skiaRects[line.Start + line.Length - 1].Right;
//Build character rects
// Build character rects
for (int i = line.Start; i < line.Start + line.Length; i++)
{
float prevRight = 0;
@ -241,7 +224,13 @@ namespace Perspex.Skia
_skiaLines.Add(line);
curY += lineHeight; // + mLeading;
curY += lineHeight;
// TODO: We may want to consider adding Leading to the vertical line spacing but for now
// it appears to make no difference. Revisit as part of FormattedText improvements.
//
//curY += mLeading;
curOff += measured + extraSkip;
}
@ -260,10 +249,14 @@ namespace Perspex.Skia
}
for (var c = 0; c < _text.Length; c++)
{
_rects.Add(_skiaRects[c].ToPerspexRect());
}
if (_skiaLines.Count == 0)
{
_size = new Size();
}
else
{
var lastLine = _skiaLines[_skiaLines.Count - 1];
@ -275,38 +268,37 @@ namespace Perspex.Skia
{
SKPaint paint = Paint;
/* This originated from Native code, it might be useful
//Debugging code for character positions
/* TODO: This originated from Native code, it might be useful for debugging character positions as
* we improve the FormattedText support. Will need to port this to C# obviously. Rmove when
* not needed anymore.
SkPaint dpaint;
ctx->Canvas->save();
ctx->Canvas->translate(origin.fX, origin.fY);
for (int c = 0; c < Lines.size(); c++)
{
dpaint.setARGB(255, 0, 0, 0);
SkRect rc;
rc.fLeft = 0;
rc.fTop = Lines[c].Top;
rc.fRight = Lines[c].Width;
rc.fBottom = rc.fTop + LineOffset;
ctx->Canvas->drawRect(rc, dpaint);
dpaint.setARGB(255, 0, 0, 0);
SkRect rc;
rc.fLeft = 0;
rc.fTop = Lines[c].Top;
rc.fRight = Lines[c].Width;
rc.fBottom = rc.fTop + LineOffset;
ctx->Canvas->drawRect(rc, dpaint);
}
for (int c = 0; c < Length; c++)
{
dpaint.setARGB(255, c % 10 * 125 / 10 + 125, (c * 7) % 10 * 250 / 10, (c * 13) % 10 * 250 / 10);
dpaint.setStyle(SkPaint::kFill_Style);
ctx->Canvas->drawRect(Rects[c], dpaint);
dpaint.setARGB(255, c % 10 * 125 / 10 + 125, (c * 7) % 10 * 250 / 10, (c * 13) % 10 * 250 / 10);
dpaint.setStyle(SkPaint::kFill_Style);
ctx->Canvas->drawRect(Rects[c], dpaint);
}
ctx->Canvas->restore();
*/
// These seems to vertically align the text properly
var yOffset = (LineOffset); // + 1) / 2;
for (int c = 0; c < _skiaLines.Count; c++)
{
PerspexFormattedTextLine line = _skiaLines[c];
var subString = _text.Substring(line.Start, line.Length);
canvas.DrawText(subString, origin.X, origin.Y + line.Top + yOffset, paint);
canvas.DrawText(subString, origin.X, origin.Y + line.Top + LineOffset, paint);
}
}

240
src/Skia/Perspex.Skia/MethodTable.cs

@ -1,240 +0,0 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Perspex.Media;
// ReSharper disable InconsistentNaming
namespace Perspex.Skia
{
/* No longer needed with SkiaSharp
unsafe abstract class MethodTable
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _CreateWindowRenderTarget(IntPtr nativeHandle);
public _CreateWindowRenderTarget CreateWindowRenderTarget;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _RenderTargetCreateRenderingContext(IntPtr target);
public _RenderTargetCreateRenderingContext RenderTargetCreateRenderingContext;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DisposeRenderTarget(IntPtr target);
public _DisposeRenderTarget DisposeRenderTarget;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DisposeRenderingContext(IntPtr ctx);
public _DisposeRenderingContext DisposeRenderingContext;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DrawRectangle(IntPtr ctx, void* brush, ref SkRect rect, float borderRadius);
public _DrawRectangle DrawRectangle;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _PushClip(IntPtr ctx, ref SkRect rect);
public _PushClip PushClip;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _PopClip(IntPtr ctx);
public _PopClip PopClip;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _SetTransform(IntPtr ctx, void* matrix6);
public _SetTransform SetTransformNative;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DrawLine(IntPtr ctx, void* brush, float x1, float y1, float x2, float y2);
public _DrawLine DrawLine;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _CreatePath(SkiaGeometryElement[] elements, int count, out SkRect bounds);
public _CreatePath CreatePath;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DisposePath(IntPtr handle);
public _DisposePath DisposePath;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _TransformPath(IntPtr path, void* matrix6);
public _TransformPath TransformPathNative;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DrawGeometry(IntPtr ctx, IntPtr path, void* fill, void* stroke, bool useEvenOdd);
public _DrawGeometry DrawGeometry;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DestroySkData(IntPtr handle);
public _DestroySkData DestroySkData;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate bool _LoadImage(byte[] data, int len, out IntPtr image, out int width, out int height);
public _LoadImage LoadImage;
public enum SkiaImageType
{
Png,Gif,Jpeg
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _SaveImage(IntPtr image, SkiaImageType type, int quality);
public _SaveImage SaveImage;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DrawImage(IntPtr ctx, IntPtr image, float opacity, ref SkRect srcRect, ref SkRect destRect);
public _DrawImage DrawImage;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _CreateRenderTargetBitmap(int width, int height);
public _CreateRenderTargetBitmap CreateRenderTargetBitmap;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DisposeImage(IntPtr image);
public _DisposeImage DisposeImage;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int _GetSkDataSize(IntPtr data);
public _GetSkDataSize GetSkDataSize;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _ReadSkData(IntPtr data, byte[] buffer, int count);
public _ReadSkData ReadSkData;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate NativeDrawingContextSettings* _GetDrawingContextSettingsPtr(IntPtr ctx);
public _GetDrawingContextSettingsPtr GetDrawingContextSettingsPtr;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _CreateTypeface(void* name, int style);
public _CreateTypeface CreateTypeface;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr _CreateFormattedText(void*utf16, int len, IntPtr typeface, float fontSize, TextAlignment align, NativeFormattedText** shared);
public _CreateFormattedText CreateFormattedText;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _RebuildFormattedText(IntPtr handle);
public _RebuildFormattedText RebuildFormattedText;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DestroyFormattedText(IntPtr handle);
public _DestroyFormattedText DestroyFormattedText;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _DrawFormattedText(IntPtr ctx, void* brush, IntPtr text, float x, float y);
public _DrawFormattedText DrawFormattedText;
public enum Option
{
ForceSoftware = 0
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void _SetOption(Option option, IntPtr value);
public _SetOption SetOption;
private static readonly Type[] TableOrder = new Type[]
{
typeof (_CreateWindowRenderTarget),
typeof (_DisposeRenderTarget),
typeof (_RenderTargetCreateRenderingContext),
typeof (_DisposeRenderingContext),
typeof (_DrawRectangle),
typeof (_PushClip),
typeof (_PopClip),
typeof (_SetTransform),
typeof (_DrawLine),
typeof (_CreatePath),
typeof (_DisposePath),
typeof (_DrawGeometry),
typeof (_GetSkDataSize),
typeof (_ReadSkData),
typeof (_DestroySkData),
typeof (_LoadImage),
typeof (_SaveImage),
typeof (_DrawImage),
typeof (_CreateRenderTargetBitmap),
typeof (_DisposeImage),
typeof (_GetDrawingContextSettingsPtr),
typeof (_CreateTypeface),
typeof (_CreateFormattedText),
typeof (_RebuildFormattedText),
typeof (_DestroyFormattedText),
typeof (_DrawFormattedText),
typeof (_SetOption),
typeof (_TransformPath)
};
void ConvertMatrix(Matrix value, float* target)
{
target[0] = (float)value.M11;
target[1] = (float)value.M21;
target[2] = (float)value.M31;
target[3] = (float)value.M12;
target[4] = (float)value.M22;
target[5] = (float)value.M32;
}
public unsafe IntPtr TransformPath(IntPtr path, Matrix matrix)
{
var tmp = stackalloc float[6];
ConvertMatrix(matrix, tmp);
return TransformPathNative(path, tmp);
}
public unsafe void SetTransform(IntPtr ctx, Matrix matrix)
{
var tmp = stackalloc float[6];
ConvertMatrix(matrix, tmp);
SetTransformNative(ctx, tmp);
}
protected MethodTable(IntPtr methodTable)
{
var dic = typeof (MethodTable).GetFields().ToDictionary(f => f.FieldType, f => f);
for (var c = 0; c < TableOrder.Length; c++)
{
IntPtr pMethod = Marshal.ReadIntPtr(methodTable, IntPtr.Size*c);
var t = TableOrder[c];
dic[t].SetValue(this, Marshal.GetDelegateForFunctionPointer(pMethod, t));
}
}
public static readonly MethodTable Instance = new MethodTableImpl();
}
*/
}

115
src/Skia/Perspex.Skia/NativeBrush.cs

@ -1,115 +0,0 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Perspex.Media;
namespace Perspex.Skia
{
/* No longer needed with SkiaSharp
internal enum NativeBrushType
{
Solid,
LinearGradient,
RadialGradient,
Image
}
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct NativeBrush
{
public const int MaxGradientStops = 1024;
public const int MaxDashCount = 1024;
public NativeBrushType Type;
public double Opacity;
public uint Color;
//Strokes
public bool Stroke;
public float StrokeThickness;
public PenLineJoin StrokeLineJoin;
public float StrokeMiterLimit;
public int StrokeDashCount;
public float StrokeDashOffset;
public PenLineCap StrokeLineCap;
//Gradients
public int GradientStopCount;
public GradientSpreadMethod GradientSpreadMethod;
public SkiaPoint GradientStartPoint, GradientEndPoint;
public float GradientRadius;
//Image Brush
public IntPtr Bitmap;
public TileMode BitmapTileMode;
public SkiaPoint BitmapTranslation;
//Blobs
public fixed uint GradientStopColors [MaxGradientStops];
public fixed float GradientStops [MaxGradientStops];
public fixed float StrokeDashes [MaxDashCount];
public void Reset()
{
Type = NativeBrushType.Solid;
Opacity = 1f;
Color = 0;
Stroke = false;
StrokeThickness = 1;
GradientStopCount = 0;
StrokeDashCount = 0;
StrokeLineCap = PenLineCap.Flat;
}
}
unsafe class NativeBrushContainer : IDisposable
{
private readonly NativeBrushPool _pool;
public NativeBrush* Brush;
readonly List<IDisposable> _disposables = new List<IDisposable>();
public NativeBrushContainer(NativeBrushPool pool)
{
_pool = pool;
Brush = (NativeBrush*) Marshal.AllocHGlobal(Marshal.SizeOf(typeof (NativeBrush))).ToPointer();
Brush->Reset();
}
public void AddDisposable(IDisposable disp)
{
_disposables.Add(disp);
}
public void Dispose()
{
foreach (var disp in _disposables)
disp.Dispose();
_disposables.Clear();
Brush->Reset();
_pool?.Return(this);
}
}
class NativeBrushPool
{
public static NativeBrushPool Instance { get; } = new NativeBrushPool();
readonly Stack<NativeBrushContainer> _pool = new Stack<NativeBrushContainer>();
public void Return(NativeBrushContainer c)
{
_pool.Push(c);
}
public NativeBrushContainer Get()
{
if (_pool.Count == 0)
return new NativeBrushContainer(this);
return _pool.Pop();
}
}
*/
}

12
src/Skia/Perspex.Skia/NativeDrawingContextSettings.cs

@ -1,12 +0,0 @@
using System.Runtime.InteropServices;
/* No longer needed with SkiaSharp
namespace Perspex.Skia
{
[StructLayout(LayoutKind.Sequential)]
struct NativeDrawingContextSettings
{
public double Opacity;
}
}
*/

27
src/Skia/Perspex.Skia/NativeFormattedText.cs

@ -1,27 +0,0 @@
using System.Runtime.InteropServices;
/* No longer needed with SkiaSharp
namespace Perspex.Skia
{
[StructLayout(LayoutKind.Sequential)]
unsafe struct NativeFormattedText
{
public float WidthConstraint;
public int LineCount;
public NativeFormattedTextLine* Lines;
public SkRect* Bounds;
};
[StructLayout(LayoutKind.Sequential)]
unsafe struct NativeFormattedTextLine
{
public float Top;
public int Start;
public int Length;
public float Height;
public float Width;
};
}
*/

1
src/Skia/Perspex.Skia/Perspex.Skia.projitems

@ -18,6 +18,7 @@
<Compile Include="$(MSBuildThisFileDirectory)SkiaSharpExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)StreamGeometryImpl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TypefaceCache.cs" />
<Compile Include="$(MSBuildThisFileDirectory)WindowDrawingContextImpl.cs" />
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)readme.md" />

110
src/Skia/Perspex.Skia/PerspexHandleHolder.cs

@ -1,110 +0,0 @@
using System;
/* No longer needed with SkiaSharp
namespace Perspex.Skia
{
abstract class PerspexHandleHolder : IDisposable
{
private readonly IntPtr _handle;
public IntPtr Handle
{
get
{
CheckDisposed();
return _handle;
}
}
public bool IsDisposed { get; private set; }
public void CheckDisposed()
{
if (IsDisposed)
throw new ObjectDisposedException(GetType().FullName);
}
protected PerspexHandleHolder(IntPtr handle)
{
_handle = handle;
}
protected abstract void Delete(IntPtr handle);
public void Dispose()
{
if(IsDisposed)
return;
IsDisposed = true;
Delete(_handle);
GC.SuppressFinalize(this);
}
~PerspexHandleHolder()
{
Dispose();
}
}
class RefCountable<T> : IDisposable where T : PerspexHandleHolder
{
class Shared
{
public readonly T Target;
private int _refCount = 1;
public Shared(T target)
{
Target = target;
}
public void AddRef() => _refCount++;
public void Release()
{
_refCount--;
if (_refCount <= 0)
Target.Dispose();
}
}
public bool IsDisposed => _shared == null;
private Shared _shared;
public void CheckDisposed()
{
if (IsDisposed)
throw new ObjectDisposedException(GetType().FullName);
}
public IntPtr Handle
{
get
{
CheckDisposed();
return _shared.Target.Handle;
}
}
public RefCountable(T handle)
{
_shared = new Shared(handle);
}
public RefCountable(RefCountable<T> other)
{
other._shared.Target.CheckDisposed();
other._shared.AddRef();
_shared = other._shared;
}
public RefCountable<T> Clone() => new RefCountable<T>(this);
public void Dispose()
{
_shared?.Release();
_shared = null;
}
}
}
*/

24
src/Skia/Perspex.Skia/PlatformRenderInterface.cs

@ -30,16 +30,16 @@ namespace Perspex.Skia
IBitmapImpl LoadBitmap(byte[] data)
{
var bitmap = new SKBitmap();
if(!SKImageDecoder.DecodeMemory(data, bitmap))
{
throw new ArgumentException("Unable to load bitmap from provided data");
}
var bitmap = new SKBitmap();
if (!SKImageDecoder.DecodeMemory(data, bitmap))
{
throw new ArgumentException("Unable to load bitmap from provided data");
}
return new BitmapImpl(bitmap);
}
return new BitmapImpl(bitmap);
}
public IBitmapImpl LoadBitmap(System.IO.Stream stream)
public IBitmapImpl LoadBitmap(System.IO.Stream stream)
{
using (var sr = new BinaryReader(stream))
{
@ -62,9 +62,9 @@ namespace Perspex.Skia
return new BitmapImpl(width, height);
}
public IRenderTarget CreateRenderer(IPlatformHandle handle)
{
return new WindowRenderTarget(handle.Handle);
}
public IRenderTarget CreateRenderer(IPlatformHandle handle)
{
return new WindowRenderTarget(handle.Handle);
}
}
}

13
src/Skia/Perspex.Skia/RenderTarget.cs

@ -17,22 +17,20 @@ using Perspex.Win32.Interop;
namespace Perspex.Skia
{
internal class RenderTarget : IRenderTarget
internal partial class RenderTarget : IRenderTarget
{
public SKSurface Surface { get; protected set; }
//protected override void Delete(IntPtr handle) => MethodTable.Instance.DisposeRenderTarget(handle);
public virtual DrawingContext CreateDrawingContext()
{
return
new DrawingContext(
new DrawingContextImpl(Surface.Canvas)); // MethodTable.Instance.RenderTargetCreateRenderingContext(Handle)));
new DrawingContextImpl(Surface.Canvas));
}
public void Dispose()
{
//throw new NotImplementedException();
// Nothing to do here.
}
}
@ -69,7 +67,7 @@ namespace Perspex.Skia
}
#endif
void FixSize()
private void FixSize()
{
int width, height;
GetPlatformWindowSize(_hwnd, out width, out height);
@ -91,7 +89,6 @@ namespace Perspex.Skia
_bitmap = new SKBitmap(width, height, SKColorType.N_32, SKAlphaType.Premul);
//bitmap.LockPixels();
IntPtr length;
var pixels = _bitmap.GetPixels(out length);
@ -99,7 +96,7 @@ namespace Perspex.Skia
Surface = SKSurface.Create(_bitmap.Info, pixels, _bitmap.RowBytes);
}
void GetPlatformWindowSize(IntPtr hwnd, out int w, out int h)
private void GetPlatformWindowSize(IntPtr hwnd, out int w, out int h)
{
#if __IOS__
var bounds = GetApplicationFrame();

31
src/Skia/Perspex.Skia/SkRect.cs

@ -1,31 +0,0 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
/* No longer needed with SkiaSharp
namespace Perspex.Skia
{
[StructLayout(LayoutKind.Sequential)]
struct SkRect
{
public float Left, Top, Right, Bottom;
public static SkRect FromRect(Rect rc)
{
return new SkRect()
{
Left = (float) rc.X,
Top = (float) rc.Y,
Right = (float) rc.Right,
Bottom = (float) rc.Bottom
};
}
public Rect ToRect() => new Rect(Left, Top, Right - Left, Bottom - Top);
}
}
*/

5
src/Skia/Perspex.Skia/SkiaPlatform.cs

@ -31,8 +31,9 @@ namespace Perspex.Skia
{
s_forceSoftwareRendering = value;
// Do we still need this with SkiaSharp??
//MethodTable.Instance.SetOption(MethodTable.Option.ForceSoftware, new IntPtr(value ? 1 : 0));
// TODO: I left this property here as place holder. Do we still need the ability to Force software rendering?
// Is it even possible with SkiaSharp? Perhaps kekekes can answer as part of the HW accel work.
//
throw new NotImplementedException();
}
}

33
src/Skia/Perspex.Skia/SkiaPoint.cs

@ -1,33 +0,0 @@
using System.Runtime.InteropServices;
/* No longer needed with SkiaSharp
namespace Perspex.Skia
{
[StructLayout(LayoutKind.Sequential)]
struct SkiaPoint
{
public float X, Y;
public SkiaPoint(float x, float y)
{
X = x;
Y = y;
}
public SkiaPoint(double x, double y)
{
X = (float)x;
Y = (float)y;
}
public SkiaPoint(Point p) : this(p.X, p.Y)
{
}
public static implicit operator SkiaPoint(Point pt) => new SkiaPoint(pt);
}
}
*/

11
src/Skia/Perspex.Skia/StreamGeometryImpl.cs

@ -85,7 +85,6 @@ namespace Perspex.Skia
private readonly StreamGeometryImpl _geometryImpl;
private SKPath _path;
//readonly List<SkiaGeometryElement> _elements = new List<SkiaGeometryElement>();
Point _currentPoint;
public StreamContext(StreamGeometryImpl geometryImpl)
{
@ -95,16 +94,13 @@ namespace Perspex.Skia
public void Dispose()
{
// Not sure what we need to do here....
// //throw new NotImplementedException();
// TODO: Not sure what we need to do here. This code left here for reference.
//
// var arr = _elements.ToArray();
// SkRect rc;
// _path?.Dispose();
// _path = new SKPath(new SkPath(MethodTable.Instance.CreatePath(arr, arr.Length, out rc)));
// _geometryImpl.ApplyTransform();
// _geometryImpl.Bounds = rc.ToRect();
SKRect rc;
@ -116,9 +112,6 @@ namespace Perspex.Skia
public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection)
{
throw new NotImplementedException();
//ArcToHelper.ArcTo(this, _currentPoint, point, size, rotationAngle, isLargeArc, sweepDirection);
//_currentPoint = point;
}
public void BeginFigure(Point startPoint, bool isFilled)

21
src/Skia/Perspex.Skia/WindowDrawingContextImpl.cs

@ -0,0 +1,21 @@

namespace Perspex.Skia
{
// not sure we need this yet
internal class WindowDrawingContextImpl : DrawingContextImpl
{
WindowRenderTarget _target;
public WindowDrawingContextImpl(WindowRenderTarget target)
: base(target.Surface.Canvas)
{
_target = target;
}
public override void Dispose()
{
base.Dispose();
_target.Present();
}
}
}

7
src/Skia/Perspex.Skia/readme.md

@ -35,7 +35,12 @@ Android
iOS
- Get GLView working again. See HW above
Win32
- Cleanup the unmanaged methods (BITMAPINFO) if possible
General
- Cleanup/eliminate obsolete files
- Finish cleanup of the many Test Applications
- Get Skia Unit Tests passing
- Get Skia Unit Tests passing

18
src/Windows/Perspex.Win32/SystemDialogImpl.cs

@ -40,23 +40,23 @@ namespace Perspex.Win32
var filterBuffer = new char[filters.Length];
filters.CopyTo(0, filterBuffer, 0, filterBuffer.Length);
var defExt = (dialog as SaveFileDialog)?.DefaultExtension.ToArray();
var defExt = (dialog as SaveFileDialog)?.DefaultExtension.ToArray();
var fileBuffer = new char[256];
dialog.InitialFileName?.CopyTo(0, fileBuffer, 0, dialog.InitialFileName.Length);
string userSelectedExt = null;
var title = dialog.Title.ToArray();
var initialDir = dialog.InitialDirectory.ToArray();
var title = dialog.Title.ToArray();
var initialDir = dialog.InitialDirectory.ToArray();
fixed (char* pFileBuffer = fileBuffer)
fixed (char* pFileBuffer = fileBuffer)
fixed (char* pFilterBuffer = filterBuffer)
fixed (char* pDefExt = defExt)
fixed (char* pInitDir = initialDir)
fixed (char* pTitle = title)
{
var ofn = new UnmanagedMethods.OpenFileName()
{
{
hwndOwner = hWnd,
hInstance = IntPtr.Zero,
lCustData = IntPtr.Zero,
@ -124,8 +124,8 @@ namespace Perspex.Win32
!userSelectedExt.Contains("*"))
dir = Path.ChangeExtension(dir, userSelectedExt);
}
return new[] {dir};
return new[] { dir };
}
return files.Select(f => Path.Combine(dir, f)).ToArray();
@ -133,7 +133,7 @@ namespace Perspex.Win32
}
public Task<string> ShowFolderDialogAsync(OpenFolderDialog dialog, IWindowImpl parent)
{
{
return Task.Factory.StartNew(() =>
{
string result = string.Empty;
@ -177,7 +177,7 @@ namespace Perspex.Win32
{
try
{
result = Marshal.PtrToStringAuto(pszString);
result = Marshal.PtrToStringAuto(pszString);
}
finally
{

2
src/iOS/Perspex.iOS/Perspex.iOS.csproj

@ -39,11 +39,11 @@
<Compile Include="Extensions.cs" />
<Compile Include="iOSPlatform.cs" />
<Compile Include="PerspexView.cs" />
<Compile Include="PerspexAppDelegate.cs" />
<Compile Include="PlatformSettings.cs" />
<Compile Include="PlatformThreadingInterface.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Specific\KeyboardEventsHelper.cs" />
<Compile Include="WindowingPlatformImpl.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Perspex.Animation\Perspex.Animation.csproj">

77
src/iOS/Perspex.iOS/PerspexAppDelegate.cs

@ -1,77 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Perspex.Controls.Platform;
using Perspex.Input;
using Perspex.Input.Platform;
using Perspex.Platform;
using Perspex.Shared.PlatformSupport;
using Perspex.Skia;
using UIKit;
/* No Longer needed
namespace Perspex.iOS
{
public class PerspexAppDelegate : UIApplicationDelegate
{
static bool _initialized = false;
internal static MouseDevice MouseDevice;
internal static KeyboardDevice KeyboardDevice;
protected void InitPerspex(Type appType)
{
if(_initialized)
return;
_initialized = true;
var window = new UIWindow(UIScreen.MainScreen.Bounds);
var controller = new PerspexViewController(window);
window.RootViewController = controller;
window.MakeKeyAndVisible();
Application.RegisterPlatformCallback(() =>
{
MouseDevice = new MouseDevice();
KeyboardDevice = new KeyboardDevice();
SharedPlatform.Register(appType.Assembly);
PerspexLocator.CurrentMutable
.Bind<IClipboard>().ToTransient<Clipboard>()
//.Bind<ISystemDialogImpl>().ToTransient<SystemDialogImpl>()
.Bind<IStandardCursorFactory>().ToTransient<CursorFactory>()
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)
.Bind<IMouseDevice>().ToConstant(MouseDevice)
.Bind<IPlatformSettings>().ToSingleton<PlatformSettings>()
.Bind<IPlatformThreadingInterface>().ToConstant(PlatformThreadingInterface.Instance)
.Bind<IWindowingPlatform>().ToConstant(new WindowingPlatform(controller.PerspexView));
SkiaPlatform.Initialize();
});
}
class WindowingPlatform : IWindowingPlatform
{
private readonly IWindowImpl _window;
public WindowingPlatform(IWindowImpl window)
{
_window = window;
}
public IWindowImpl CreateWindow()
{
return _window;
}
public IWindowImpl CreateEmbeddableWindow()
{
throw new NotImplementedException();
}
public IPopupImpl CreatePopup()
{
throw new NotImplementedException();
}
}
}
}
*/

30
src/iOS/Perspex.iOS/PerspexView.cs

@ -57,8 +57,8 @@ namespace Perspex.iOS
(_controller.InterfaceOrientation == UIInterfaceOrientation.LandscapeLeft
|| _controller.InterfaceOrientation == UIInterfaceOrientation.LandscapeRight);
// Bounds here (if top level) needs to correspond with the rendertarget
var frame = UIScreen.MainScreen.Bounds;
// Bounds here (if top level) needs to correspond with the rendertarget
var frame = UIScreen.MainScreen.Bounds;
if (needFlip)
Frame = new CGRect(frame.Y, frame.X, frame.Height, frame.Width);
else
@ -76,14 +76,14 @@ namespace Perspex.iOS
public IPlatformHandle Handle => PerspexPlatformHandle;
public double Scaling
{
get
{
// This does not appear to make any difference, but on iOS we
// have Retina (x2) and we probably want this eventually
return 1; //UIScreen.MainScreen.Scale;
}
}
{
get
{
// This does not appear to make any difference, but on iOS we
// have Retina (x2) and we probably want this eventually
return 1; //UIScreen.MainScreen.Scale;
}
}
public WindowState WindowState
{
@ -169,7 +169,7 @@ namespace Perspex.iOS
Input?.Invoke(new RawMouseEventArgs(
iOSPlatform.MouseDevice,
(uint) touch.Timestamp,
(uint)touch.Timestamp,
_inputRoot,
RawMouseEventType.LeftButtonUp,
location,
@ -185,10 +185,10 @@ namespace Perspex.iOS
{
var location = touch.LocationInView(this).ToPerspex();
_touchLastPoint = location;
Input?.Invoke(new RawMouseEventArgs(iOSPlatform.MouseDevice, (uint) touch.Timestamp, _inputRoot,
Input?.Invoke(new RawMouseEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot,
RawMouseEventType.Move, location, InputModifiers.None));
Input?.Invoke(new RawMouseEventArgs(iOSPlatform.MouseDevice, (uint) touch.Timestamp, _inputRoot,
Input?.Invoke(new RawMouseEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot,
RawMouseEventType.LeftButtonDown, location, InputModifiers.None));
}
}
@ -200,7 +200,7 @@ namespace Perspex.iOS
{
var location = touch.LocationInView(this).ToPerspex();
if (iOSPlatform.MouseDevice.Captured != null)
Input?.Invoke(new RawMouseEventArgs(iOSPlatform.MouseDevice, (uint) touch.Timestamp, _inputRoot,
Input?.Invoke(new RawMouseEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp, _inputRoot,
RawMouseEventType.Move, location, InputModifiers.LeftMouseButton));
else
{
@ -208,7 +208,7 @@ namespace Perspex.iOS
double correction = 0.02;
Input?.Invoke(new RawMouseWheelEventArgs(iOSPlatform.MouseDevice, (uint)touch.Timestamp,
_inputRoot, location, (location - _touchLastPoint)* correction, InputModifiers.LeftMouseButton));
_inputRoot, location, (location - _touchLastPoint) * correction, InputModifiers.LeftMouseButton));
}
_touchLastPoint = location;
}

33
src/iOS/Perspex.iOS/WindowingPlatformImpl.cs

@ -0,0 +1,33 @@
using Perspex.Platform;
using System;
namespace Perspex.iOS
{
// This is somewhat generic, could probably put this elsewhere. But I don't think
// it should part of the iOS App Delegate
//
class WindowingPlatformImpl : IWindowingPlatform
{
private readonly IWindowImpl _window;
public WindowingPlatformImpl(IWindowImpl window)
{
_window = window;
}
public IWindowImpl CreateWindow()
{
return _window;
}
public IWindowImpl CreateEmbeddableWindow()
{
throw new NotImplementedException();
}
public IPopupImpl CreatePopup()
{
throw new NotImplementedException();
}
}
}

41
src/iOS/Perspex.iOS/iOSPlatform.cs

@ -18,8 +18,7 @@ namespace Perspex
return app;
}
// I wish I could merge this with the SkiaPlatform itself. Might be possible
// once we switch to SkiaSharp
// TODO: Can we merge this with UseSkia somehow once HW/platform cleanup is done?
public static AppT UseSkiaViewHost<AppT>(this AppT app) where AppT : Application
{
var window = new UIWindow(UIScreen.MainScreen.Bounds);
@ -28,7 +27,7 @@ namespace Perspex
window.MakeKeyAndVisible();
PerspexLocator.CurrentMutable
.Bind<IWindowingPlatform>().ToConstant(new WindowingPlatform(controller.PerspexView));
.Bind<IWindowingPlatform>().ToConstant(new WindowingPlatformImpl(controller.PerspexView));
SkiaPlatform.Initialize();
@ -40,45 +39,15 @@ namespace Perspex
// Asset loading searches our own assembly?
var loader = new AssetLoader(assembly);
PerspexLocator.CurrentMutable.Bind<IAssetLoader>().ToConstant(loader);
return app;
}
// This is somewhat generic, could probably put this elsewhere. But I don't think
// it should part of the iOS App Delegate
//
class WindowingPlatform : IWindowingPlatform
{
private readonly IWindowImpl _window;
public WindowingPlatform(IWindowImpl window)
{
_window = window;
}
public IWindowImpl CreateWindow()
{
return _window;
}
public IWindowImpl CreateEmbeddableWindow()
{
throw new NotImplementedException();
}
public IPopupImpl CreatePopup()
{
throw new NotImplementedException();
}
}
}
}
namespace Perspex.iOS
{
// TODO: Perhaps we should make this class handle all these interfaces directly, like we
// do for Win32 and Gtk
// do for Win32 and Gtk platforms
//
public class iOSPlatform //: IPlatformThreadingInterface, IPlatformSettings, IWindowingPlatform
{
@ -90,12 +59,10 @@ namespace Perspex.iOS
MouseDevice = new MouseDevice();
KeyboardDevice = new KeyboardDevice();
// refactored
//SharedPlatform.Register(appType.Assembly);
PerspexLocator.CurrentMutable
.Bind<IPclPlatformWrapper>().ToSingleton<PclPlatformWrapper>()
.Bind<IClipboard>().ToTransient<Clipboard>()
// TODO: what does this look like for iOS??
//.Bind<ISystemDialogImpl>().ToTransient<SystemDialogImpl>()
.Bind<IStandardCursorFactory>().ToTransient<CursorFactory>()
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)

56
src/iOS/Perspex.iOSTestApplication/AppDelegate.cs

@ -27,65 +27,17 @@ namespace Perspex.iOSTestApplication
//
public override bool FinishedLaunching(UIApplication uiapp, NSDictionary options)
{
var app = new App();
var app = new App()
.UseiOS()
.UseSkiaViewHost()
.UseSkia();
app.UseiOS();
app.UseSkiaViewHost();
app.UseSkia();
// looking for this URI fails: "TestApplication.github_icon.png"
var asm = typeof(App).Assembly;
app.UseAssetAssembly(asm);
//MainWindow.RootNamespace = "Perspex.iOSTestApplication";
//var window = MainWindow.Create();
////var window = Create();
//window.Show();
//app.Run(window);
app.Run();
return true;
}
// This provides a simple UI tree for testing input handling
public static Window Create()
{
Window window = new Window
{
Title = "Perspex Test Application",
//Width = 900,
//Height = 480,
Background = Brushes.Red,
Content = new StackPanel
{
Margin = new Thickness(30),
Background = Brushes.Yellow,
Children = new Controls.Controls
{
new TextBlock
{
Text = "TEXT BLOCK",
Width = 300,
Height = 40,
Background = Brushes.White,
Foreground = Brushes.Black
},
new Button
{
Content = "BUTTON",
Width = 150,
Height = 40,
Background = Brushes.LightGreen,
Foreground = Brushes.Black
}
}
}
};
return window;
}
}

Loading…
Cancel
Save