Sdílet prostřednictvím


Rozšířené formátování textu

Windows Presentation Foundation (WPF) poskytuje robustní sadu rozhraní API pro zahrnutí textu do aplikace. Rozhraní API pro rozložení a uživatelské rozhraní (UI), jako je například TextBlock, poskytují nejběžnější a nejobecnější prvky pro prezentaci textu. Rozhraní kreslení API, jako GlyphRunDrawing a FormattedText, poskytují prostředky pro zahrnutí formátovaného textu do kreseb. WpF na nejpokročilejší úrovni poskytuje rozšiřitelný modul pro formátování textu, který řídí všechny aspekty textové prezentace, jako je správa úložiště textu, správa formátování textu a správa vložených objektů.

Toto téma obsahuje úvod do formátování textu WPF. Zaměřuje se na implementaci klienta a použití modulu formátování textu WPF.

Poznámka:

Všechny příklady kódu v tomto dokumentu najdete v ukázce rozšířeného formátování textu.

Požadavky

V tomto tématu se předpokládá, že znáte rozhraní API vyšší úrovně používaná pro textovou prezentaci. Většina uživatelských scénářů nevyžaduje rozhraní API pro pokročilé formátování textu popsané v tomto tématu. Úvod do různých textových rozhraní API najdete v tématu Dokumenty ve WPF.

Rozšířené formátování textu

Ovládací prvky rozložení textu a uživatelského rozhraní ve WPF poskytují vlastnosti formátování, které umožňují snadno zahrnout do aplikace formátovaný text. Tyto ovládací prvky zpřístupňují řadu vlastností pro zpracování prezentace textu, která zahrnuje jeho typ písma, velikost a barvu. Za běžných okolností můžou tyto ovládací prvky zpracovávat většinu textové prezentace ve vaší aplikaci. Některé pokročilé scénáře ale vyžadují kontrolu nad textovým úložištěm i textová prezentace. WPF poskytuje rozšiřitelný modul pro formátování textu pro tento účel.

Pokročilé funkce formátování textu nalezené ve WPF se skládají z modulu formátování textu, úložiště textu, spuštění textu a vlastností formátování. Modul TextFormatterpro formátování textu vytvoří řádky textu, které se mají použít pro prezentaci. Toho dosáhnete zahájením procesu formátování řádku a voláním formátovače FormatLinetextu . Formátovací modul textu načte úseky textu z vašeho úložiště textu voláním jeho metody GetTextRun. Objekty TextRun se pak vytvoří do TextLine objektů pomocí textového formátovače a předají vaší aplikaci pro kontrolu nebo zobrazení.

Použití formátovače textu

TextFormatter je modul pro formátování textu WPF a poskytuje služby pro formátování a dělení řádků textu. Formátovací modul textu dokáže zpracovat různé formáty textových znaků a styly odstavců a zahrnuje podporu pro mezinárodní rozložení textu.

Na rozdíl od tradičního textového rozhraní API TextFormatter komunikuje s klientem rozložení textu prostřednictvím sady metod zpětného volání. Vyžaduje, aby klient poskytl tyto metody v implementaci třídy TextSource. Následující diagram znázorňuje interakci rozložení textu mezi klientskou aplikací a TextFormatter.

Diagram rozložení textu klienta a TextFormatter

Formátovací modul textu se používá k načtení formátovaných textových řádků z textového úložiště, což je implementace TextSource. To se provádí tak, že nejprve pomocí metody vytvoříte instanci textového formátovače Create . Tato metoda vytvoří instanci textového formátovače a nastaví maximální hodnoty pro výšku a šířku řádku. Jakmile se vytvoří instance textového formátovače, proces vytvoření řádku se spustí voláním FormatLine metody. TextFormatter volá k textovému zdroji, aby načetl parametry textu a formátování pro segmenty textu, které tvoří řádek.

V následujícím příkladu se zobrazí proces formátování textového úložiště. Objekt TextFormatter slouží k načtení textových řádků z textového úložiště a následnému naformátování textového řádku pro kreslení do objektu DrawingContext.

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

Implementace úložiště textu klienta

Když rozšíříte modul formátování textu, budete muset implementovat a spravovat všechny aspekty úložiště textu. Toto není triviální úkol. Úložiště textu zodpovídá za sledování vlastností spuštění textu, vlastností odstavce, vložených objektů a dalšího podobného obsahu. Poskytuje také textový formátovací modul s jednotlivými TextRun objekty, které textový formátovací modul používá k vytváření TextLine objektů.

Aby bylo možné zpracovat virtualizaci textového úložiště, musí být textové úložiště odvozeno z TextSource. TextSource definuje metodu, pomocí které formátovací modul textu načítá text z úložiště textu. GetTextRun je metoda používaná textovým formátovacím programem k načtení běhů textu použitých při formátování řádků. Volání GetTextRun je opakovaně prováděno formátovacím modulem textu, dokud nenastane jedna z následujících podmínek:

  • Vrátí se TextEndOfLine nebo podtřída.

  • Kumulovaná šířka textových úseků překračuje maximální šířku řádku zadanou buď při volání pro vytvoření formátovače textu, nebo při volání metody textového FormatLine formátovače.

  • Vrátí se sekvence nového řádku Unicode, například CF, LF nebo CRLF.

Poskytování řetězců textu

Jádrem procesu formátování textu je interakce mezi formátovačem textu a úložištěm textu. Vaše implementace TextSource poskytuje textovému formátovacímu modulu objekty TextRun a vlastnosti, se kterými se formátují části textu. Tuto interakci zpracovává GetTextRun metoda, která je volána textovým formátovačem.

Následující tabulka uvádí některé předdefinované TextRun objekty.

Typ textového spuštění Použití
TextCharacters Specializovaný textový běh se používá k předání reprezentace glyfových znaků zpět do textového formátovače.
TextEmbeddedObject Specializovaný textový segment se používá k poskytování obsahu, ve kterém se provádí měření, zachytávání událostí a kreslení jako celek, například tlačítko nebo obrázek v textu.
TextEndOfLine Specializovaný text se používá k označení konce řádku.
TextEndOfParagraph Specializovaný text se používá k označení konce odstavce.
TextEndOfSegment Specializovaný textový úsek, který slouží k označení konce segmentu, například k ukončení oblasti ovlivněné předchozím TextModifier úsekem.
TextHidden Specializovaný úsek textu používaný k označení rozsahu skrytých znaků.
TextModifier Specializovaný běh textu slouží k úpravě vlastností textových běhů v rámci jeho působnosti. Rozsah se rozšiřuje na další odpovídající část textu TextEndOfSegment, nebo na další TextEndOfParagraph.

Libovolný z předdefinovaných TextRun objektů může být podtříděn. To umožňuje zdroji textu poskytnout textovému formátovači textové části, které obsahují vlastní data.

Následující příklad ukazuje metodu GetTextRun . Toto textové úložiště vrací TextRun objekty do textového formátovače pro zpracování.

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

Poznámka:

V tomto příkladu poskytuje úložiště textu stejné vlastnosti textu pro celý text. Pokročilá úložiště textu by musela implementovat vlastní správu rozsahu, aby jednotlivé znaky měly různé vlastnosti.

Určení vlastností formátování

TextRun objekty jsou formátovány pomocí vlastností poskytovaných textovým úložištěm. Tyto vlastnosti se dodávají ve dvou typech, TextParagraphProperties a TextRunProperties. TextParagraphProperties popisovač inkluzivních vlastností odstavce, například TextAlignment a FlowDirection. TextRunProperties jsou vlastnosti, které se můžou lišit pro každý běh textu v rámci odstavce, například štětec popředí, Typeface velikost písma. Chcete-li implementovat vlastní typy vlastností odstavců a vlastní typy vlastností textu, musí vaše aplikace vytvořit třídy odvozené z TextParagraphProperties a TextRunProperties v uvedeném pořadí.

Viz také