Freigeben über


Erweiterte Textformatierung

Die Windows Presentation Foundation (WPF) stellt einen stabilen Satz von APIs zur Verfügung, mit denen Ihrer Anwendung Text hinzugefügt werden kann. Layout und user interface (UI) APIs, wie z. B. TextBlock, stellen allgemeine und am häufigsten verwendete Elemente für die Textdarstellung bereit. Zeichnungs-APIs, wie z. B. GlyphRunDrawing und FormattedText, stellen eine Methode zum Darstellen von formatiertem Text in Zeichnungen bereit. Auf höchster Ebene stellt WPF ein erweiterbares Textformatierungsmodul bereit, mit dem jeder Aspekt der Textdarstellung gesteuert werden kann, wie zum Beispiel die Textspeicherverwaltung, Verwaltung der Textausführungsformatierung und Verwaltung von eingebetteten Objekten.

Dieses Thema bietet eine Einführung in die WPF-Textformatierung. Das Hauptaugenmerk liegt in diesem Thema auf der Clientimplementierung und Verwendung des WPF-Textformatierungsmoduls.

HinweisHinweis

Alle in diesem Dokument aufgeführten Codebeispiele finden Sie unter Beispiel für die erweiterte Textformatierung.

Dieses Thema enthält folgende Abschnitte.

  • Voraussetzungen
  • Erweiterte Textformatierung
  • Verwenden des Textformatierungsprogramms
  • Implementieren des Clienttextspeichers
  • Bereitstellen von Textausführungen
  • Festlegen von Formatierungseigenschaften
  • Verwandte Abschnitte

Voraussetzungen

In diesem Thema wird davon ausgegangen, dass Sie mit den APIs höherer Ebene, die für die Textdarstellung verwendet werden, vertraut sind. Für die meisten Benutzerszenarien werden die APIs für die erweiterte Textformatierung, die in diesem Thema erläutert werden, nicht benötigt. Eine Einführung in die verschiedenen Text-APIs finden Sie unter Dokumente in WPF.

Erweiterte Textformatierung

Die Textlayout- und UI-Steuerelemente in WPF stellen Formatierungseigenschaften zur Verfügung, mit denen Sie auf einfache Weise formatierten Text in Ihre Anwendung einbeziehen können. Diese Steuerelemente machen eine Reihe von Eigenschaften verfügbar, mit denen die Darstellung von Text gehandhabt werden kann, einschließlich Schriftart, Größe und Farbe. Unter normalen Umständen können diese Steuerelemente den Großteil der Textdarstellung in Ihrer Anwendung verarbeiten. Einige erweiterte Szenarien erfordern jedoch häufig auch die Steuerung des Textspeichers neben der Textdarstellung. Zu diesem Zweck stellt WPF ein erweitertes Textformatierungsmodul bereit.

Die von WPF bereitgestellten erweiterten Funktionen für die Textformatierung umfassen ein Textformatierungsmodul, einen Textspeicher, Textausführungen und Formatierungseigenschaften. Das Textformatierungsmodul TextFormatter erstellt Textzeilen, die für die Darstellung verwendet werden können. Dies wird durch die Initialisierung des Zeilenformatierungsprozesses und das Aufrufen von FormatLine des Textformatierungsprogramms erreicht. Das Textformatierungsprogramm ruft Textausführungen aus dem Textspeicher ab, indem die GetTextRun-Methode des Speichers aufgerufen wird. Die TextRun-Objekte werden dann vom Textformatierungsprogramm in TextLine-Objekte umgewandelt und an die Anwendung zur Überprüfung oder Anzeige weitergegeben.

Verwenden des Textformatierungsprogramms

TextFormatter ist das Textformatierungsmodul von WPF und stellt Dienste zum Formatieren und Umbrechen von Textzeilen zur Verfügung. Das Textformatierungsprogramm kann verschiedene Textzeichenformate und Absatzstile verarbeiten und bietet Unterstützung für internationale Textlayouts.

Im Gegensatz zu einer herkömmlichen Text-API interagiert der TextFormatter mit einem Textlayoutclient über eine Reihe von Rückrufmethoden. Hierfür ist erforderlich, dass der Client diese Methoden in einer Implementierung der TextSource-Klasse bereitstellt. Im folgenden Diagramm wird die Textlayoutinteraktion zwischen der Clientanwendung und TextFormatter veranschaulicht.

Interaktion zwischen Anwendung und TextFormatter

Diagramm des Textlayout-Clients und TextFormatter

Das Textformatierungsprogramm wird zum Abrufen formatierter Textzeilen aus dem Textspeicher verwendet, wobei es sich um die Implementierung von TextSource handelt. Hierzu wird zunächst eine Instanz des Textformatierungsprogramms mit der Create-Methode erstellt. Diese Methode erstellt eine Instanz des Textformatierungsprogramms und legt Werte für die maximale Zeilenhöhe und -breite fest. Nachdem eine Instanz des Textformatierungsprogramms erstellt wurde, wird der Zeilenerstellungsvorgang gestartet, indem die FormatLine-Methode aufgerufen wird. TextFormatter ruft die Text- und Formatierungsparameter für die Textausführungen, die eine Zeile bilden, erneut aus der Textquelle ab.

Im folgenden Beispiel wird dargestellt, wie ein Textspeicher formatiert wird. Das TextFormatter-Objekt wird zum Abrufen von Textzeilen aus dem Textspeicher und zum anschließenden Formatieren der Textzeilen zum Zeichnen im DrawingContext verwendet.

         ' Create a DrawingGroup object for storing formatted text.
         textDest = New DrawingGroup()
         Dim dc As DrawingContext = textDest.Open()

         ' Update the text store.
         _textStore.Text = textToFormat.Text
         _textStore.FontRendering = _currentRendering

         ' Create a TextFormatter object.
         Dim formatter As TextFormatter = TextFormatter.Create()

         ' Format each line of text from the text store and draw it.
         Do While textStorePosition < _textStore.Text.Length
            ' Create a textline from the text store using the TextFormatter object.
            Using myTextLine As TextLine = formatter.FormatLine(_textStore, textStorePosition, 96*6, New GenericTextParagraphProperties(_currentRendering), Nothing)
                ' Draw the formatted text into the drawing context.
                myTextLine.Draw(dc, linePosition, InvertAxes.None)

                ' Update the index position in the text store.
                textStorePosition += myTextLine.Length

                ' Update the line position coordinate for the displayed line.
                linePosition.Y += myTextLine.Height
            End Using
         Loop

         ' Persist the drawn text content.
         dc.Close()

         ' Display the formatted text in the DrawingGroup object.
         myDrawingBrush.Drawing = textDest
// Create a DrawingGroup object for storing formatted text.
textDest = new DrawingGroup();
DrawingContext dc = textDest.Open();

// Update the text store.
_textStore.Text = textToFormat.Text;
_textStore.FontRendering = _currentRendering;

// Create a TextFormatter object.
TextFormatter formatter = TextFormatter.Create();

// Format each line of text from the text store and draw it.
while (textStorePosition < _textStore.Text.Length)
{
   // Create a textline from the text store using the TextFormatter object.
   using (TextLine myTextLine = formatter.FormatLine(
       _textStore,
       textStorePosition,
       96*6,
       new GenericTextParagraphProperties(_currentRendering),
       null))
   {
       // Draw the formatted text into the drawing context.
       myTextLine.Draw(dc, linePosition, InvertAxes.None);

       // Update the index position in the text store.
       textStorePosition += myTextLine.Length;

       // Update the line position coordinate for the displayed line.
       linePosition.Y += myTextLine.Height;
   }
}

// Persist the drawn text content.
dc.Close();

// Display the formatted text in the DrawingGroup object.
myDrawingBrush.Drawing = textDest;

Implementieren des Clienttextspeichers

Wenn Sie das Textformatierungsmodul erweitern, müssen Sie alle Aspekte des Textspeichers implementieren und verwalten. Dies ist keine einfache Aufgabe. Der Textspeicher ist verantwortlich für die Nachverfolgung von Textausführungseigenschaften, Absatzeigenschaften, eingebetteten Objekten und anderem ähnlichen Inhalt. Er stellt dem Textformatierungsprogramm außerdem einzelne TextRun-Objekte zur Verfügung, mit dem das Textformatierungsprogramm TextLine-Objekte erstellt.

Um die Virtualisierung des Textspeichers zu behandeln, muss der Textspeicher von der TextSource abgeleitet werden. TextSource definiert die Methode, die vom Textformatierungsprogramm verwendet wird, um Textausführungen aus dem Textspeicher abzurufen. GetTextRun ist die Methode, die vom Textformatierungsprogramm zum Abrufen von Textausführungen für die Zeilenformatierung verwendet wird. Das Textformatierungsprogramm ruft GetTextRun wiederholt auf, bis eine der folgenden Bedingungen auftritt:

  • Es wird TextEndOfLine oder eine Unterklasse zurückgegeben.

  • Die kumulierte Breite von Textausführungen überschreitet die maximale Zeilenbreite, die entweder im Aufruf zum Erstellen des Textformatierungsprogramms oder im Aufruf der FormatLine-Methode des Textformatierungsprogramms festgelegt ist.

  • Es wird eine Unicode-Zeilenumbruchsequenz wie "CF", "LF" oder "CRLF" zurückgegeben.

Bereitstellen von Textausführungen

Kern des Textformatierungsprozesses ist das Zusammenwirken von Textformatierungsprogramm und Textspeicher. Ihre Implementierung von TextSource liefert dem Textformatierungsprogramm die TextRun-Objekte und Eigenschaften, mit denen die Textausführungen formatiert werden sollen. Diese Interaktion wird von der GetTextRun-Methode behandelt, die vom Textformatierungsprogramm aufgerufen wird.

In der folgenden Tabelle sind einige der vordefinierten TextRun-Objekte aufgeführt.

TextRun-Typ

Verwendung

TextCharacters

Die spezialisierte Textausführung, die verwendet wird, um eine Darstellung von Zeichensymbolen an das Textformatierungsprogramm zu übergeben.

TextEmbeddedObject

Die spezialisierte Textausführung, die zum Bereitstellen von Inhalt verwendet wird, bei dem das Messen, der Treffertest und das Zeichnen in einem Schritt durchgeführt wird, wie z. B. eine Schaltfläche oder ein Bild im Text.

TextEndOfLine

Die spezialisierte Textausführung, die zum Markieren des Zeilenendes verwendet wird.

TextEndOfParagraph

Die spezialisierte Textausführung, die zum Markieren des Absatzendes verwendet wird.

TextEndOfSegment

Die spezialisierte Textausführung, die zum Markieren des Segmentendes verwendet wird, wie z. B. das Ende des Bereichs, auf den sich eine vorherige TextModifier-Ausführung auswirkt.

TextHidden

Die spezialisierte Textausführung, die zum Markieren eines Bereichs mit verborgenen Zeichen verwendet wird.

TextModifier

Die spezialisierte Textausführung, die zum Ändern der Eigenschaften von Textausführungen in ihrem Bereich verwendet wird. Der Bereich erstreckt sich bis zur nächsten entsprechenden TextEndOfSegment-Textausführung oder zum nächsten TextEndOfParagraph.

Jedes vordefinierte TextRun-Objekt kann als Unterklasse definiert werden. Dies ermöglicht der Textquelle, dem Textformatierungsprogramm Textausführungen bereitzustellen, die benutzerdefinierte Daten enthalten.

Im folgenden Beispiel wird eine GetTextRun-Methode veranschaulicht. Dieser Textspeicher gibt TextRun-Objekte zur Verarbeitung an das Textformatierungsprogramm zurück.

      ' Used by the TextFormatter object to retrieve a run of text from the text source.
      Public Overrides Function GetTextRun(ByVal textSourceCharacterIndex As Integer) As TextRun
         ' Make sure text source index is in bounds.
         If textSourceCharacterIndex < 0 Then
            Throw New ArgumentOutOfRangeException("textSourceCharacterIndex", "Value must be greater than 0.")
         End If
         If textSourceCharacterIndex >= _text.Length Then
            Return New TextEndOfParagraph(1)
         End If

         ' Create TextCharacters using the current font rendering properties.
         If textSourceCharacterIndex < _text.Length Then
            Return New TextCharacters(_text, textSourceCharacterIndex, _text.Length - textSourceCharacterIndex, New GenericTextRunProperties(_currentRendering))
         End If

         ' Return an end-of-paragraph if no more text source.
         Return New TextEndOfParagraph(1)
      End Function
// Used by the TextFormatter object to retrieve a run of text from the text source.
public override TextRun GetTextRun(int textSourceCharacterIndex)
{
   // Make sure text source index is in bounds.
   if (textSourceCharacterIndex < 0)
      throw new ArgumentOutOfRangeException("textSourceCharacterIndex", "Value must be greater than 0.");
   if (textSourceCharacterIndex >= _text.Length)
   {
      return new TextEndOfParagraph(1);
   }

   // Create TextCharacters using the current font rendering properties.
   if (textSourceCharacterIndex < _text.Length)
   {
      return new TextCharacters(
         _text,
         textSourceCharacterIndex,
         _text.Length - textSourceCharacterIndex,
         new GenericTextRunProperties(_currentRendering));
   }

   // Return an end-of-paragraph if no more text source.
   return new TextEndOfParagraph(1);
}
HinweisHinweis

In diesem Beispiel stellt der Textspeicher dem gesamten Text die gleichen Texteigenschaften bereit.Erweiterte Textspeicher müssten ihre eigene Abschnittsverwaltung implementieren, um zu ermöglichen, dass einzelne Zeichen über verschiedene Eigenschaften verfügen können.

Festlegen von Formatierungseigenschaften

TextRun-Objekte werden anhand der vom Textspeicher bereitgestellten Eigenschaften formatiert. Es gibt zwei Arten dieser Eigenschaften: TextParagraphProperties und TextRunProperties. TextParagraphProperties verarbeiten nur auf Abschnitte bezogene Eigenschaften wie TextAlignment und FlowDirection. TextRunProperties sind Eigenschaften, die sich für jede Textausführung in einem Abschnitt unterscheiden können, wie zum Beispiel der Vordergrundpinsel, Typeface und Schriftgröße. Um benutzerdefinierte Absatz- und Textausführungs-Eigenschaftentypen erstellen zu können, muss Ihre Anwendung Klassen erstellen, die sich von TextParagraphProperties bzw. TextRunProperties ableiten.

Siehe auch

Konzepte

Typografie in WPF

Dokumente in WPF