// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using SkiaSharp;
using Microsoft.Maui.Graphics;
namespace Microsoft.Maui.Platform;
///
/// Extension methods for color conversions between MAUI and SkiaSharp.
///
public static class ColorExtensions
{
///
/// Converts a MAUI Color to an SKColor.
///
public static SKColor ToSKColor(this Color color)
{
if (color == null)
return SKColors.Transparent;
return new SKColor(
(byte)(color.Red * 255),
(byte)(color.Green * 255),
(byte)(color.Blue * 255),
(byte)(color.Alpha * 255));
}
///
/// Converts an SKColor to a MAUI Color.
///
public static Color ToMauiColor(this SKColor color)
{
return new Color(
color.Red / 255f,
color.Green / 255f,
color.Blue / 255f,
color.Alpha / 255f);
}
///
/// Creates a new SKColor with the specified alpha value.
///
public static SKColor WithAlpha(this SKColor color, byte alpha)
{
return new SKColor(color.Red, color.Green, color.Blue, alpha);
}
///
/// Creates a lighter version of the color.
///
public static SKColor Lighter(this SKColor color, float factor = 0.2f)
{
return new SKColor(
(byte)Math.Min(255, color.Red + (255 - color.Red) * factor),
(byte)Math.Min(255, color.Green + (255 - color.Green) * factor),
(byte)Math.Min(255, color.Blue + (255 - color.Blue) * factor),
color.Alpha);
}
///
/// Creates a darker version of the color.
///
public static SKColor Darker(this SKColor color, float factor = 0.2f)
{
return new SKColor(
(byte)(color.Red * (1 - factor)),
(byte)(color.Green * (1 - factor)),
(byte)(color.Blue * (1 - factor)),
color.Alpha);
}
///
/// Gets the luminance of the color.
///
public static float GetLuminance(this SKColor color)
{
return 0.299f * color.Red / 255f +
0.587f * color.Green / 255f +
0.114f * color.Blue / 255f;
}
///
/// Determines if the color is considered light.
///
public static bool IsLight(this SKColor color)
{
return color.GetLuminance() > 0.5f;
}
///
/// Gets a contrasting color (black or white) for text on this background.
///
public static SKColor GetContrastingColor(this SKColor backgroundColor)
{
return backgroundColor.IsLight() ? SKColors.Black : SKColors.White;
}
///
/// Converts a MAUI Paint to an SKColor if possible.
///
public static SKColor? ToSKColorOrNull(this Paint? paint)
{
if (paint is SolidPaint solidPaint && solidPaint.Color != null)
return solidPaint.Color.ToSKColor();
return null;
}
///
/// Converts a MAUI Paint to an SKColor, using a default if not a solid color.
///
public static SKColor ToSKColor(this Paint? paint, SKColor defaultColor)
{
return paint.ToSKColorOrNull() ?? defaultColor;
}
}
///
/// Font extensions for converting MAUI fonts to SkiaSharp.
///
public static class FontExtensions
{
///
/// Gets the SKFontStyle from a MAUI Font.
///
public static SKFontStyle ToSKFontStyle(this Font font)
{
// Map MAUI FontWeight (enum with numeric values) to SKFontStyleWeight
var weight = (int)font.Weight switch
{
100 => SKFontStyleWeight.Thin, // Thin
200 => SKFontStyleWeight.ExtraLight, // UltraLight
300 => SKFontStyleWeight.Light, // Light
400 => SKFontStyleWeight.Normal, // Regular
500 => SKFontStyleWeight.Medium, // Medium
600 => SKFontStyleWeight.SemiBold, // Semibold
700 => SKFontStyleWeight.Bold, // Bold
800 => SKFontStyleWeight.ExtraBold, // Heavy
900 => SKFontStyleWeight.Black, // Black
_ => font.Weight >= FontWeight.Bold ? SKFontStyleWeight.Bold : SKFontStyleWeight.Normal
};
var slant = font.Slant switch
{
FontSlant.Italic => SKFontStyleSlant.Italic,
FontSlant.Oblique => SKFontStyleSlant.Oblique,
_ => SKFontStyleSlant.Upright
};
return new SKFontStyle(weight, SKFontStyleWidth.Normal, slant);
}
///
/// Creates an SKFont from a MAUI Font.
///
public static SKFont ToSKFont(this Font font, float defaultSize = 14f)
{
var size = font.Size > 0 ? (float)font.Size : defaultSize;
var typeface = SKTypeface.FromFamilyName(font.Family ?? "sans-serif", font.ToSKFontStyle());
return new SKFont(typeface, size);
}
}
///
/// Thickness extensions for converting MAUI Thickness to SKRect.
///
public static class ThicknessExtensions
{
///
/// Converts a MAUI Thickness to an SKRect representing padding/margin.
///
public static SKRect ToSKRect(this Thickness thickness)
{
return new SKRect(
(float)thickness.Left,
(float)thickness.Top,
(float)thickness.Right,
(float)thickness.Bottom);
}
}