Compartilhar via


Formatação de Texto Avançada

O Windows Presentation Foundation (WPF) fornece um conjunto robusto de APIs para incluir o texto em seu aplicativo. Layout and user interface (UI) APIs, such as TextBlock, provide the most common and general use elements for text presentation. Desenho APIs, como GlyphRunDrawing e FormattedText, que fornecem um meio para incluir texto formatado em desenhos. No máximo nível Avançado, WPF fornece um texto extensível formatação mecanismo para controlar todos os aspectos da apresentação de texto, como gerenciamento de armazenamento de texto, o gerenciamento de formatação de texto executar e o gerenciamento do objeto incorporado.

This topic provides an introduction to WPF text formatting. It focuses on client implementation and use of the WPF text formatting engine.

Observação

Todos os exemplos de código neste documento podem ser encontrados no Exemplo de formatação de texto avançado.

Este tópico contém as seguintes seções.

  • Prerequisites
  • Advanced Text Formatting
  • Using the Text Formatter
  • Implementing the Client Text Store
  • Providing Text Runs
  • Specifying Formatting Properties
  • Tópicos relacionados

Prerequisites

This topic assumes that you are familiar with the higher level APIs used for text presentation. Most user scenarios will not require the advanced text formatting APIs discussed in this topic. For an introduction to the different text APIs, see Documentos no WPF.

Advanced Text Formatting

The text layout and UI controls in WPF provide formatting properties that allow you to easily include formatted text in your application. These controls expose a number of properties to handle the presentation of text, which includes its typeface, size, and color. Under ordinary circumstances, these controls can handle the majority of text presentation in your application. No entanto, alguns cenários avançados exigem o controle do armazenamento de texto, bem como a apresentação de texto. WPFFornece um mecanismo para essa finalidade de formatação de texto extensível.

The advanced text formatting features found in WPF consist of a text formatting engine, a text store, text runs, and formatting properties. The text formatting engine, TextFormatter, creates lines of text to be used for presentation. This is achieved by initiating the line formatting process and calling the text formatter's FormatLine. O formatador de texto recupera o texto execuções do seu armazenamento de texto chamando o armazenamento GetTextRun método. The TextRun objects are then formed into TextLine objects by the text formatter and given to your application for inspection or display.

Using the Text Formatter

TextFormatter is the WPF text formatting engine and provides services for formatting and breaking text lines. The text formatter can handle different text character formats and paragraph styles, and includes support for international text layout.

Unlike a traditional text API, the TextFormatter interacts with a text layout client through a set of callback methods. It requires the client to provide these methods in an implementation of the TextSource class. The following diagram illustrates the text layout interaction between the client application and TextFormatter.

Interaction between application and TextFormatter

Diagrama de cliente de layout de texto e TextFormatter

The text formatter is used to retrieve formatted text lines from the text store, which is an implementation of TextSource. This is done by first creating an instance of the text formatter by using the Create method. This method creates an instance of the text formatter and sets the maximum line height and width values. Assim que uma instância de formatador de texto é criada, o processo de criação de linha é iniciado chamando o FormatLine método. TextFormatterchama de volta para a fonte de texto para recuperar o texto e os parâmetros de formatação para a execução do texto que formam uma linha.

In the following example, the process of formatting a text store is shown. The TextFormatter object is used to retrieve text lines from the text store and then format the text line for drawing into the 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;

Implementing the Client Text Store

When you extend the text formatting engine, you are required to implement and manage all aspects of the text store. This is not a trivial task. The text store is responsible for tracking text run properties, paragraph properties, embedded objects, and other similar content. It also provides the text formatter with individual TextRun objects which the text formatter uses to create TextLine objects.

Para lidar com a virtualização do armazenamento de texto, o armazenamento de texto deve ser derivado de TextSource. TextSourceDefine o método que o formatador de texto usa para recuperar o texto de execuções do armazenamento de texto. GetTextRuné o método usado pelo formatador de texto para recuperar texto executa usado na formatação de linha. The call to GetTextRun is repeatedly made by the text formatter until one of the following conditions occurs:

  • A TextEndOfLine or a subclass is returned.

  • The accumulated width of text runs exceeds the maximum line width specified in either the call to create the text formatter or the call to the text formatter's FormatLine method.

  • A Unicode newline sequence, such as "CF", "LF", or "CRLF", is returned.

Providing Text Runs

The core of the text formatting process is the interaction between the text formatter and the text store. Your implementation of TextSource provides the text formatter with the TextRun objects and the properties with which to format the text runs. This interaction is handled by the GetTextRun method, which is called by the text formatter.

The following table shows some of the predefined TextRun objects.

TextRun Type

Usage

TextCharacters

The specialized text run used to pass a representation of character glyphs back to the text formatter.

TextEmbeddedObject

The specialized text run used to provide content in which measuring, hit testing, and drawing is done in whole, such as a button or image within the text.

TextEndOfLine

The specialized text run used to mark the end of a line.

TextEndOfParagraph

The specialized text run used to mark the end of a paragraph.

TextEndOfSegment

The specialized text run used to mark the end of a segment, such as to end the scope affected by a previous TextModifier run.

TextHidden

The specialized text run used to mark a range of hidden characters.

TextModifier

The specialized text run used to modify properties of text runs in its scope. The scope extends to the next matching TextEndOfSegment text run, or the next TextEndOfParagraph.

Any of the predefined TextRun objects can be subclassed. This allows your text source to provide the text formatter with text runs that include custom data.

The following example demonstrates a GetTextRun method. This text store returns TextRun objects to the text formatter for processing.

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

Observação

In this example, the text store provides the same text properties to all of the text.Advanced text stores would need to implement their own span management to allow individual characters to have different properties.

Specifying Formatting Properties

TextRun objects are formatted by using properties provided by the text store. Essas propriedades vêm em dois tipos, TextParagraphProperties e TextRunProperties. TextParagraphPropertiesmanipular propriedades inclusive de parágrafo, como TextAlignment e FlowDirection. TextRunPropertiessão propriedades que podem ser diferentes para cada texto executado dentro de um parágrafo, como, por exemplo, o pincel de primeiro plano, Typefacee tamanho de fonte. To implement custom paragraph and custom text run property types, your application must create classes that derive from TextParagraphProperties and TextRunProperties respectively.

Consulte também

Conceitos

Tipologia no WPF

Documentos no WPF