/* Copyright (c) Citrix Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimer in the documentation and/or other * materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; using System.Drawing.Text; using System.Windows.Forms; namespace XenAdmin.Core { class Drawing { /// /// The color of URLs. /// // Feel free to improve this definition if you can think of a nicer way // (it doesn't seem to be one of the SystemColors, nor helpfully provided in LinkLabel) public static readonly Color LinkColor = Color.Blue; /// /// The color of tooltip backgrounds in XP. /// public static readonly Color ToolTipColor = Color.FromArgb(255, 255, 225); public static readonly Color XPBorderColor = Color.FromArgb(123, 158, 189); public static readonly Pen XPBorderPen = new Pen(XPBorderColor, 1); private static readonly ColorMatrix GreyScaleColorMatrix = new ColorMatrix(new float[][] { new float[] {0.2125f, 0.2125f, 0.2125f, 0, 0}, new float[] {0.2577f, 0.2577f, 0.2577f, 0, 0}, new float[] {0.0361f, 0.0361f, 0.0361f, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {0.38f, 0.38f, 0.38f, 0, 1} }); private static readonly ColorMatrix AlphaColorMatrix = new ColorMatrix(new float[][] { new float[] {1, 0, 0, 0, 0}, new float[] {0, 1, 0, 0, 0}, new float[] {0, 0, 1, 0, 0}, new float[] {0, 0, 0, .75f, 0}, new float[] {0, 0, 0, 0, 1} }); public static readonly ImageAttributes GreyScaleAttributes = new ImageAttributes(); public static readonly ImageAttributes AlphaAttributes = new ImageAttributes(); static Drawing() { GreyScaleAttributes.SetColorMatrix(GreyScaleColorMatrix); AlphaAttributes.SetColorMatrix(AlphaColorMatrix); } /// /// Kerpow! /// public static void QuickDraw(Graphics gTarget, Bitmap buffer) { QuickDraw(gTarget, buffer, new Point(0, 0), new Rectangle(0, 0, buffer.Width, buffer.Height)); } /// /// Kerpow! /// public static void QuickDraw(Graphics gTarget, Bitmap buffer, Point source, Rectangle dest) { IntPtr pTarget = gTarget.GetHdc(); IntPtr pSource = CreateCompatibleDC(pTarget); IntPtr pNew = buffer.GetHbitmap(); SelectObject(pSource, pNew); BitBlt(pTarget, dest.X, dest.Y, dest.Width, dest.Height, pSource, source.X, source.Y, TernaryRasterOperations.SRCCOPY); DeleteObject(pNew); DeleteDC(pSource); gTarget.ReleaseHdc(pTarget); } [DllImport("gdi32.dll", SetLastError = true)] public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, TernaryRasterOperations dwRop); [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] public static extern IntPtr CreateCompatibleDC(IntPtr hdc); [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] public static extern bool DeleteDC(IntPtr hdc); [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)] public static extern bool DeleteObject(IntPtr hObject); public enum TernaryRasterOperations : uint { SRCCOPY = 0x00CC0020, SRCPAINT = 0x00EE0086, SRCAND = 0x008800C6, SRCINVERT = 0x00660046, SRCERASE = 0x00440328, NOTSRCCOPY = 0x00330008, NOTSRCERASE = 0x001100A6, MERGECOPY = 0x00C000CA, MERGEPAINT = 0x00BB0226, PATCOPY = 0x00F00021, PATPAINT = 0x00FB0A09, PATINVERT = 0x005A0049, DSTINVERT = 0x00550009, BLACKNESS = 0x00000042, WHITENESS = 0x00FF0062 } public static TextRenderingHint TextRenderingHint { get { return TextRenderingHint.SystemDefault; } } // // CA-23037: & character in name, custom field (anything on general panel) // renders as a keyboard shortcut // public static void DrawText(IDeviceContext dc, String text, Font font, Point point, Color color) { TextRenderer.DrawText(dc, text, font, point, color, TextFormatFlags.NoPrefix); } public static void DrawText(IDeviceContext dc, String text, Font font, Point point, Color color, Color backColor) { DrawText(dc, text, font, point, color, backColor, TextFormatFlags.NoPrefix); } public static void DrawText(IDeviceContext dc, String text, Font font, Point point, Color color, Color backColor, TextFormatFlags flags) { TextRenderer.DrawText(dc, text, font, point, color, backColor, flags | TextFormatFlags.NoPrefix); } public static void DrawText(IDeviceContext dc, String text, Font font, Rectangle bounds, Color color) { DrawText(dc, text, font, bounds, color, TextFormatFlags.NoPrefix); } public static void DrawText(IDeviceContext dc, String text, Font font, Rectangle bounds, Color color, TextFormatFlags textFormatFlags) { TextRenderer.DrawText(dc, text, font, bounds, color, textFormatFlags | TextFormatFlags.NoPrefix); } public static void DrawText(IDeviceContext dc, String text, Font font, Rectangle bounds, Color foreColor, Color backColor) { DrawText(dc, text, font, bounds, foreColor, backColor, TextFormatFlags.NoPrefix); } public static void DrawText(IDeviceContext dc, String text, Font font, Rectangle bounds, Color foreColor, Color backColor, TextFormatFlags flags) { TextRenderer.DrawText(dc, text, font, bounds, foreColor, backColor, flags | TextFormatFlags.NoPrefix); } public static Size MeasureText(String text, Font font) { return MeasureText(text, font, new Size(Int32.MaxValue, Int32.MaxValue), TextFormatFlags.NoPrefix); } public static Size MeasureText(String text, Font font, Size proposedSize, TextFormatFlags flags) { return TextRenderer.MeasureText(text, font, proposedSize, flags | TextFormatFlags.NoPrefix); } public static Size MeasureText(IDeviceContext dc, String text, Font font) { return MeasureText(dc, text, font, new Size(Int32.MaxValue, Int32.MaxValue), TextFormatFlags.NoPrefix); } public static Size MeasureText(IDeviceContext dc, String text, Font font, TextFormatFlags flags) { return MeasureText(dc, text, font, new Size(Int32.MaxValue, Int32.MaxValue), flags); } public static Size MeasureText(IDeviceContext dc, String text, Font font, Size proposedSize, TextFormatFlags flags) { return TextRenderer.MeasureText(dc, text, font, proposedSize, flags | TextFormatFlags.NoPrefix); } /// /// Draw me a progress bar. Copes with visual styles being on or off /// /// Graphics to draw to /// where to draw the progress bar /// how much progress (0.0-1.0) /// public static void DrawProgressBar(Graphics g, Rectangle r, double progress) { if (Application.RenderWithVisualStyles) { ProgressBarRenderer.DrawHorizontalBar(g, r); Rectangle s = new Rectangle( r.X + 4, r.Y + 3, (int)((r.Width - 8) * progress), r.Height - 5); ProgressBarRenderer.DrawHorizontalChunks(g, s); } else { g.FillRectangle(SystemBrushes.ButtonShadow, r); Rectangle s = new Rectangle( r.X + 1, r.Y + 1, r.Width - 1, r.Height - 1); g.FillRectangle(SystemBrushes.ButtonHighlight, s); Rectangle t = new Rectangle( r.X + 1, r.Y + 1, r.Width - 2, r.Height - 2); g.FillRectangle(SystemBrushes.ButtonFace, t); int barwidth = (int)(progress * (r.Width - 4)); int chunkwidth = 7; int chunkgap = 2; int progleft = 0; while (progleft + chunkwidth + chunkgap < barwidth) { Rectangle u = new Rectangle( r.X + 2 + progleft, r.Y + 2, chunkwidth, 13); g.FillRectangle(SystemBrushes.ActiveCaption, u); progleft += chunkwidth + chunkgap; } Rectangle v = new Rectangle( r.X + 2 + progleft, r.Y + 2, chunkwidth - progleft, 13); g.FillRectangle(SystemBrushes.ActiveCaption, v); } } public enum SimpleProgressBarColor { Green, Red, Blue }; /// /// Draws a simple progress bar (just the chunks with a grey 1 pixel border). /// /// The device context used for drawing. /// The rectangle that specifies where it should be drawn. /// The value of the progress. Should be between 0.0 and 1.0. /// The color of the progress bar. public static void DrawSimpleProgressBar(Graphics g, Rectangle r, double progress, SimpleProgressBarColor color) { using (Bitmap bitmap = new Bitmap(r.Width, r.Height)) { using (Graphics gg = Graphics.FromImage(bitmap)) { //fill background in white gg.FillRectangle(Brushes.White, new Rectangle(0, 0, r.Width, r.Height)); Rectangle chunks = new Rectangle(0, 0, (int)(r.Width * progress), r.Height); if (Application.RenderWithVisualStyles) { ProgressBarRenderer.DrawHorizontalChunks(gg, chunks); } else { var brush = Brushes.LightGreen; if (color == SimpleProgressBarColor.Red) { brush = Brushes.Red; } else if (color == SimpleProgressBarColor.Blue) { brush = Brushes.Blue; } gg.FillRectangle(brush, chunks); } } if (Application.RenderWithVisualStyles && color != SimpleProgressBarColor.Green) { for (int i = 0; i < bitmap.Width * progress; i++) { for (int j = 0; j < bitmap.Height; j++) { Color c = bitmap.GetPixel(i, j); if (color == SimpleProgressBarColor.Blue) { bitmap.SetPixel(i, j, Color.FromArgb(c.R, c.B, c.G)); } else { //red bitmap.SetPixel(i, j, Color.FromArgb(c.G, c.R, c.B)); } } } } // draw progress bar g.DrawImage(bitmap, r); // draw rectangle around progress bar. g.DrawRectangle(SystemPens.ControlDark, r); } } /// /// Converts input image to grey scale using Drawing.GreyScaleAttributes /// /// Image to convert /// Image converted to grey scale public static Image ConvertToGreyScale(Image source) { var bitmap = new Bitmap(source.Width, source.Height); using (Graphics graphics = Graphics.FromImage(bitmap)) { var rectangle = new Rectangle(0, 0, source.Width, source.Height); graphics.DrawImage(source, rectangle, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, Drawing.GreyScaleAttributes); return bitmap; } } } }