internal static GlowBitmap Create(GlowDrawingContext drawingContext, GlowBitmapPart bitmapPart, Color color) { var orCreateAlphaMask = GetOrCreateAlphaMask(bitmapPart); var glowBitmap = new GlowBitmap( drawingContext.ScreenDC, orCreateAlphaMask.Width, orCreateAlphaMask.Height); for (var i = 0; i < orCreateAlphaMask.DIBits.Length; i += BytesPerPixelBgra32) { var b = orCreateAlphaMask.DIBits[i + 3]; var val = PremultiplyAlpha(color.R, b); var val2 = PremultiplyAlpha(color.G, b); var val3 = PremultiplyAlpha(color.B, b); Marshal.WriteByte(glowBitmap.DIBits, i, val3); Marshal.WriteByte(glowBitmap.DIBits, i + 1, val2); Marshal.WriteByte(glowBitmap.DIBits, i + 2, val); Marshal.WriteByte(glowBitmap.DIBits, i + 3, b); } return(glowBitmap); }
public static RenderTargetBitmap GenerateBitmapSource(GlowBitmapPart part, int glowDepth, bool useRadialGradientForCorners) { var size = GetSize(part, glowDepth); var drawingVisual = new DrawingVisual(); using (var drawingContext = drawingVisual.RenderOpen()) { if (glowDepth > 1) { var gradientBrush = CreateGradientBrush(part, useRadialGradientForCorners); gradientBrush.Freeze(); drawingContext.DrawRectangle(gradientBrush, null, new Rect(0, 0, size.Width, size.Height)); drawingContext.DrawRectangle(Brushes.Black, null, GetBlackRect(part, glowDepth)); } else { drawingContext.DrawRectangle(Brushes.Black, null, new Rect(0, 0, size.Width, size.Height)); } } var targetBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Pbgra32); targetBitmap.Render(drawingVisual); return(targetBitmap); }
private static Size GetSize(GlowBitmapPart part, int glowDepth) { switch (part) { case GlowBitmapPart.CornerTopLeft: case GlowBitmapPart.CornerTopRight: case GlowBitmapPart.CornerBottomLeft: case GlowBitmapPart.CornerBottomRight: return(new Size(glowDepth, glowDepth)); case GlowBitmapPart.Top: case GlowBitmapPart.Bottom: return(new Size(1, glowDepth)); case GlowBitmapPart.TopLeft: case GlowBitmapPart.TopRight: case GlowBitmapPart.BottomLeft: case GlowBitmapPart.BottomRight: return(new Size(Math.Min(glowDepth, 6), glowDepth)); case GlowBitmapPart.Left: case GlowBitmapPart.Right: return(new Size(glowDepth, 1)); case GlowBitmapPart.LeftTop: case GlowBitmapPart.LeftBottom: case GlowBitmapPart.RightTop: case GlowBitmapPart.RightBottom: return(new Size(glowDepth, Math.Min(glowDepth, 6))); default: throw new ArgumentOutOfRangeException(nameof(part), part, null); } }
private static StartAndEndPoint GetStartAndEndPoint(GlowBitmapPart part) { switch (part) { case GlowBitmapPart.CornerTopLeft: return(new(new Point(1, 1), new Point(0, 0))); case GlowBitmapPart.CornerTopRight: return(new(new Point(0, 1), new Point(1, 0))); case GlowBitmapPart.CornerBottomLeft: return(new(new Point(1, 0), new Point(0, 1))); case GlowBitmapPart.CornerBottomRight: return(new(new Point(0, 0), new Point(1, 1))); case GlowBitmapPart.TopLeft: return(new(new Point(0.6, 1), new Point(0.5, 0))); case GlowBitmapPart.Top: return(new(new Point(0.5, 1), new Point(0.5, 0))); case GlowBitmapPart.TopRight: return(new(new Point(0.4, 1), new Point(0.5, 0))); case GlowBitmapPart.LeftTop: return(new(new Point(1, 0.1), new Point(0, 0))); case GlowBitmapPart.Left: return(new(new Point(1, 0), new Point(0, 0))); case GlowBitmapPart.LeftBottom: return(new(new Point(1, 0), new Point(0, 0.1))); case GlowBitmapPart.BottomLeft: return(new(new Point(0.6, 0), new Point(0.5, 1))); case GlowBitmapPart.Bottom: return(new(new Point(0.5, 0), new Point(0.5, 1))); case GlowBitmapPart.BottomRight: return(new(new Point(0.4, 0), new Point(0.5, 1))); case GlowBitmapPart.RightTop: return(new(new Point(0, 0.1), new Point(1, 0))); case GlowBitmapPart.Right: return(new(new Point(0, 0), new Point(1, 0))); case GlowBitmapPart.RightBottom: return(new(new Point(0, 0), new Point(1, 0.1))); default: throw new ArgumentOutOfRangeException(nameof(part), part, null); } }
private static GradientBrush CreateGradientBrush(GlowBitmapPart part, bool useRadialGradientForCorners) { var startAndEndPoint = GetStartAndEndPoint(part); var gradientStops = GetGradientStops(part, useRadialGradientForCorners); var gradientStopCollection = new GradientStopCollection(gradientStops); if (useRadialGradientForCorners == false) { return(new LinearGradientBrush(gradientStopCollection, startAndEndPoint.Start, startAndEndPoint.End)); } switch (part) { case GlowBitmapPart.CornerTopLeft: case GlowBitmapPart.CornerTopRight: case GlowBitmapPart.CornerBottomLeft: case GlowBitmapPart.CornerBottomRight: return(new RadialGradientBrush(gradientStopCollection) { GradientOrigin = startAndEndPoint.Start, Center = new Point(startAndEndPoint.Start.X.AreClose(0) ? 0.2 : 0.8, startAndEndPoint.Start.Y.AreClose(0) ? 0.2 : 0.8), RadiusX = 1, RadiusY = 1 }); case GlowBitmapPart.TopLeft: case GlowBitmapPart.Top: case GlowBitmapPart.TopRight: case GlowBitmapPart.LeftTop: case GlowBitmapPart.Left: case GlowBitmapPart.LeftBottom: case GlowBitmapPart.BottomLeft: case GlowBitmapPart.Bottom: case GlowBitmapPart.BottomRight: case GlowBitmapPart.RightTop: case GlowBitmapPart.Right: case GlowBitmapPart.RightBottom: return(new LinearGradientBrush(gradientStopCollection, startAndEndPoint.Start, startAndEndPoint.End)); default: throw new ArgumentOutOfRangeException(nameof(part), part, null); } }
private static CachedBitmapInfo GetOrCreateAlphaMask(GlowBitmapPart bitmapPart) { if (_transparencyMasks[(int)bitmapPart] == null) { var bitmapImage = new BitmapImage(new Uri($"pack://application:,,,/HandyControl;Component/Resources/Images/GlowWindow/{bitmapPart}.png")); var array = new byte[BytesPerPixelBgra32 * bitmapImage.PixelWidth * bitmapImage.PixelHeight]; var stride = BytesPerPixelBgra32 * bitmapImage.PixelWidth; bitmapImage.CopyPixels(array, stride, 0); _transparencyMasks[(int)bitmapPart] = new CachedBitmapInfo( array, bitmapImage.PixelWidth, bitmapImage.PixelHeight); } return(_transparencyMasks[(int)bitmapPart]); }
private static Rect GetBlackRect(GlowBitmapPart part, int glowDepth) { switch (part) { case GlowBitmapPart.CornerTopLeft: return(new Rect(new Point(glowDepth - 1, glowDepth - 1), new Size(1, 1))); case GlowBitmapPart.CornerTopRight: return(new Rect(new Point(0, glowDepth - 1), new Size(1, 1))); case GlowBitmapPart.CornerBottomLeft: return(new Rect(new Point(glowDepth - 1, 0), new Size(1, 1))); case GlowBitmapPart.CornerBottomRight: return(new Rect(new Point(0, 0), new Size(1, 1))); case GlowBitmapPart.TopLeft: case GlowBitmapPart.Top: case GlowBitmapPart.TopRight: return(new Rect(new Point(0, glowDepth - 1), new Size(glowDepth, 1))); case GlowBitmapPart.LeftTop: case GlowBitmapPart.Left: case GlowBitmapPart.LeftBottom: return(new Rect(new Point(glowDepth - 1, 0), new Size(1, glowDepth))); case GlowBitmapPart.BottomLeft: case GlowBitmapPart.Bottom: case GlowBitmapPart.BottomRight: return(new Rect(new Point(0, 0), new Size(glowDepth, 1))); case GlowBitmapPart.RightTop: case GlowBitmapPart.Right: case GlowBitmapPart.RightBottom: return(new Rect(new Point(0, 0), new Size(1, glowDepth))); default: throw new ArgumentOutOfRangeException(nameof(part), part, null); } }
private static IEnumerable <GradientStop> GetGradientStops(GlowBitmapPart part, bool useRadialGradientForCorners) { switch (part) { case GlowBitmapPart.CornerBottomLeft: case GlowBitmapPart.CornerBottomRight: case GlowBitmapPart.CornerTopLeft: case GlowBitmapPart.CornerTopRight: if (useRadialGradientForCorners) { yield return(new GradientStop(ColorFromString("#55838383"), 0)); yield return(new GradientStop(ColorFromString("#02838383"), 0.5)); yield return(new GradientStop(ColorFromString("#00000000"), 1)); } else { yield return(new GradientStop(ColorFromString("#55838383"), 0)); yield return(new GradientStop(ColorFromString("#02838383"), 0.3)); yield return(new GradientStop(ColorFromString("#00000000"), 1)); } break; default: yield return(new GradientStop(ColorFromString("#55838383"), 0)); yield return(new GradientStop(ColorFromString("#02838383"), 0.6)); yield return(new GradientStop(ColorFromString("#00000000"), 1)); break; } }