テキストの高度な書式設定Advanced Text Formatting

Windows Presentation Foundation (WPF) では、アプリケーションにテキストを含めるための堅牢な API のセットが提供されています。Windows Presentation Foundation (WPF) provides a robust set of APIs for including text in your application. レイアウトと TextBlock のような ユーザー インターフェイス (UI)user interface (UI) API により、テキスト表示のための最も一般的な要素が提供されます。Layout and ユーザー インターフェイス (UI)user interface (UI) APIs, such as TextBlock, provide the most common and general-use elements for text presentation. GlyphRunDrawingFormattedText のような描画 API は、描画に書式設定されたテキストを追加する手段です。Drawing APIs, such as GlyphRunDrawing and FormattedText, provide a means for including formatted text in drawings. 最も高度なレベルでは、WPF によって提供される拡張テキスト書式設定エンジンにより、テキスト保管管理、テキスト ラン書式設定管理、埋め込みオブジェクト管理など、テキスト表示のあらゆる側面が制御されます。At the most advanced level, WPF provides an extensible text formatting engine to control every aspect of text presentation, such as text store management, text run formatting management, and embedded object management.

このトピックでは、WPF でのテキスト書式設定の概要について説明します。This topic provides an introduction to WPF text formatting. WPF のテキスト書式設定エンジンのクライアントでの実装と使用について主に取り上げます。It focuses on client implementation and use of the WPF text formatting engine.

注意

ドキュメント内のすべてのコード サンプルは、「テキストの高度な書式設定サンプル」にあります。All code examples within this document can be found in the Advanced Text Formatting Sample.

必須コンポーネントPrerequisites

このトピックは、テキスト表示に使用されるレベルの高い API に関する知識があることを前提に書かれています。This topic assumes that you are familiar with the higher level APIs used for text presentation. ほとんどのユーザー シナリオでは、このトピックにあるようなテキストの高度な書式設定 API は必要ありません。Most user scenarios will not require the advanced text formatting APIs discussed in this topic. 他のテキスト API の概要については、「WPF のドキュメント」を参照してください。For an introduction to the different text APIs, see Documents in WPF.

テキストの高度な書式設定Advanced Text Formatting

WPF のテキスト レイアウトと UIUI のコントロールによって提供される書式設定プロパティを使用すると、書式設定されたテキストをアプリケーションに簡単に追加できます。The text layout and UIUI 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. しかしながら、一部の高度なシナリオでは、テキスト表示と同様にテキスト保存を制御する必要があります。However, some advanced scenarios require the control of text storage as well as text presentation. WPF では、この目的のための拡張テキスト書式設定エンジンが提供されます。WPF provides an extensible text formatting engine for this purpose.

WPF の高度なテキスト書式設定機能は、テキスト書式設定エンジン、テキスト ストア、テキスト ラン、書式設定プロパティで構成されます。The advanced text formatting features found in WPF consist of a text formatting engine, a text store, text runs, and formatting properties. テキスト書式設定エンジン TextFormatter では、表示に使用されるテキスト行が作成されます。The text formatting engine, TextFormatter, creates lines of text to be used for presentation. これは、行の書式設定プロセスを開始し、テキスト フォーマッタの FormatLine を呼び出すことで行われます。This is achieved by initiating the line formatting process and calling the text formatter's FormatLine. テキスト フォーマッタでは、テキスト ストアの GetTextRun メソッドを呼び出すことによって、ストアからテキスト ランが取得されます。The text formatter retrieves text runs from your text store by calling the store's GetTextRun method. 次に、テキスト フォーマッタにより TextRun オブジェクトから書式設定された TextLine オブジェクトが作成されて、検査または表示のためにアプリケーションに提供されます。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 は WPF のテキスト書式設定エンジンであり、テキスト行を書式設定したり、改行したりするためのサービスを提供します。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.

従来のテキスト API とは異なり、TextFormatter では、一連のコールバック メソッドにより、テキスト レイアウト クライアントとの対話が行われます。Unlike a traditional text API, the TextFormatter interacts with a text layout client through a set of callback methods. クライアントでは、TextSource クラスの実装で、これらのメソッドを提供する必要があります。It requires the client to provide these methods in an implementation of the TextSource class. 次の図は、クライアント アプリケーションと TextFormatter の間で行われるテキスト レイアウトの相互作用を示したものです。The following diagram illustrates the text layout interaction between the client application and TextFormatter.

テキスト レイアウト クライアントと TextFormatter のダイアグラム

テキスト フォーマッタは、TextSource の実装であるテキスト ストアから書式設定されたテキスト行を取得するために使用されます。The text formatter is used to retrieve formatted text lines from the text store, which is an implementation of TextSource. これは、最初に Create メソッドを使用してテキスト フォーマッタのインスタンスを作成することで行われます。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. テキスト フォーマッタのインスタンスが作成されるとすぐに、FormatLine メソッドが呼び出されることによって、行の作成プロセスが開始されます。As soon as an instance of the text formatter is created, the line creation process is started by calling the FormatLine method. TextFormatter では、テキスト ソースが再び呼び出されて、行を形成するテキスト ランのテキストと書式設定パラメーターが取得されます。TextFormatter calls back to the text source to retrieve the text and formatting parameters for the runs of text that form a line.

次の例は、テキスト ストアを書式設定するプロセスを示しています。In the following example, the process of formatting a text store is shown. TextFormatter オブジェクトを使用して、テキスト ストアからテキスト行が取得された後、DrawingContext に描画するためのテキスト行の書式設定が行われます。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();
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

クライアント テキスト ストアを実装する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. また、テキスト フォーマッタに個々の TextRun オブジェクトが提供されます。テキスト フォーマッタでは、このオブジェクトを使用して、TextLine オブジェクトが作成されます。It also provides the text formatter with individual TextRun objects which the text formatter uses to create TextLine objects.

テキスト ストアの仮想化を処理するため、テキスト ストアは TextSource から派生される必要があります。To handle the virtualization of the text store, the text store must be derived from TextSource. TextSource では、テキスト ストアからテキスト ランを取得するためにテキスト フォーマッタによって使用されるメソッドが定義されています。TextSource defines the method the text formatter uses to retrieve text runs from the text store. GetTextRun は、行の書式設定で使用されるテキスト ランを取得するためにテキスト フォーマッタによって使用されるメソッドです。GetTextRun is the method used by the text formatter to retrieve text runs used in line formatting. 次のいずれかの条件が発生するまで、テキスト フォーマッタによって GetTextRun が繰り返し呼び出されます。The call to GetTextRun is repeatedly made by the text formatter until one of the following conditions occurs:

  • TextEndOfLine またはサブクラスが返される。A TextEndOfLine or a subclass is returned.

  • テキスト ランの累積の幅が、テキスト フォーマッタを作成するための呼び出し、またはテキスト フォーマッタの FormatLine メソッドの呼び出しのいずれかで指定されている行の最大幅を超過する。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.

  • "CF"、"LF"、"CRLF" など、Unicode の改行シーケンスが返される。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. TextSource の実装で、テキスト フォーマッタに、TextRun オブジェクトとテキスト ランの書式設定プロパティを提供します。Your implementation of TextSource provides the text formatter with the TextRun objects and the properties with which to format the text runs. このやりとりは、テキスト フォーマッタによって呼び出される GetTextRun メソッドで処理されます。This interaction is handled by the GetTextRun method, which is called by the text formatter.

次の表では、事前定義されている TextRun オブジェクトの一部を示します。The following table shows some of the predefined TextRun objects.

TextRun の種類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 前の TextModifier ランの影響を受ける範囲の終わりなど、セグメントの終わりをマークするための特殊なテキスト ラン。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. 範囲は、次に一致する TextEndOfSegment テキスト ランまで、または次の TextEndOfParagraph まで拡張されます。The scope extends to the next matching TextEndOfSegment text run, or the next TextEndOfParagraph.

事前定義されている TextRun オブジェクトのどれでもサブクラス化できます。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.

GetTextRun メソッドの例を次に示します。The following example demonstrates a GetTextRun method. このテキスト ストアでは、処理のためにテキスト フォーマッタに TextRun オブジェクトが返されます。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 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

注意

この例では、テキスト ストアはすべてのテキストに同じテキスト プロパティを提供します。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 オブジェクトは、テキスト ストアによって提供されるプロパティを使用して書式設定されます。TextRun objects are formatted by using properties provided by the text store. これらのプロパティは、TextParagraphPropertiesTextRunProperties の 2 つの型で渡されます。These properties come in two types, TextParagraphProperties and TextRunProperties. TextParagraphProperties では、TextAlignmentFlowDirection などの段落の包括的プロパティが処理されます。TextParagraphProperties handle paragraph inclusive properties such as TextAlignment and FlowDirection. TextRunProperties は、前景ブラシ、Typeface、フォント サイズなど、段落内のテキスト ランごとに異なる場合があるプロパティです。TextRunProperties are properties that can be different for each text run within a paragraph, such as foreground brush, Typeface, and font size. カスタム段落やカスタム テキストのラン プロパティ型を実装するには、アプリケーションでそれぞれ TextParagraphProperties および TextRunProperties から派生するクラスを作成する必要があります。To implement custom paragraph and custom text run property types, your application must create classes that derive from TextParagraphProperties and TextRunProperties respectively.

関連項目See also