Mise en forme de texte avancée

Windows Presentation Foundation (WPF) fournit un ensemble fiable d'APIs pour inclure du texte dans votre application. Layout et user interface (UI)APIs, tel que TextBlock, fournissent les éléments d'utilisation les plus courants et généraux pour la présentation de texte. L'APIs de dessin, telle que GlyphRunDrawing et FormattedText permet d'inclure du texte mis en forme dans des dessins. Au niveau le plus avancé, WPF, fournit un moteur de mise en forme de texte extensible pour contrôler chaque aspect de la présentation de texte, tel que la gestion du magasin de texte, la gestion de séquence de texte et la gestion d'objet incorporé.

Cette rubrique présente la mise en forme du texte WPF. Elle porte principalement sur l'implémentation cliente et l'utilisation du moteur de mise en forme du texte WPF.

RemarqueRemarque

Tous les exemples de code dans ce document se trouvent dans Mise en forme de texte avancée, exemple.

Cette rubrique comprend les sections suivantes.

  • Composants requis
  • Mise en forme de texte avancée
  • Utilisation du formateur de texte
  • Implémentation du magasin de texte client
  • Fourniture des séquences de texte
  • Spécification des propriétés de mise en forme
  • Rubriques connexes

Composants requis

Cette rubrique suppose que vous connaissez le niveau supérieur APIs utilisé pour la présentation de texte. La plupart des scénarios utilisateur ne nécessitent pas les APIs de mise en forme de texte avancée décrites dans cette rubrique. Pour une présentation des différentes APIs texte, consultez Documents dans WPF.

Mise en forme de texte avancée

La mise en page de texte et les contrôles UI dans WPF fournissent des propriétés de mise en forme qui permettent d'inclure facilement le texte mis en forme dans votre application. Ces contrôles exposent des propriétés pour gérer la présentation de texte, ce qui inclut sa police, sa taille et sa couleur. Dans des conditions normales, ces contrôles peuvent gérer la majorité de la présentation de texte dans votre application. Cependant, certains scénarios avancés requièrent le contrôle du stockage de texte ainsi que la présentation du texte. WPF fournit un moteur de mise en forme du texte extensible dans ce but.

Les fonctionnalités de mise en forme de texte avancée dans WPF sont constituées d'un moteur de mise en forme de texte, d'un magasin de texte, de séquences de texte et de propriétés de mise en forme. Le moteur de mise en forme du texte, TextFormatter, crée des lignes de texte à utiliser pour la présentation. Cela est accompli en initialisant le processus de la mise en forme de ligne et en appelant les FormatLine du formateur de texte. Le formateur de texte récupère les séquences de texte de votre magasin de texte en appelant la méthode GetTextRun du magasin. Ensuite, les objets TextRun sont transformés en objets TextLine par le formateur de texte et transmis à votre application pour l'inspection ou l'affichage.

Utilisation du formateur de texte

TextFormatter est le moteur de mise en forme du texte WPF et il fournit des services pour mettre en forme et couper des lignes de texte. Le formateur de texte peut gérer différents formats de caractères alphabétiques et il prend en charge la présentation de texte internationale.

Contrairement à une API texte traditionnelle, le TextFormatter interagit avec le client de disposition de texte par l'intermédiaire d'un ensemble de méthodes de rappel. Cela suppose que le client fournisse ces méthodes dans une implémentation de la classe TextSource. Le diagramme suivant montre l'interaction de la disposition du texte entre l'application cliente et TextFormatter.

Interaction entre l'application et TextFormatter

Diagramme du client de disposition du texte et TextFormatter

Le formateur de texte est utilisé pour récupérer des lignes de texte mis en forme dans le magasin de texte qui est une implémentation de TextSource. Cette opération est effectuée en créant une instance du formateur de texte et en utilisant la méthode Create. Cette méthode crée une instance du formateur de texte et définit la hauteur et la largeur de ligne maximales. Dès qu'une instance du formateur de texte est créée, le processus de création de ligne est démarré en appelant la méthode FormatLine. TextFormatter rappelle la source de texte pour récupérer le texte et les paramètres de mise en forme pour les séries de texte qui forment une ligne.

L'exemple suivant montre le processus de mise en forme d'un magasin de texte. L'objet TextFormatter est utilisé pour récupérer des lignes de texte du magasin de texte et mettre en forme la ligne de texte pour la placer dans le DrawingContext.

         ' 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;

Implémentation du magasin de texte client

Lorsque vous étendez le moteur de mise en forme du texte, vous devez implémenter et gérer tous les aspects du magasin de texte. Ce n'est pas une tâche simple. Le magasin de texte est chargé de suivre les propriétés de séquence de texte, les propriétés de paragraphe, les objets incorporés et tout autre contenu semblable. Il fournit également au formateur de texte des objets TextRun individuels que le formateur de texte utilise pour créer des objets TextLine.

Pour gérer la virtualisation du magasin de texte, le magasin de texte doit être dérivé de TextSource. TextSource définit la méthode que le formateur de texte utilise pour récupérer les séquences de texte du magasin de texte. GetTextRun est la méthode utilisée par le formateur de texte pour récupérer les séquences de texte utilisées dans la mise en forme de ligne. L'appel à GetTextRun est exécuté de manière répétitive par le formateur de texte jusqu'à ce que l'une des conditions suivantes existe :

  • Un TextEndOfLine ou une sous-classe sont retournés.

  • La largeur cumulée des séquences de texte dépasse la largeur de ligne maximale spécifiée dans l'appel pour créer le formateur de texte ou l'appel à la méthode FormatLine du formateur de texte.

  • Une séquence de saut de ligne Unicode, telle que "CF", "LF" ou "CRLF", est retournée.

Fourniture des séquences de texte

Le cœur du processus de mise en forme du texte est l'interaction entre le formateur de texte et le magasin de texte. Votre implémentation TextSource fournit au formateur de texte les objets et les propriétés TextRun nécessaires à la mis en forme des séquences de texte. Cette interaction est contrôlée par la méthode GetTextRun appelée par le formateur de texte.

Le tableau suivant répertorie certains des objets TextRun prédéfinis.

Type TextRun

Utilisation

TextCharacters

Séquence de texte spécialisée utilisée pour renvoyer une représentation des glyphes de caractères au formateur de texte.

TextEmbeddedObject

La séquence de texte spécialisée utilisée pour fournir le contenu de mesure, le test de positionnement et le dessin est effectuée globalement, tel qu'un bouton ou une image dans le texte.

TextEndOfLine

Séquence de texte spécialisée utilisée pour marquer la fin d'une ligne.

TextEndOfParagraph

Séquence de texte spécialisée utilisée pour marquer la fin d'un paragraphe.

TextEndOfSegment

Séquence de texte spécialisée utilisée pour marquer la fin d'un segment, pour terminer, par exemple, la portée affectée par une séquence TextModifier précédente.

TextHidden

Séquence de texte spécialisée utilisée pour marquer une plage de caractères cachés.

TextModifier

Séquence de texte spécialisée utilisée pour modifier les propriétés de séquences de texte dans sa portée. La portée s'étend à la séquence de texte TextEndOfSegment correspondante suivante ou au TextEndOfParagraph suivant.

Chacun des objets TextRun prédéfinis peut être sous-classé. Cela permet à la source de texte de fournir au formateur de texte des séquences de texte qui incluent des données personnalisées.

L'exemple de code suivant montre une méthode GetTextRun. Ce magasin de texte retourne des objets TextRun au formateur de texte pour les traiter.

      ' 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);
}
RemarqueRemarque

Dans cet exemple, le magasin de texte fournit les mêmes propriétés de texte à l'ensemble du texte.Les magasins de textes avancés doivent implémenter leur propre gestion de plage pour que les caractères individuels aient des propriétés différentes.

Spécification des propriétés de mise en forme

Les objets TextRun sont mis en forme en utilisant les propriétés fournies par le magasin de texte. Ces propriétés sont de deux types, TextParagraphProperties et TextRunProperties. TextParagraphProperties gère les propriétés de paragraphe telles que TextAlignment et FlowDirection. TextRunProperties sont des propriétés qui peuvent être différentes pour chaque séquence de texte au sein d'un paragraphe, tel que le pinceau de premier plan, Typeface et taille de police. Pour implémenter des types de propriétés de paragraphe personnalisé et de séquence de texte personnalisé, votre application doit créer des classes dérivées de TextParagraphProperties et de TextRunProperties, respectivement.

Voir aussi

Concepts

Typographie dans WPF

Documents dans WPF