BarRaider / streamdeck-tools

The Stream Deck Tools library wraps all the communication with the Stream Deck app, allowing you to focus on actually writing the Plugin's logic
https://barraider.com
MIT License
470 stars 70 forks source link

AddTextPath doesn't dispose all objects, doesn't provide horizontal alignment, and vertical alignment doesn't work correctly. #68

Open JoeSchulte opened 1 year ago

JoeSchulte commented 1 year ago

Here is an updated version of this function that resolves these three items.

    /// <summary>
    /// Adds a text path to an existing Graphics object. Uses TitleParameters to emulate the Text settings in the Property Inspector.
    /// Fixes issues with some resources not being disposed at the completion of the call.
    /// Also fixes issues with verticle alignment and allows you to specify horizontal alignment.
    /// </summary>
    /// <param name="graphics"></param>
    /// <param name="titleParameters"></param>
    /// <param name="rectangle">Rectangle where you would like to place the text, can typically be the whole image size.</param>
    /// <param name="text"></param>
    /// <param name="strokeColor"></param>
    /// <param name="strokeThickness"></param>
    /// <param name="horizontalAlignment">Alow horizontal alignment like StreamDeck does natively</param>
    public static void AddTextPath(this Graphics graphics, TitleParameters titleParameters, Rectangle rectangle, string text, Color strokeColor, float strokeThickness, StringAlignment horizontalAlignment = StringAlignment.Center)
    {
        try
        {
            if (titleParameters == null)
            {
                Logger.Instance.LogMessage(TracingLevel.ERROR, "AddTextPath: titleParameters is null");
                return;
            }

            using (var font = new Font(titleParameters.FontFamily, (float)titleParameters.FontSizeInPixelsScaledToDefaultImage, titleParameters.FontStyle, GraphicsUnit.Pixel))
            {
                graphics.PageUnit = GraphicsUnit.Pixel;

                StringAlignment lineAlignment;
                switch (titleParameters.VerticalAlignment)
                {
                    case TitleVerticalAlignment.Middle:
                        lineAlignment = StringAlignment.Center;
                        break;
                    case TitleVerticalAlignment.Bottom:
                        lineAlignment = StringAlignment.Far;
                        break;
                    default:
                        lineAlignment = StringAlignment.Near;
                        break;

                };
                // Let StringFormat do the work to do the alignment
                var format = new StringFormat() { LineAlignment = lineAlignment, Alignment = horizontalAlignment };

                using (var graphicsPath = new GraphicsPath())
                {
                    graphicsPath.AddString(text, font.FontFamily, (int)font.Style, graphics.DpiY * font.SizeInPoints / rectangle.Width, rectangle, format);

                    using (var pen = new Pen(strokeColor, strokeThickness))
                    {
                        graphics.DrawPath(pen, graphicsPath);
                        graphics.FillPath(new SolidBrush(titleParameters.TitleColor), graphicsPath);
                    }
                }
            }
        }
        catch (Exception arg)
        {
            Logger.Instance.LogMessage(TracingLevel.ERROR, $"AddTextPath Exception {arg}");
        }
    }