Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/Common.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<NoWarn>$(NoWarn);NU5105;CS8981;NETSDK1138;SYSLIB0050;SYSLIB0051</NoWarn>
<LangVersion Condition="$(MSBuildProjectExtension) == '.csproj'">10</LangVersion>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<ValidateXcodeVersion>false</ValidateXcodeVersion>
</PropertyGroup>

<!-- support t4 templates in projects -->
Expand Down
2 changes: 1 addition & 1 deletion lib/monomac
Submodule monomac updated 113 files
15 changes: 4 additions & 11 deletions src/Eto.Mac/CGConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,9 @@ namespace Eto.iOS
{
public static partial class CGConversions
{
static CGColorSpace deviceRGB;
static CGColorSpace colorSpace;

static CGColorSpace CreateDeviceRGB()
{
if (deviceRGB != null)
return deviceRGB;

deviceRGB = CGColorSpace.CreateDeviceRGB();
return deviceRGB;
}
static CGColorSpace CreateColorSpace() => colorSpace ??= CGColorSpace.CreateSrgb();

public static CGColor ToCG(this NSColor color)
{
Expand All @@ -34,7 +27,7 @@ public static CGColor ToCG(this NSColor color)
return cgColor;

// try to convert to RGB colorspace so we can convert it to CGColor
var converted = color.UsingColorSpaceFast(NSColorSpace.DeviceRGB);
var converted = color.UsingColorSpace(NSColorSpace.SRGBColorSpace);
if (converted == null)
return new CGColor(0, 0, 0, 1f);

Expand All @@ -52,7 +45,7 @@ public static CGColor ToCG(this Color color)
return nscolor.ToCG();
if (color.ControlObject is CGColor cgcolor)
return cgcolor;
return new CGColor(CreateDeviceRGB(), new nfloat[] { color.R, color.G, color.B, color.A });
return new CGColor(CreateColorSpace(), new nfloat[] { color.R, color.G, color.B, color.A });
}

public static Color ToEto(this CGColor color)
Expand Down
17 changes: 13 additions & 4 deletions src/Eto.Mac/Drawing/BitmapHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ public void Create(int width, int height, PixelFormat pixelFormat)
const int bytesPerPixel = bitsPerPixel / 8;
int bytesPerRow = bytesPerPixel * width;

rep = bmprep = new NSBitmapImageRep(IntPtr.Zero, width, height, bitsPerComponent, 3, false, false, NSColorSpace.DeviceRGB, bytesPerRow, bitsPerPixel);
var cgimage = new CGBitmapContext(IntPtr.Zero, width, height, bitsPerComponent, bytesPerRow, CGColorSpace.CreateSrgb(), CGBitmapFlags.NoneSkipLast).ToImage();
rep = bmprep = new NSBitmapImageRep(cgimage);
Control = new NSImage();
Control.AddRepresentation(rep);
break;
Expand All @@ -126,8 +127,13 @@ public void Create(int width, int height, PixelFormat pixelFormat)
const int bitsPerPixel = numComponents * bitsPerComponent;
const int bytesPerPixel = bitsPerPixel / 8;
int bytesPerRow = bytesPerPixel * width;

rep = bmprep = new NSBitmapImageRep(IntPtr.Zero, width, height, bitsPerComponent, numComponents, false, false, NSColorSpace.DeviceRGB, bytesPerRow, bitsPerPixel);

// no way to create a CGImage with 24bpp AND there's no way to get the sRGB colorspace name,
// so create NSBitmapImageRep directly then change colorspace to sRGB.
// why oh why apple didn't you make a new version of this API with a colorspace instance vs. name..?
using var tmpbmp = new NSBitmapImageRep(IntPtr.Zero, width, height, bitsPerComponent, numComponents, false, false, NSColorSpace.CalibratedRGB, bytesPerRow, bitsPerPixel);
rep = bmprep = tmpbmp.ConvertingToColorSpace(NSColorSpace.SRGBColorSpace, NSColorRenderingIntent.Default);

Control = new NSImage();
Control.AddRepresentation(rep);
break;
Expand All @@ -140,8 +146,11 @@ public void Create(int width, int height, PixelFormat pixelFormat)
const int bitsPerPixel = numComponents * bitsPerComponent;
const int bytesPerPixel = bitsPerPixel / 8;
int bytesPerRow = bytesPerPixel * width;

var cgimage = new CGBitmapContext(IntPtr.Zero, width, height, bitsPerComponent, bytesPerRow, CGColorSpace.CreateSrgb(), CGBitmapFlags.PremultipliedLast).ToImage();

rep = bmprep = new NSBitmapImageRep(IntPtr.Zero, width, height, bitsPerComponent, numComponents, true, false, NSColorSpace.DeviceRGB, bytesPerRow, bitsPerPixel);
// rep = bmprep = new NSBitmapImageRep(IntPtr.Zero, width, height, bitsPerComponent, numComponents, true, false, NSColorSpace.DeviceRGB, bytesPerRow, bitsPerPixel);
rep = bmprep = new NSBitmapImageRep(cgimage);
Control = new NSImage();
Control.AddRepresentation(rep);
break;
Expand Down
4 changes: 2 additions & 2 deletions src/Eto.Mac/Drawing/LinearGradientBrushHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void Draw(GraphicsHandler graphics, bool stroke, FillMode fillMode, bool
if (wrap == GradientWrapMode.Pad)
{
if (Gradient == null)
Gradient = new CGGradient(CGColorSpace.CreateDeviceRGB(), new [] { StartColor, EndColor }, new nfloat[] { (nfloat)0f, (nfloat)1f });
Gradient = new CGGradient(CGColorSpace.CreateSrgb(), new [] { StartColor, EndColor }, new nfloat[] { (nfloat)0f, (nfloat)1f });
}
else
{
Expand All @@ -86,7 +86,7 @@ public void Draw(GraphicsHandler graphics, bool stroke, FillMode fillMode, bool
if (Gradient == null || scale > lastScale)
{
var stops = GradientHelper.GetGradientStops(StartColor, EndColor, scale, wrap).ToList();
Gradient = new CGGradient(CGColorSpace.CreateDeviceRGB(), stops.Select(r => r.Item2).ToArray(), stops.Select(r => (nfloat)r.Item1).ToArray());
Gradient = new CGGradient(CGColorSpace.CreateSrgb(), stops.Select(r => r.Item2).ToArray(), stops.Select(r => (nfloat)r.Item1).ToArray());
lastScale = scale;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Eto.Mac/Drawing/RadialGradientBrushHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void Draw(GraphicsHandler graphics, bool stroke, FillMode fillMode, bool
{
var stops = GradientHelper.GetGradientStops(StartColor.ToCG(), EndColor.ToCG(), scale, wrap).ToList();
lastScale = scale;
Gradient = new CGGradient(CGColorSpace.CreateDeviceRGB(), stops.Select(r => r.Item2).ToArray(), stops.Select(r => (nfloat)r.Item1).ToArray());
Gradient = new CGGradient(CGColorSpace.CreateSrgb(), stops.Select(r => r.Item2).ToArray(), stops.Select(r => (nfloat)r.Item1).ToArray());
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/Eto.Mac/Eto.macOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<DefineConstants>$(DefineConstants);OSX;DESKTOP;UNIFIED;MACOS_NET;USE_CFSTRING</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefaultItemExcludes>$(DefaultItemExcludes);build\*</DefaultItemExcludes>
<NoWarn>$(NoWarn);CA1416;CS8981</NoWarn>
<NoWarn>$(NoWarn);CA1416;CS8981;NETSDK1202</NoWarn>
</PropertyGroup>
<ItemGroup>
<Using Include="AppKit" />
Expand Down
2 changes: 1 addition & 1 deletion src/Eto.Mac/Forms/ColorDialogHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ protected virtual void OnDidResignKey(NSNotification notification)

public virtual void OnColorChanged()
{
_color = Control.Color.UsingColorSpace(NSColorSpace.DeviceRGBColorSpace).ToEto();
_color = Control.Color.UsingColorSpace(NSColorSpace.SRGBColorSpace).ToEto();
if (_color == _lastColor)
return;
_lastColor = _color;
Expand Down
4 changes: 2 additions & 2 deletions src/Eto.Mac/Forms/Controls/MacImageAndTextCell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public class MacImageListItemCell : EtoLabelFieldCell
public const int ImagePadding = 2;
NSShadow textShadow;
NSShadow textHighlightShadow;
NSColor groupColor = NSColor.FromCalibratedRgba(0x6F / (float)0xFF, 0x7E / (float)0xFF, 0x8B / (float)0xFF, 1.0F);
//light shade: NSColor.FromCalibratedRgba (0x82 / (float)0xFF, 0x90 / (float)0xFF, 0x9D / (float)0xFF, 1.0F);
NSColor groupColor = NSColor.FromSrgb(0x6F / (float)0xFF, 0x7E / (float)0xFF, 0x8B / (float)0xFF, 1.0F);
//light shade: NSColor.FromSrgb (0x82 / (float)0xFF, 0x90 / (float)0xFF, 0x9D / (float)0xFF, 1.0F);


public MacImageListItemCell()
Expand Down
2 changes: 1 addition & 1 deletion src/Eto.Mac/Forms/MacView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ public virtual Color BackgroundColor
get { return Widget.Properties.Get<Color?>(MacView.BackgroundColorKey) ?? DefaultBackgroundColor; }
set
{
if (value != BackgroundColor)
if (value != Widget.Properties.Get<Color?>(MacView.BackgroundColorKey))
{
Widget.Properties[MacView.BackgroundColorKey] = value;
SetBackgroundColor(value);
Expand Down
15 changes: 2 additions & 13 deletions src/Eto.Mac/MacConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,7 @@ public static NSColor ToNSUI(this Color color)
return nscolor;
if (color.ControlObject is CGColor cgcolor && MacVersion.IsAtLeast(10, 8))
return NSColor.FromCGColor(cgcolor);
return NSColor.FromDeviceRgba(color.R, color.G, color.B, color.A);
}

public static NSColor ToNSUI(this Color color, bool calibrated)
{
if (color.ControlObject is NSColor nscolor)
return nscolor;
if (color.ControlObject is CGColor cgcolor && MacVersion.IsAtLeast(10, 8))
return NSColor.FromCGColor(cgcolor);
return calibrated
? NSColor.FromCalibratedRgba(color.R, color.G, color.B, color.A)
: NSColor.FromDeviceRgba(color.R, color.G, color.B, color.A);
return NSColor.FromSrgb(color.R, color.G, color.B, color.A);
}

[Obsolete("Use ToEtoWithAppearance(NSColor) instead")]
Expand Down Expand Up @@ -57,7 +46,7 @@ public static Color ToEto(this NSColor color)
if (color == null)
return Colors.Transparent;

var colorspace = NSColorSpace.DeviceRGBColorSpace;
var colorspace = NSColorSpace.SRGBColorSpace;

var converted = color.UsingColorSpace(colorspace);
if (converted == null)
Expand Down
6 changes: 3 additions & 3 deletions src/Eto.iOS/Drawing/BitmapHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void Create(int width, int height, PixelFormat pixelFormat)
Data = NSMutableData.FromLength(bytesPerRow * height);

provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRgb(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
Control = UIImage.FromImage(cgimage, 0f, UIImageOrientation.Up);

break;
Expand All @@ -89,7 +89,7 @@ public void Create(int width, int height, PixelFormat pixelFormat)
//Data = new NSMutableData ((uint)(bytesPerRow * height));

provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.NoneSkipFirst, provider, null, true, CGColorRenderingIntent.Default);
cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRgb(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.NoneSkipFirst, provider, null, true, CGColorRenderingIntent.Default);
Control = UIImage.FromImage(cgimage, 0f, UIImageOrientation.Up);

break;
Expand All @@ -104,7 +104,7 @@ public void Create(int width, int height, PixelFormat pixelFormat)
Data = new NSMutableData((uint)(bytesPerRow * height));

provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRgb(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
Control = UIImage.FromImage(cgimage, 0f, UIImageOrientation.Up);
break;
}
Expand Down
10 changes: 5 additions & 5 deletions src/Eto/Drawing/Color.cs
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ public void Invert()
/// <returns>The 32-bit ARGB value that corresponds to this color</returns>
public int ToArgb()
{
return (int)((uint)(B * byte.MaxValue) | (uint)(G * byte.MaxValue) << 8 | (uint)(R * byte.MaxValue) << 16 | (uint)(A * byte.MaxValue) << 24);
return (int)((uint)Bb | (uint)Gb << 8 | (uint)Rb << 16 | (uint)Ab << 24);
}

/// <summary>
Expand All @@ -694,7 +694,7 @@ public int ToArgb()
/// <returns>A premultiplied ARGB value</returns>
public int ToPremultipliedArgb()
{
return (int)((uint)(B * A * byte.MaxValue) | (uint)(G * A * byte.MaxValue) << 8 | (uint)(R * A * byte.MaxValue) << 16 | (uint)(A * byte.MaxValue) << 24);
return (int)((uint)Math.Round(B * A * byte.MaxValue + .5f) | (uint)Math.Round(G * A * byte.MaxValue + .5f) << 8 | (uint)Math.Round(R * A * byte.MaxValue + .5f) << 16 | (uint)Ab << 24);
}

/// <summary>
Expand All @@ -704,12 +704,12 @@ public int ToPremultipliedArgb()
public int ToArgb(ColorStyles style)
{
if (style.HasFlag(ColorStyles.ExcludeAlpha))
return (int)((uint)(B * byte.MaxValue) | (uint)(G * byte.MaxValue) << 8 | (uint)(R * byte.MaxValue) << 16);
return (int)((uint)Bb | (uint)Gb << 8 | (uint)Rb << 16);

if (style.HasFlag(ColorStyles.AlphaLast))
return (int)((uint)(A * byte.MaxValue) | (uint)(B * byte.MaxValue) << 8 | (uint)(G * byte.MaxValue) << 16 | (uint)(R * byte.MaxValue) << 24);
return (int)((uint)Ab | (uint)Bb << 8 | (uint)Gb << 16 | (uint)Rb << 24);
else
return (int)((uint)(B * byte.MaxValue) | (uint)(G * byte.MaxValue) << 8 | (uint)(R * byte.MaxValue) << 16 | (uint)(A * byte.MaxValue) << 24);
return (int)((uint)Bb | (uint)Gb << 8 | (uint)Rb << 16 | (uint)Ab << 24);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Eto/Forms/Controls/Control.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ internal void TriggerStyleChanged(EventArgs e)
/// characteristics of the control and its children, since it must enable layers to do so.
/// </remarks>
/// <value>The color of the background.</value>
public Color BackgroundColor
public virtual Color BackgroundColor
{
get { return Handler.BackgroundColor; }
set { Handler.BackgroundColor = value; }
Expand Down
2 changes: 1 addition & 1 deletion test/Eto.Test.Mac/Eto.Test.macOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<PackageSigningKey>3rd Party Mac Developer Installer</PackageSigningKey>
<MonoBundlingExtraArgs>--nowarn:2006 --nowarn:0176</MonoBundlingExtraArgs>
<DefineConstants>MACOS_NET</DefineConstants>
<SupportedOSPlatformVersion>10.15</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion>12.0</SupportedOSPlatformVersion>
<NoWarn>CA1416;CS8981</NoWarn>

<TrimMode>partial</TrimMode>
Expand Down
6 changes: 4 additions & 2 deletions test/Eto.Test.Mac/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<string>12.0</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSRequiresAquaSystemAppearance</key>
<string>False</string>
<false/>
<key>UIDesignRequiresCompatibility</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
Expand Down
2 changes: 1 addition & 1 deletion test/Eto.Test.Mac/UnitTests/GridViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private static void SetParameters(NSTableViewStyle style, int intercellSpacing,
[TestCase(NSTableViewStyle.Plain, -1, "Some Text", 100, 180)]
[TestCase(NSTableViewStyle.Plain, -1, "Some Text", 15, -1)]
[TestCase(NSTableViewStyle.Plain, -1, "Some Much Longer Text That Should Still Work", 100, 180)]
[TestCase(NSTableViewStyle.Plain, 20, "Some Text", 100)]
[TestCase(NSTableViewStyle.Plain, 20, "Some Text", 100, -1)]
[TestCase(NSTableViewStyle.Plain, 20, "Some Text", 15, -1)]
[TestCase(NSTableViewStyle.Plain, 3, "Some Text", 100, 180)]
[TestCase(NSTableViewStyle.Plain, 3, "Some Text", 15, -1)]
Expand Down
14 changes: 13 additions & 1 deletion test/Eto.Test/Sections/Drawing/SystemColorSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,19 @@ public static ControlType Create<T>(Action<T> mod = null, Action<T, string> set

IEnumerable<ControlType> GetControlTypes()
{
yield return ControlType.Create<Drawable>(c => c.Size = new Size(100, 20));
yield return ControlType.Create<Drawable>(c =>
{
c.Paint += (sender, e) =>
{
var color = c.BackgroundColor;
var g = e.Graphics;
var rect = new RectangleF(c.Size);
rect.Inset(4);
g.FillRectangle(color, rect.X, rect.Y, rect.Width / 2, rect.Height);
g.FillRectangle(Color.FromArgb(color.ToArgb()), rect.X + rect.Width / 2, rect.Y, rect.Width / 2, rect.Height);
};
c.Size = new Size(100, 20);
});
yield return ControlType.Create<Label>(set: (c,v) => c.Text = v, getTextColor: c => c.TextColor, setTextColor: (c, v) => c.TextColor = v);
yield return ControlType.Create<TextBox>(set: (c, v) => c.Text = v, getTextColor: c => c.TextColor, setTextColor: (c, v) => c.TextColor = v);
yield return ControlType.Create<TextArea>(set: (c, v) => c.Text = v, getTextColor: c => c.TextColor, setTextColor: (c, v) => c.TextColor = v);
Expand Down
39 changes: 38 additions & 1 deletion test/Eto.Test/UnitTests/Drawing/BitmapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ void TestPixels(Color topLeft, Color topRight, Color bottomLeft, Color bottomRig
{
Assert.That(bmp, Is.Not.Null);
Assert.That(savedBitmap, Is.Not.Null);

Assert.That(bmp.GetPixel(0, 0), Is.EqualTo(topLeft), test + ".1.1");
Assert.That(bmp.GetPixel(halfSize, 0), Is.EqualTo(topRight), test + ".1.2");
Assert.That(bmp.GetPixel(0, halfSize), Is.EqualTo(bottomLeft), test + ".1.3");
Expand Down Expand Up @@ -542,5 +542,42 @@ void TestPixels(Color topLeft, Color topRight, Color bottomLeft, Color bottomRig
GetSavedBitmap();
TestPixels(redColor, emptyColor, greenColor, blueColor, "#3");
}

[TestCase(PixelFormat.Format24bppRgb, 24)]
[TestCase(PixelFormat.Format32bppRgb, 32)]
[TestCase(PixelFormat.Format32bppRgba, 32)]
public void BitmapShouldHaveCorrectBits(PixelFormat format, int expectedBits)
{
Invoke(() =>
{
var bitmap = new Bitmap(10, 10, format);
using var bd = bitmap.Lock();
Assert.That(bd.BitsPerPixel, Is.EqualTo(expectedBits));
});
}

[TestCase(PixelFormat.Format24bppRgb)]
[TestCase(PixelFormat.Format32bppRgb)]
public void BitmapShouldNotHaveTransparency(PixelFormat format)
{
Invoke(() =>
{
var bitmap = new Bitmap(10, 10, format);
using var bd = bitmap.Lock();
var color = Color.FromArgb(255, 0, 0, 255); // fully transparent blue
bd.SetPixel(0, 0, color);
var ms = new MemoryStream();
bitmap.Save(ms, ImageFormat.Png);
ms.Position = 0;

var loadedBitmap = new Bitmap(ms);
using var bdLoaded = loadedBitmap.Lock();
var gottenColor = bd.GetPixel(0, 0);
Assert.That(gottenColor.A, Is.EqualTo(255), "Alpha should be 255");
Assert.That(gottenColor.R, Is.EqualTo(0), "Red should be 0");
Assert.That(gottenColor.G, Is.EqualTo(0), "Green should be 0");
Assert.That(gottenColor.B, Is.EqualTo(255), "Blue should be 255");
});
}
}
}
Loading