Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

WPF: Transform PathGeometry data in mini-language

5.00/5 (4 votes)
2 May 2018CPOL 8.2K  
Parse, scale and/or translate Path data to create new XAML data

Introduction

Instead of using a constant RenderTransform to transform a given PathGeometry at runtime, the following routine creates the desired XAML.
Basically it splits the data into commands (upper- or lowercase letters) and coordinates.
All coordinates are scaled, only absolute coordinates (preceeding uppercase letter) are translated.

C#
using System;
using System.Globalization;
using System.Text;

public static string ScaleTranslatePath(string data, double scale = 1, double x = 0, double y = 0, int digits = 1)
{
    string format = "0." + new string('#', digits);

    StringBuilder sb = new StringBuilder(data.Length);

    if (data.StartsWith("F0") || data.StartsWith("F1"))
    {
        // StreamGeometry.FillRule
        sb.Append(data.Substring(0, 3));
        data = data.Substring(3);
    }

    string[] parts = data.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
    int i = 0;
    bool isAbsolute = false;

    foreach (string part in parts)
    {
        double value;
        if (part.Length == 1 && char.IsLetter(part, 0))
        {
            i = 0;
            isAbsolute = char.IsUpper(part, 0);
            sb.Append(part);
        }
        else if (double.TryParse(part, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out value))
        {
            value *= scale;

            if (isAbsolute)
            {
                if (i++ % 2 == 0)
                {
                    value += x;
                }
                else
                {
                    value += y;
                }
            }

            value = Math.Round(value, digits);
            sb.Append(value.ToString(format, CultureInfo.InvariantCulture));
        }

        sb.Append(' ');
    }

    return sb.ToString(0, sb.Length - 1);
}

MSDN: Path Markup Syntax

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)