示例#1
0
        /// <summary>
        /// Draw an outlined text on a graphic.
        /// Draw a text using an outline in it, from custom CardGraphicComponent values. These are used to get position of text and destination picture/graphic.
        /// </summary>
        /// <param name="g">Graphic to draw the text</param>
        /// <param name="text">Text to draw</param>
        /// <param name="canvas">Values for position, font, etc. of the text</param>
        /// <param name="parent">If canvas has a parent, use it for relative position of the text</param>
        /// <param name="centered">If text must be drawn centered or not</param>
        public static void drawOutlineText(Graphics g, string text, CardGraphicComponent canvas, CardGraphicComponent parent, bool centered=false)
        {
            // Check parent to get proper offsets
            var offsetTop  = 0;
            var offsetLeft = 0;
            if (parent != null)
            {
                offsetLeft = parent.Left;
                offsetTop  = parent.Top;
            }
            // set atialiasing for drawing
            g.SmoothingMode     = SmoothingMode.HighQuality; // AntiAlias
            g.InterpolationMode = InterpolationMode.HighQualityBicubic; // High
            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            g.PixelOffsetMode   = PixelOffsetMode.HighQuality;
            // Create GraphicsPath to draw text
            using (GraphicsPath path = new GraphicsPath())
            {
                // Calculate position in case text must be draw centered or not
                float txtWidth = 0;
                if (centered)
                    txtWidth = getStringWidth(g, text, new Font(canvas.font.FontFamily, canvas.font.Size, canvas.font.Style, GraphicsUnit.Point, ((byte)(0)))) / 2;
                // Add string to path
                path.AddString(text, canvas.font.FontFamily, (int)canvas.font.Style, canvas.font.Size, new Point(canvas.Left + offsetLeft - (int)txtWidth, canvas.Top + offsetTop), StringFormat.GenericTypographic);
                // Draw text using this pen. This does the trick (with the path) to draw the outline
                using (Pen pen = new Pen(canvas.borderColor, canvas.Outline))
                {
                    pen.LineJoin = LineJoin.Round;

                    g.DrawPath(pen, path);
                    g.FillPath(canvas.textColor, path);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Render string text in graphics over a path using given font.
        /// Path will be a cuve (the one defined in main class).
        /// </summary>
        /// <param name="g">Graphic to draw to.</param>
        /// <param name="text">Text to draw.</param>
        /// <param name="component">CardGraphicComponent to get style parameters to draw text (font, size...)</param>
        /// <param name="squish">Used to adjust spaces between chars due to MeasureString</param>
        /// <param name="debug">If true, it draws a red curve as reference. Default: do not draw.</param>
        public void renderText(System.Drawing.Graphics g, string text, CardGraphicComponent component, bool squish = false, bool debug = false)
        {
            // Define vars
            Font fontR  = Graphic.findBestFitFont(g, text, component.font, getPathLength(pathSegments), squish);
            var width   = Graphic.getStringWidth(g, text, fontR, squish);
            // If text too big and it was adjusted, we need adjust the vertical offset too
            var adjust  = component.font.Size - fontR.Size;
            var middleX = (last.X + first.X) / 2;
            var middleY = getY(middleX);
            var startX  = middleX - (width / 2);
            var startY = getY(startX);
            var len     = text.Length;
            var space   = g.MeasureString(" ", fontR, Point.Empty, StringFormat.GenericDefault).Width;
            var factor  = (squish) ? Config.align : 0f;
            var flaw    = 2 * fontR.Size / component.font.Size; // First char needs an offset, idk why :S
            float w;
            // set atialiasing
            g.SmoothingMode     = SmoothingMode.HighQuality; // AntiAlias
            g.InterpolationMode = InterpolationMode.HighQualityBicubic; // High
            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            g.PixelOffsetMode   = PixelOffsetMode.HighQuality;
            // Go along string and render chars
            for (int characterIndex = 0; characterIndex < len; characterIndex++)
            {
                char @char = text[characterIndex];
                w = (@char == ' ') ? space : g.MeasureString(@char.ToString(), fontR, Point.Empty, StringFormat.GenericTypographic).Width - factor;
                // put char in (startX, startY)
                using (GraphicsPath characterPath = new GraphicsPath())
                {
                    characterPath.AddString(@char.ToString(), fontR.FontFamily, (int)fontR.Style, fontR.Size, Point.Empty, StringFormat.GenericTypographic);
                    // Transformation matrix to move the character to the correct location.
                    // Note that all actions on the Matrix class are prepended, so we apply them in reverse.
                    var transform = new Matrix();
                    // Translate to the final position
                    transform.Translate(startX + flaw, startY + adjust);
                    // Rotate the character
                    var cathetus = getY(startX + w) - startY;
                    var hypothenuse = Math.Sqrt(Math.Pow(w - flaw, 2) + Math.Pow(cathetus, 2));
                    var angle = (factor == 0) ? 0f : Math.Asin(cathetus / hypothenuse) * 180f / (float)Math.PI;
                    transform.Rotate((float)angle);
                    // Apply transformations
                    characterPath.Transform(transform);
                    // Draw the character
                    using (Pen pen = new Pen(component.borderColor, component.Outline))
                    {
                        pen.LineJoin = LineJoin.Round;

                        g.DrawPath(pen, characterPath);
                        g.FillPath(component.textColor, characterPath);
                    }
                }
                // Skip offset for the other chars
                flaw = 0;
                // Update new position
                startX += w;
                startY = getY(startX);
            }
            // Show path line if debugging
            if (debug)
            {
                // Get path of N points
                PointF[] points = getPath(pathSegments);
                using (GraphicsPath path = new GraphicsPath())
                {
                    // Create curve
                    path.AddCurve(points);
                    // And draw it to the screen.
                    using (Pen pen = new Pen(Color.Red, 2))
                    {
                        g.DrawPath(pen, path);
                    }
                }
            }
        }