Bounds describes the minor-axis bounds of a line of text. In a LTR or RTL
layout, it describes the vertical axis. In a BTT or TTB layout, it describes
the horizontal.
For horizontal text:
- Ascent GLYPH
| GLYPH
| GLYPH
| GLYPH
| GLYPH
- Baseline GLYPH
| GLYPH
| GLYPH
| GLYPH
- Descent GLYPH
|
- Gap
For vertical text:
Descent ------- Baseline --------------- Ascent --- Gap
| | | |
GLYPH GLYPH GLYPH
GLYPH GLYPH GLYPH GLYPH GLYPH Ascent is the maximum ascent away from the baseline. This value is typically
positive in coordiate systems that grow up. Descent is the maximum descent away from the baseline. This value is typically
negative in coordinate systems that grow up. Gap is the height of empty pixels between lines. This value is typically positive
in coordinate systems that grow up. LineThickness returns the thickness of a line of text described by b,
that is its height for horizontal text, its width for vertical text.
Fontmap provides a general mechanism to select
a face to use when shaping text. ResolveFace is called by [SplitByFace] and [Segmenter.Split] for each input rune potentially
triggering a face change.
It must always return a valid (non nil) [*font.Face] value.FontmapScript(interface)
func SplitByFace(input Input, availableFaces Fontmap) []Input
func (*Segmenter).Split(text Input, faces Fontmap) []Input
FontmapScript is an optional interface supporting script hints. ResolveFace is called by [SplitByFace] and [Segmenter.Split] for each input rune potentially
triggering a face change.
It must always return a valid (non nil) [*font.Face] value. SetScript set the script to which the (next) runes passed to [ResolveFace]
belong.
Providing this information before calling [ResolveFace] is useful for two reasons :
- optimizing [ResolveFace] for runes with a shared script
- for runes with Common and Inherited script, the script resolved by a segmentation step
is more accurate
FontmapScript : Fontmap
Glyph describes the attributes of a single glyph from a single
font face in a shaped output. Advance is the distance between the current dot (without offset applied) and the next dot.
It is typically positive for horizontal text, and negative for vertical text. ClusterIndex is the lowest rune index of all runes shaped into
this glyph cluster. All glyphs sharing the same cluster value
are part of the same cluster and will have identical RuneCount
and GlyphCount fields.
Deprecated: Use TextIndex() instead. GlyphCount is the number of glyphs in this output glyph cluster.
Deprecated: Use GlyphsCount() instead.GlyphIDfont.GID Height is the height of the glyph content,
expressed as a distance from the [YBearing],
typically negativeMaskuint32 RuneCount is the number of input runes shaped into this output
glyph cluster.
Deprecated: Use RunesCount() instead. Width is the width of the glyph content,
expressed as a distance from the [XBearing],
typically positive XAdvance is the distance between the current dot (without offset applied) and the next dot.
It is typically positive for horizontal text, and always zero for vertical text.
Deprecated: Use Advance instead. XBearing is the distance between the dot (with offset applied) and
the glyph content, typically positive for horizontal text;
often negative for vertical text. Offsets to be applied to the dot before actually drawing
the glyph.
For vertical text, YOffset is typically used to position the glyph
below the horizontal line at the dot YAdvance is the distance between the current dot (without offset applied) and the next dot.
It is typically negative for vertical text, and always zero for horizontal text.
Deprecated: Use Advance instead. YBearing is the distance between the dot (with offset applied) and
the top of the glyph content, typically positive Offsets to be applied to the dot before actually drawing
the glyph.
For vertical text, YOffset is typically used to position the glyph
below the horizontal line at the dot GlyphsCount is the number of glyphs in this output glyph cluster. LeftSideBearing returns the distance from the glyph's X origin to
its leftmost edge. This value can be negative if the glyph extends
across the origin. RightSideBearing returns the distance from the glyph's right edge to
the edge of the glyph's advance. This value can be negative if the glyph's
right edge is after the end of its advance. RuneCount is the number of input runes shaped into this output
glyph cluster. TextIndex is the lowest rune index of all runes shaped into
this glyph cluster. All glyphs sharing the same cluster value
are part of the same cluster and will have identical RunesCount
and GlyphsCount values.
HarfbuzzShaper implements the Shaper interface using harfbuzz.
Reusing this shaper type across multiple shaping operations is
faster and more memory-efficient than creating a new shaper
for each operation. SetFontCacheSize adjusts the size of the font cache within the shaper.
It is safe to adjust the size after using the shaper, though shrinking
it may result in many evictions on the next shaping. Shape turns an input into an output.
*HarfbuzzShaper : Shaper
Direction is the directionality of the text. Face is the font face to render the text in. FontFeatures activates or deactivates optional features
provided by the font.
The settings are applied to the whole [Text]. Language is an identifier for the language of the text. RunStart and RunEnd indicate the subslice of Text being shaped. RunStart and RunEnd indicate the subslice of Text being shaped. Script is an identifier for the writing system used in the text. Size is the requested size of the font.
More generally, it is a scale factor applied to the resulting metrics.
For instance, given a device resolution (in dpi) and a point size (like 14), the `Size` to
get result in pixels is given by : pointSize * dpi / 72 Text is the body of text being shaped. Only the range Text[RunStart:RunEnd] is considered
for shaping, with the rest provided as context for the shaper. This helps with, for example,
cross-run Arabic shaping or handling combining marks at the start of a run.
func SplitByFace(input Input, availableFaces Fontmap) []Input
func SplitByFontGlyphs(input Input, availableFaces []*font.Face) []Input
func (*Segmenter).Split(text Input, faces Fontmap) []Input
func SplitByFace(input Input, availableFaces Fontmap) []Input
func SplitByFontGlyphs(input Input, availableFaces []*font.Face) []Input
func (*HarfbuzzShaper).Shape(input Input) Output
func (*Segmenter).Split(text Input, faces Fontmap) []Input
func Shaper.Shape(Input) Output
func WrapConfig.WithTruncator(shaper Shaper, input Input) WrapConfig
Line holds runs of shaped text wrapped onto a single line. All the contained
Output should be displayed sequentially on one line. AdjustBaselines aligns runs with different baselines.
For vertical text, it centralizes 'sideways' runs, so
that text with mixed 'upright' and
'sideways' orientation is better aligned.
This is currently a no-op for horizontal text.
Note that this method only update cross-axis metrics,
so that the advance is preserved. As such, it is valid
to call this method after line wrapping, for instance.
func (*LineWrapper).WrapParagraph(config WrapConfig, maxWidth int, paragraph []rune, runs RunIterator) (_ []Line, truncated int)
func (*LineWrapper).WrapParagraphF(config WrapConfig, maxWidth fixed.Int26_6, paragraph []rune, runs RunIterator) (_ []Line, truncated int)
LineBreakPolicy specifies when considering a line break within a "word" or UAX#14
segment is allowed.( LineBreakPolicy) String() string
LineBreakPolicy : expvar.Var
LineBreakPolicy : fmt.Stringer
const Always
const Never
const WhenNecessary
LineWrapper holds reusable state for a line wrapping operation. Reusing
LineWrappers for multiple paragraphs should improve performance. Prepare initializes the LineWrapper for the given paragraph and shaped text.
It must be called prior to invoking WrapNextLine. Prepare invalidates any
lines previously returned by this wrapper. WrapNextLine wraps the shaped glyphs of a paragraph to a particular max width.
It is meant to be called iteratively to wrap each line, allowing lines to
be wrapped to different widths within the same paragraph. When done is true,
subsequent calls to WrapNextLine (without calling Prepare) will return a nil line.
The returned line is only valid until the next call to
[*LineWrapper.Prepare] or [*LineWrapper.WrapParagraph].
If the LineWrapper's [WrapConfig].TruncateAfterLines
is non-zero, the final line of text returned by successive calls to WrapNextLine
may be truncated. The quantity of runes truncated by wrapping the line is
returned in [WrappedLine].Truncated. If this is non-zero AND the LineWrapper's
[WrapConfig].Truncator is set, the final line will end with an extra [Output].
[Output]s before the final [Output] will represent the input runes that are still
visible before truncation, and the final [Output] will be a copy of the Truncator
with its Runes.Count set to the quantity of runes truncated during line wrapping.
See also [WrapNextLineF] which supports a decimal [maxWidth]. WrapNextLineF is the same as [WrapNextLine], but accepts a non integer [maxWidth]. WrapParagraph wraps the paragraph's shaped glyphs to a constant maxWidth.
It is equivalent to iteratively invoking WrapLine with a constant maxWidth.
If the config has a non-zero TruncateAfterLines, WrapParagraph will return at most
that many lines. The truncated return value is the count of runes truncated from
the end of the text. The returned lines are only valid until the next call to
[*LineWrapper.WrapParagraph] or [*LineWrapper.Prepare].
See [(*LineWrapper).WrapNextLine] for a description of how [WrapConfig]'s truncation
features impact the wrapped text output. This method returns the quantity of runes
truncated by line wrapping in the [truncated] return value.
See also [WrapParagraphF] which supports a decimal [maxWidth]. WrapParagraphF is the same as [WrapParagraph], but accepts a non integer [maxWidth].
Output describes the dimensions and content of shaped text. Advance is the distance the Dot has advanced.
It is typically positive for horizontal text, negative for vertical. Direction is the direction used to shape the text,
as provided in the Input. Face is the font face that this output is rendered in. This is needed in
the output in order to render each run in a multi-font sequence in the
correct font. GlyphBounds describes a tight bounding box on the specific glyphs contained
within this output. The dimensions may not be sufficient to contain all
glyphs within the chosen font.
Its [Gap] field is always zero. Glyphs are the shaped output text. LineBounds describes the font's suggested line bounding dimensions. The
dimensions described should contain any glyphs from the given font. Runes describes the runes this output represents from the input text. Size is copied from the shaping.Input.Size that produced this Output. VisualIndex is the visual position of this run within its containing line where
0 indicates the leftmost run and increasing values move to the right. This is
useful for sorting the runs for drawing purposes. AddLetterSpacing alters the run, adding [additionalSpacing] between
each Harfbuzz clusters.
Space is added at the boundaries if and only if there is an adjacent run, as specified by [isStartRun] and [isEndRun].
See also the convenience function [AddSpacing] to handle a slice of runs.
See also https://www.w3.org/TR/css-text-3/#letter-spacing-property AddWordSpacing alters the run, adding [additionalSpacing] on each
word separator.
[text] is the input slice used to create the run.
Note that space is always added, even on boundaries.
See also the convenience function [AddSpacing] to handle a slice of runs.
See also https://www.w3.org/TR/css-text-3/#word-separator FromFontUnit converts an unscaled font value to the current [Size] RecalculateAll updates the all other fields of the Output
to match the current contents of the Glyphs field.
This method will fail with UnimplementedDirectionError if the Output
direction is unimplemented. RecomputeAdvance updates only the Advance field based on the current
contents of the Glyphs field. It is faster than RecalculateAll(),
and can be used to speed up line wrapping logic. ToFontUnit converts a metrics (typically found in [Glyph] fields)
to unscaled font units.
func (*HarfbuzzShaper).Shape(input Input) Output
func RunIterator.Next() (index int, run Output, isValid bool)
func RunIterator.Peek() (index int, run Output, isValid bool)
func Shaper.Shape(Input) Output
func AddSpacing(runs []Output, text []rune, wordSpacing, letterSpacing fixed.Int26_6)
func NewSliceIterator(outs []Output) RunIterator
Range indicates the location of a sequence of elements within a longer slice.CountintOffsetint
RunIterator defines a type that can incrementally provide shaped text. Next returns the next run in the iterator, if any. If there is a next run,
its index, content, and true will be returned, and the iterator will advance
to the following element. Otherwise Next returns an undefined index, an empty
Output, and false. Peek returns the same thing Next() would, but does not advance the iterator (so the
next call to Next() will return the same thing). Restore resets the iteration state to the most recently Save()-ed position. Save marks the current iterator position such that the iterator can return to it later
when Restore() is called. Only one position may be saved at a time, with subsequent
calls to Save() overriding the current value.
func NewSliceIterator(outs []Output) RunIterator
func (*LineWrapper).Prepare(config WrapConfig, paragraph []rune, runs RunIterator)
func (*LineWrapper).WrapParagraph(config WrapConfig, maxWidth int, paragraph []rune, runs RunIterator) (_ []Line, truncated int)
func (*LineWrapper).WrapParagraphF(config WrapConfig, maxWidth fixed.Int26_6, paragraph []rune, runs RunIterator) (_ []Line, truncated int)
Segmenter holds a state used to split input
according to three caracteristics : text direction (bidi),
script, and face. Split segments the given pre-configured input according to:
- text direction
- script
- language
- (vertical text only) glyph orientation
- face, as defined by [faces]
Only the input runes in the range [text.RunStart] to [text.RunEnd] will be split.
As a consequence, it sets the following fields of the returned runs:
- Text, RunStart, RunEnd
- Direction
- Script
- Language
- Face
[text.Direction] is used during bidi ordering, and should refer to the general
context [text] is used in (typically the user system preference for GUI apps.)
For vertical text, if its orientation is set, is copied as it is; otherwise, the
orientation is resolved using the Unicode recommendations (see https://www.unicode.org/reports/tr50/).
When possible, the language are resolved to match the current script. For instance,
(language: 'fr', script: 'arabic') is resolved to language: 'arabic'.
The returned sliced is owned by the [Segmenter] and is only valid until
the next call to [Split].
WrapConfig provides line-wrapper settings. BreakPolicy determines under what circumstances the wrapper will consider
breaking in between UAX#14 line breaking candidates, or "within words" in
many scripts. Direction describes the text layout of the overall paragraph, rather than
individual runs of text. This is used to compute the correct visual order of
bidirectional text runs. DisableTrailingWhitespaceTrim turns off a feature that automatically sets the
advance of trailing whitespace on a line to zero. In display contexts, you
usually want this feature enabled, but for text editors it is frequently
desirable to allow trailing whitespace to occupy space itself. TextContinues indicates that the paragraph wrapped by this config is not the
final paragraph in the text. This alters text truncation when filling the
final line permitted by TruncateAfterLines. If the text of this paragraph
does fit entirely on TruncateAfterLines, normally the truncator symbol would
not be inserted. However, if the overall body of text continues beyond this
paragraph (indicated by TextContinues), the truncator should still be inserted
to indicate that further paragraphs of text were truncated. This field has
no effect if TruncateAfterLines is zero. TruncateAfterLines is the number of lines of text to allow before truncating
the text. A value of zero means no limit. Truncator, if provided, will be inserted at the end of a truncated line. This
feature is only active if TruncateAfterLines is nonzero. See the documentation
for [LineWrapper.WrapNextLine] for details about how this works. WithTruncator returns a copy of WrapConfig with the Truncator field set to the
result of shaping input with shaper.
func WrapConfig.WithTruncator(shaper Shaper, input Input) WrapConfig
func (*LineWrapper).Prepare(config WrapConfig, paragraph []rune, runs RunIterator)
func (*LineWrapper).WrapParagraph(config WrapConfig, maxWidth int, paragraph []rune, runs RunIterator) (_ []Line, truncated int)
func (*LineWrapper).WrapParagraphF(config WrapConfig, maxWidth fixed.Int26_6, paragraph []rune, runs RunIterator) (_ []Line, truncated int)
WrappedLine is the result of wrapping one line of text. Line is the content of the line, as a slice of shaped runs NextLine is the indice (in the input text slice) of the begining
of the next line. It will equal len(text) if all the text
fit in one line. TrimmedTrailingWhitespace is the space taken by trailing whitespace
before if was trimmed (usually positive).
It is zero if [DisableTrailingWhitespaceTrim] is set to true,
or if there is no whitespace at the end of the line. Truncated is the count of runes truncated from the end of the line,
if this line was truncated.
func (*LineWrapper).WrapNextLine(maxWidth int) (out WrappedLine, done bool)
func (*LineWrapper).WrapNextLineF(maxWidth fixed.Int26_6) (out WrappedLine, done bool)
Package-Level Functions (total 4)
AddSpacing adds additionnal spacing between words and letters, mutating the given [runs].
[text] is the input slice the [runs] refer to.
See the method [Output.AddWordSpacing] and [Output.AddLetterSpacing] for details
about what spacing actually is.
NewSliceIterator returns a [RunIterator] backed by an already-shaped slice of [Output]s.
SplitByFace split the runes from 'input' to several items, sharing the same
characteristics as 'input', expected for the `Face` which is set to
the return value of the [Fontmap.ResolveFace] call.
The 'Face' field of 'input' is ignored: only 'availableFaces' is used to select the face.
SplitByFontGlyphs split the runes from 'input' to several items, sharing the same
characteristics as 'input', expected for the `Face` which is set to
the first font among 'availableFonts' providing support for all the runes
in the item.
Runes supported by no fonts are mapped to the first element of 'availableFonts', which
must not be empty.
The 'Face' field of 'input' is ignored: only 'availableFaces' are consulted.
Rune coverage is obtained by calling the NominalGlyph() method of each font.
See also [SplitByFace] for a more general approach of font selection.
Package-Level Constants (total 3)
Always means that lines will always choose to break within words if it means that
more text can fit on the line.
Never means that words will never be broken internally, allowing them to exceed
the specified maxWidth.
WhenNecessary means that lines will only be broken within words when the word
cannot fit on the next line by itself or during truncation to preserve as much
of the final word as possible.
The pages are generated with Goldsv0.8.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.