WPF: Geometry aus formatiertem Text erstellen

Die Anforderung, Text in ein Geometry-Element umzuwandeln, liegt schnell am Tisch. Dies beginnt bei speziellen Manipulationen (Verwendung von unterschiedlichen Brushes) und geht geht hin zu Performance- und Speicherthemen bei der Verwendung von Text in Shapes etc.

Die Umwandlung hierzu geht recht einfach:

var formattedText = new FormattedText("M", 
                    CultureInfo.CurrentCulture, 
                    FlowDirection.LeftToRight, 
                    new Typeface("Tahoma", 
                        FontStyles.Italic, 
                        FontWeights.Bold, 
                        FontStretches.Condensed), 
                    16, 
                    Brushes.Black);

var geometry = formattedText.BuildGeometry(new Point(5,5));

In diesem Fall ist das einfach nur der Buchstabe M im Font Tahoma, Schriftgröße 16, kursiv und fett. Spezielle Brushes kommen hier noch nicht zum Zuge.

Wichtig ist, dass der Text natürlich im Nachhinein nicht mehr geändert werden kann. Hierzu müsste das Geometry-Objekt neu erstellt werden.

Wer nun besonders viele dieser Geometry-Objekte zu erstellen hat und auch immer wieder dieselben Texte zum Zug kommen, der kann sich einfach behelfen.

public class TextGeometryBuilder
{
    private static Dictionary<string, Geometry> cachedGeometries = new Dictionary<string, Geometry>();

    public string Text { get; set; }
    public FontFamily FontFamily { get; set; }
    public FontStyle FontStyle { get; set; }
    public FontWeight FontWeight { get; set; }
    public FontStretch FontStretch { get; set; }
    public double FontSize { get; set; }
    public Point Origin { get; set; }

    public Geometry Geometry
    {
        get
        {
            if (cachedGeometries.ContainsKey(Text))
            {
                return cachedGeometries[Text];
            }

            var formattedText = new FormattedText(Text, 
                CultureInfo.CurrentCulture, 
                FlowDirection.LeftToRight, 
                new Typeface(FontFamily, FontStyle, FontWeight, FontStretch), 
                    FontSize, 
                    Brushes.Black);

            var geometry = formattedText.BuildGeometry(Origin);
            cachedGeometries.Add(Text, geometry);
            return geometry;
        }
    }

    public PathGeometry PathGeometry
    {
        get
        {
            return PathGeometry.CreateFromGeometry(Geometry);
        }
    }
}

Mit dieser Implementierung kann der TextGeometryBuilder auch via XAML verwendet werden. So kann man ihn als Ressource zur Verfügung stellen:

<ext:TextGeometryBuilder x:Key="MyGeometry" 
                         Text="M" 
                         FontFamily="Tahoma" 
                         FontSize="14" 
                         FontWeight="Bold" 
                         Origin="5,5"/>

Die eigentliche Besonderheit stellt aber der interne Cache dar. Dieser merkt sich die resultierenden Geometry-Objekte und die korrespondierenden Texte. Dadurch kann bei häufiger Verwendung mit gleichen Texten viel Zeit gespart werden. Unterschiedliche Konfigurationen für denselben Text sind in dieser Variante nicht vorgesehen.

Die definierte Ressource kann nun wie folgt verwendet werden (hier am Beispiel eines User Controls):

<Grid>
    <Ellipse 
    StrokeThickness="3"
    Stroke="Black" Fill="White"
        x:Name="Elli"/>
    <Path Data="{Binding Source={StaticResource MyGeometry}, Path=Geometry}" 
          Fill="Black"/>
</Grid>

Viel Spaß damit.

Veröffentlicht von Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Cookie-Einstellungen
Auf dieser Website werden Cookie verwendet. Diese werden für den Betrieb der Website benötigt oder helfen uns dabei, die Website zu verbessern.
Alle Cookies zulassen
Auswahl speichern
Individuelle Einstellungen
Individuelle Einstellungen
Dies ist eine Übersicht aller Cookies, die auf der Website verwendet werden. Sie haben die Möglichkeit, individuelle Cookie-Einstellungen vorzunehmen. Geben Sie einzelnen Cookies oder ganzen Gruppen Ihre Einwilligung. Essentielle Cookies lassen sich nicht deaktivieren.
Speichern
Abbrechen
Essenziell (1)
Essenzielle Cookies werden für die grundlegende Funktionalität der Website benötigt.
Cookies anzeigen