Поделиться через


Дополнительное форматирование текста

Windows Presentation Foundation (WPF) предоставляет APIs — набор надежных инструментов для включения текста в приложение. Макет и user interface (UI) APIs, такие как TextBlock, предоставляют наиболее типично и обще-используемые элементы для представления текста. APIs для рисования, например GlyphRunDrawing и FormattedText, предоставляют возможность включения в рисунки форматированного текста. На наиболее продвинутом уровне WPF предоставляет расширенный механизм форматирования текста для управления каждым аспектом представления текста: управление хранением и исполнением форматирования текста, и управление внедренным объектом.

В этом разделе представлено введение в форматирование текста WPF. Основное внимание уделяется реализации клиента и использовании механизма форматирования текста WPF.

ПримечаниеПримечание

Все примеры кода в этом документе можно найти в разделе Пример расширенного форматирования текста.

В этом разделе содержатся следующие подразделы.

  • Предварительные требования
  • Дополнительное форматирование текста
  • Использование модуля форматирования текста
  • Реализация клиентского хранилища текста
  • Предоставление исполнений текста
  • Определение свойств форматирования
  • Связанные разделы

Предварительные требования

Чтение этого раздела предполагает знакомство с верхним уровнем APIs, использующегося для представлении текста. Большинство пользовательских скриптов не потребует дополнительного форматирования текста APIs, рассмотренного в этом разделе. Для введения в другой текст APIs см. Документы в WPF.

Дополнительное форматирование текста

Макет текста и элементы управления UI в WPF предоставляют свойства форматирования, позволяющие легко включать в приложение форматированный текст. Эти элементы управления предоставляют ряд свойств для обработки представления текста, включающие его гарнитуру, размер и цвет. В обычных условиях эти элементы управления могут обрабатывать большинство представлений текста в приложении. Однако в некоторых более сложных ситуациях требуется контроль процесса хранения текста наравне с контролем представления. WPF предоставляет для этой цели расширенный механизм форматирования текста.

Дополнительные функции форматирования текста, расположенные в WPF, состоят из механизма форматирования текста, хранилища текста, исполнения текста и свойств форматирования. Механизм форматирования текста, TextFormatter, создает строки текста, используемые для его представления. Это достигается путем инициирования процесса форматирования строки и вызовом модуля форматирования текста FormatLine. Модуль форматирования текста извлекает текстовые последовательности из хранилища текста путем вызова метода хранения GetTextRun. Затем объекты TextRun преобразуются в объекты TextLine с помощью модуля форматирования текста и передаются в приложение для проверки или отображения на экране.

Использование модуля форматирования текста

TextFormatter является механизмом форматирования текста WPF и служит для форматирования и разбивки строк текста. Модуль форматирования текста поддерживает различные форматы текстовых знаков и стили абзацев, а также включает поддержку международного макета текста.

В отличие от традиционного текстового API, объект TextFormatter взаимодействует с клиентом разметки текста через набор методов обратного вызова. Для предоставления этих методов в реализации класса TextSource требуется клиент. Следующая диаграмма иллюстрирует взаимодействие разметки текста между клиентским приложением и объектом TextFormatter.

Взаимодействие между приложением и объектом TextFormatter

Схема клиента структуры текста и TextFormatter

Модуль форматирования текста используется для извлечения форматированных строк текста из хранилища текста, которое является реализацией метода TextSource. Это осуществляется первоначальным созданием экземпляра модуля форматирования текста, путем использования метода Create. Этот метод создает экземпляр модуля форматирования текста и задает максимальные значения высоты и ширины строки. Как только экземпляр модуля форматирования текста создан, процесс создания строки запускается вызовом метода FormatLine. Объект TextFormatter выполняет обратный вызов метода к исходному тексту, чтобы извлечь текст и параметры форматирования для текстовых последовательностей, формирующих строку.

В следующем примере показан процесс форматирования хранилища текста. Объект TextFormatter используется для извлечения строк текста из хранилища текста и последующего форматирования строк текста для перемещения в 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;

Реализация клиентского хранилища текста

При расширении механизма форматирования текста потребуется реализовать и управлять аспектами хранилища текста. Это нетривиальная задача. Хранилище текста отвечает за отслеживание свойств исполнения текста, свойств абзаца, встроенных объектов и другого подобного содержимого. Оно также предоставляет модуль форматирования текста с индивидуальными объектами TextRun, которые модуль форматирования текста использует для создания объектов TextLine.

Для виртуализации хранилища текста оно должно быть производным от класса TextSource. Объект TextSource задает метод, используемый модулем форматирования текста для извлечения текстовых последовательностей из хранилища текста. Метод GetTextRun используется модулем форматирования текста для извлечения текстовых последовательностей, используемых в форматировании строки. Вызов GetTextRun неоднократно осуществляется модулем форматирования текста до тех пор, пока не выполняется одно из следующих условий:

  • Возвращается TextEndOfLine или подкласс.

  • Суммарная ширина исполнений текста превышает ширину строк, указанную или в вызове для создания модуля форматирования текста или в вызове метода FormatLine модуля форматирования текста.

  • Возвращается новая последовательность Unicode, такая как «CF», «LF», или «CRLF».

Предоставление исполнений текста

Ядром процесса форматирования текста является взаимодействие между модулем форматирования текста и хранилищем текста. Реализация TextSource предоставляет модуля форматирования текста с объектами TextRun и свойствами, с которыми форматируются исполнения текста. Это взаимодействие обрабатывается методом GetTextRun, который вызывается модулем форматирования текста.

В следующей таблице представлены некоторые из предварительно определенных объектов TextRun.

Тип TextRun

Использование

TextCharacters

Специализированное исполнение текста, используемое для обратной передачи глифов символа модулю форматирования текста.

TextEmbeddedObject

Специализированное исполнение текста используется для предоставления содержимого, в котором выполняются измерение, проверка наличия и рисование, такое как кнопка или изображения в тексте.

TextEndOfLine

Специализированное исполнение текста используется для отметки конца строки.

TextEndOfParagraph

Специализированное исполнение текста используется для отметки конца абзаца.

TextEndOfSegment

Специализированное исполнение текста используется для отметки конца сегмента, такого как конец области, на который влияет предыдущее исполнение TextModifier.

TextHidden

Специализированное исполнение текста используется для отметки диапазона скрытых знаков.

TextModifier

Специализированное исполнение текста используется для изменения свойств исполнений текста в его области. Область расширяется до следующего соответствия исполнению текста TextEndOfSegment или до следующего TextEndOfParagraph.

Любой из предварительно определенных объектов TextRun может быть подклассом. Это позволяет исходному тексту предоставлять модуль форматирования текста с исполнениями текста, включающими пользовательские данные.

В следующем примере демонстрируется использование метода GetTextRun. Этот хранилище текста возвращает объекты TextRun модулю форматирования текста для обработки.

      ' 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);
}
ПримечаниеПримечание

В этом примере, хранилище текста предоставляет те же свойства текста ко всему тексту.Дополнительные хранилища текста потребуют реализации управления их собственным диапазоном для того, чтобы позволить индивидуальным знакам иметь различные свойства.

Определение свойств форматирования

Объекты TextRun форматируются с помощью свойств, предоставляемых хранилищем текста. Такие свойства бывают двух типов: TextParagraphProperties и TextRunProperties. Класс TextParagraphProperties обрабатывает внутренние свойства параграфа, например TextAlignment и FlowDirection. Объект TextRunProperties представляет свойства, которые могут отличаться для каждой текстовой последовательности внутри параграфа, например кисть переднего плана, Typeface и размер шрифта. Для реализации пользовательских абзацев и пользовательских типов свойств исполнений текста, приложение должно создать классы, производные от TextParagraphProperties и TextRunProperties соответственно.

См. также

Основные понятия

Оформление в WPF

Документы в WPF