RichTextKit/doc/basics.page

119 строки
7.1 KiB
Plaintext

---
title: "Basic Concepts"
isMarkdown: false
---
<h1 id="basic-concepts">Basic Concepts</h1>
<p>The page describes some basic concepts that are important to understand
when working with RichTextKit.</p>
<h2 id="rich-strings">Rich Strings</h2>
<p>The easiest way to work with RichTextKit is with the <code>RichString</code> class which
provides a convenient set of methods for constructing richly decorated text.</p>
<pre class="language-csharp"><code class="language-csharp">// Create a RichString
var rs = new RichString()
.Alignment(TextAlignment.Center)
.FontFamily(&quot;Segoe UI&quot;)
.MarginBottom(20)
.Add(&quot;Welcome To RichTextKit&quot;, fontSize:24, fontWeight: 700, fontItalic: true)
.Paragraph().Alignment(TextAlignment.Left)
.FontSize(18)
.Add(&quot;This is a test string&quot;);
</code></pre>
<p>If you want to wrap and/or crop it, set the Max properties:</p>
<pre class="language-csharp"><code class="language-csharp">rs.MaxWidth = 640;
rs.MaxHeight = 480;
</code></pre>
<p>And then you can paint it:</p>
<pre class="language-csharp"><code class="language-csharp">// Paint it
rs.Paint(skia_canvas, new SKPoint(50, 50));
</code></pre>
<p>You can also get it's measured size:</p>
<pre class="language-csharp"><code class="language-csharp">Console.WriteLine($&quot;Size: {rs.MeasuredWidth} x {rs.MeasuredHeight});
</code></pre>
<p>and lots more. See the <a href="./ref/Topten.RichTextKit.RichString">RichString</a> class for details.</p>
<h2 id="text-blocks">Text Blocks</h2>
<p>Text blocks are a lower level concept that describes a single block of
text. Internally RichString builds a single text block for each paragraph.</p>
<p>Text blocks can contain forced line breaks with a newline character (<code>\n</code>).
These should be considered as in-paragraph &quot;soft returns&quot;, as opposed to
hard paragraph terminators.</p>
<p>Currently RichTextKit doesn't support non-text inline elements, although this
may be added in the future.</p>
<p>Text blocks are represented by the <a href="./ref/Topten.RichTextKit.TextBlock">TextBlock</a> class.</p>
<h2 id="styles">Styles</h2>
<p>Styles are used to describe the display attributes of text in a text block. A
text block is comprised of one of more runs of text each tagged with a
single style and these text runs are referred to a &quot;style runs&quot;.</p>
<p>Style runs are represented by the <a href="./ref/Topten.RichTextKit.StyleRun">StyleRun</a> class.</p>
<p>Styles are only used if dealing with TextBlocks directly and generally don't
need to be used if you're using the higher-level RichString interface.</p>
<h2 id="font-fallback">Font Fallback</h2>
<p>Font fallback is the process of switching to a different font when the specified
font doesn't contain the required glyphs.</p>
<p>Font fallback is often required to display emoji characters (since most fonts don't
include emoji glyphs), for most complex scripts (eg: Arabic) and Asian scripts.</p>
<p>RichTextKit uses SkiaSharp's <code>MatchCharacter</code> function to resolve the typeface to
use for font fallback.</p>
<h2 id="text-shaping">Text Shaping</h2>
<p>For most Latin based languages, rendering text is simply a matter of placing one glyph
after another in a left-to-right manner. Other languages however require a more
complicated process that often involves drawing multiple glyphs for a single character.
This process is called &quot;text shaping&quot;.</p>
<p>By default Skia (and therefore ShiaSharp) doesn't do text shaping and often displays
text incorrectly. RichTextKit uses <a href="https://www.freedesktop.org/wiki/Software/HarfBuzz/">HarfBuzz</a>
for text shaping.</p>
<h2 id="font-runs">Font Runs</h2>
<p>Font run are derived by splitting style runs into smaller segments when text
is wrapped onto a new line, or when a font fallback is required.</p>
<p>Each font run represents a single run of text that uses the same font and other
style attributes for every character in the run.</p>
<p>Font runs are represented by the <a href="./ref/Topten.RichTextKit.FontRun">FontRun</a> class.</p>
<h2 id="style-runs-vs-font-runs">Style Runs vs Font Runs</h2>
<p>Style runs and font runs are similar concepts but serve two different purposes:</p>
<ul>
<li>Style runs describe the logical view of a text block (before layout)</li>
<li>Font runs describe the physical view of a text block (after layout)</li>
</ul>
<h2 id="lines">Lines</h2>
<p>After a text block has been laid out it results in a set of lines each
consisting of one or more font runs.</p>
<p>Lines are represented by the <a href="./ref/Topten.RichTextKit.TextLine">TextLine</a> class.</p>
<h2 id="bi-directional-ltr-and-rtl-text">Bi-Directional, LTR and RTL Text</h2>
<p>Bi-directional text is the process of correctly displaying text for mixed
left-to-right and right-to-left based languages.</p>
<p>RichTextKit includes an implementation of the Unicode Bi-directional Text
Algorithm (<a href="http://www.unicode.org/reports/tr9/">UAX #9</a>) and each text block
has a &quot;base direction&quot; that controls the default layout order of text in that
paragraph.</p>
<p>The text direction of spans within the text block can be controlled using
either:</p>
<ul>
<li>Embedded control characters (as specifed by UAX #9)</li>
<li>By setting the text direction of style runs (See the <a href="./ref/Topten.RichTextKit.IStyle">IStyle</a>)</li>
</ul>
<p>When setting text direction property on style runs, the text is processed
in the same manner as an &quot;isolating sequence&quot; as described in UAX #9.</p>
<h2 id="utf-16-utf-32-code-points-and-clusters">UTF-16, UTF-32, Code Points and Clusters</h2>
<p>Internally, RichTextKit works with UTF-32 encoded text. Specifically it uses the
<code>int</code> type to represent a character rather than the <code>char</code> type.</p>
<p>To avoid confusion, the API and code base use the term &quot;code point&quot; to
refer to a single UTF-32 character.</p>
<p>Since C# strings are encoded as UTF-16, when a string is added to a text
block it will be automatically converted to UTF-32. It's important to note that
indexes into the converted string may no longer match indicies into the original
C# string. (although RichTextKit does provide functions to map between them).</p>
<p>RichTextKit uses the term <code>CodePointIndex</code> to refer to the index of a code point
in a UTF-32 buffer.</p>
<p>Also note that line endings <code>\r</code> and <code>\r\n</code> are automatically normalized to <code>\n</code>.
This conversion can also affect the mapping of code point indicies to character
indicies in the original string.</p>
<p><em>(Note: <code>\n\r</code> style line endings aren't supported)</em></p>
<p>Some complex scripts require more that one code point to describe a single user
perceived character. These groupings of code points are called &quot;clusters&quot;. This is
the same concept as used by HarfBuzz.</p>
<h2 id="measurement-and-size-units">Measurement and Size Units</h2>
<p>All measurements and sizes used by RichTextKit are logical.</p>
<p>The final size of rendered text will depend on the configuration of the target
Canvas scaling and it's up to you to determine the appropriate system of measurement
to use.</p>