harfbuzz

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2024 License: MIT, MIT Imports: 15 Imported by: 4

Documentation

Overview

Package harfbuzz provides advanced text layout for various scripts and languages, with font-aware substitutions and positioning.

Given a font and an input specified as runes, the package shapes this input and returns a slice of positioned glyphs, identified by their index in the font. See `Buffer` and its methods for more details.

This package is a direct port of the C/C++ library.

Index

Constants

View Source
const (
	// Special setting for `Feature.Start` to apply the feature from the start
	// of the buffer.
	FeatureGlobalStart = 0
	// Special setting for `Feature.End` to apply the feature from to the end
	// of the buffer.
	FeatureGlobalEnd = maxInt
)
View Source
const (
	// Special value for script index indicating unsupported script.
	NoScriptIndex = 0xFFFF
	// Special value for feature index indicating unsupported feature.
	NoFeatureIndex = 0xFFFF
	// Special value for language index indicating default or unsupported language.
	DefaultLanguageIndex = 0xFFFF
)

Variables

View Source
var UniscribeBugCompatible = false

UniscribeBugCompatible alters shaping of indic and khmer scripts:

  • when `false`, it applies the recommended shaping choices
  • when `true`, Uniscribe behavior is reproduced

Functions

func FindFeatureForLang

func FindFeatureForLang(table *tt.TableLayout, scriptIndex, languageIndex int, featureTag tt.Tag) uint16

Fetches the index of a given feature tag in the specified face's GSUB table or GPOS table, underneath the specified script and language. Return `NoFeatureIndex` it the the feature is not found.

func IsDefaultIgnorable

func IsDefaultIgnorable(ch rune) bool

IsDefaultIgnorable returns `true` for codepoints with the Default_Ignorable property (as defined in unicode data DerivedCoreProperties.txt)

func NewOTTagsFromScriptAndLanguage

func NewOTTagsFromScriptAndLanguage(script language.Script, language language.Language) (scriptTags, languageTags []tt.Tag)

NewOTTagsFromScriptAndLanguage converts an `language.Script` and an `Language` to script and language tags.

func ParseVariation

func ParseVariation(s string) (tt.Variation, error)

ParseVariation parse the string representation of a variation of the form tag=value

func SelectLanguage

func SelectLanguage(table *tt.TableLayout, scriptIndex int, languageTags []tt.Tag) (int, bool)

SelectLanguage fetches the index of the first language tag from `languageTags` in the specified layout table, underneath `scriptIndex`. It not found, the `dflt` language tag is searched. Return `true` if the requested language tag is found, `false` otherwise. If `scriptIndex` is `NoScriptIndex` or if no language is found, `DefaultLanguageIndex` is returned.

func SelectScript

func SelectScript(table *tt.TableLayout, scriptTags []tt.Tag) (int, tt.Tag, bool)

SelectScript selects an OpenType script from the `scriptTags` array, returning its index in the Scripts slice and the script tag.

If `table` does not have any of the requested scripts, then `DFLT`, `dflt`, and `latn` tags are tried in that order. If the table still does not have any of these scripts, NoScriptIndex is returned.

An additional boolean if returned : it is `true` if one of the requested scripts is selected, or `false` if a fallback script is selected or if no scripts are selected.

Types

type Buffer

type Buffer struct {
	// Info is used as internal storage during the shaping,
	// and also exposes the result: the glyph to display
	// and its original Cluster value.
	Info []GlyphInfo

	// Pos gives the position of the glyphs resulting from the shaping
	// It has the same length has `Info`.
	Pos []GlyphPosition

	// Props is required to correctly interpret the input runes.
	Props SegmentProperties
	// Glyph that replaces invisible characters in
	// the shaping result. If set to zero (default), the glyph for the
	// U+0020 SPACE character is used. Otherwise, this value is used
	// verbatim.
	Invisible fonts.GID

	// Glyph that replaces characters not found in the font during shaping.
	// The not-found glyph defaults to zero, sometimes knows as the
	// ".notdef" glyph.
	NotFound fonts.GID

	// Information about how the text in the buffer should be treated.
	Flags ShapingOptions
	// Precise the cluster handling behavior.
	ClusterLevel ClusterLevel
	// contains filtered or unexported fields
}

Buffer is the main structure holding the input text segment and its properties before shaping, and output glyphs and their information after shaping.

func NewBuffer

func NewBuffer() *Buffer

NewBuffer allocate a storage with default options. It should then be populated with `AddRunes` and shaped with `Shape`.

func (*Buffer) AddRune

func (b *Buffer) AddRune(codepoint rune, cluster int)

AddRune appends a character with the Unicode value of `codepoint` to `b`, and gives it the initial cluster value of `cluster`. Clusters can be any thing the client wants, they are usually used to refer to the index of the character in the input text stream and are output in the `GlyphInfo.Cluster` field. This also clears the posterior context (see `AddRunes`).

func (*Buffer) AddRunes

func (b *Buffer) AddRunes(text []rune, itemOffset, itemLength int)

AddRunes appends characters from text array to b. itemOffset is the position of the first character from text that will be appended, and itemLength is the number of character to add (-1 means the end of the slice). When shaping part of a larger text (e.g. a run of text from a paragraph), instead of passing just the substring corresponding to the run, it is preferable to pass the whole paragraph and specify the run start and length as itemOffset and itemLength, respectively, to give HarfBuzz the full context to be able, for example, to do cross-run Arabic shaping or properly handle combining marks at start of run. The cluster value attributed to each rune is the index in the text slice.

func (*Buffer) Clear

func (b *Buffer) Clear()

Clear resets `b` to its initial empty state (including user settings). This method should be used to reuse the allocated memory.

func (*Buffer) GuessSegmentProperties

func (b *Buffer) GuessSegmentProperties()

GuessSegmentProperties fills unset buffer segment properties based on buffer Unicode contents and can be used when no other information is available.

If buffer `Props.Script` is zero, it will be set to the Unicode script of the first character in the buffer that has a script other than Common, Inherited, and Unknown.

Next, if buffer `Props.Direction` is zero, it will be set to the natural horizontal direction of the buffer script, defaulting to `LeftToRight`.

Finally, if buffer Props.Language is empty, it will be set to the process's default language.

func (*Buffer) Reverse

func (b *Buffer) Reverse()

Reverse reverses buffer contents, that is the `Info` and `Pos` slices.

func (*Buffer) Shape

func (b *Buffer) Shape(font *Font, features []Feature)

Shape shapes the buffer using `font`, turning its Unicode characters content to positioned glyphs. If `features` is not empty, it will be used to control the features applied during shaping. If two features have the same tag but overlapping ranges the value of the feature with the higher index takes precedence.

The shaping plan depends on the font capabilities. See `NewFont` and `Face` and its extension interfaces for more details.

It also depends on the properties of the segment of text : the `Props` field of the buffer must be set before calling `Shape`.

type ClusterLevel

type ClusterLevel uint8

ClusterLevel allows selecting more fine-grained Cluster handling. It defaults to `MonotoneGraphemes`.

const (
	// Return cluster values grouped by graphemes into monotone order.
	MonotoneGraphemes ClusterLevel = iota
	//  Return cluster values grouped into monotone order.
	MonotoneCharacters
	// Don't group cluster values.
	Characters
)

func (ClusterLevel) String

func (cl ClusterLevel) String() string

type Direction

type Direction uint8

Direction is the text direction. The zero value is the initial, unset, invalid direction.

const (
	LeftToRight Direction = 4 + iota // Text is set horizontally from left to right.
	RightToLeft                      // Text is set horizontally from right to left.
	TopToBottom                      // Text is set vertically from top to bottom.
	BottomToTop                      // Text is set vertically from bottom to top.
)

func (Direction) Reverse

func (dir Direction) Reverse() Direction

Reverse reverses a text direction. Requires that the direction is valid.

type Face

type Face = fonts.Face

Face is the interface providing font metrics and layout information. Harfbuzz is mostly useful when used with fonts providing advanced layout capabilities : see the extension interface `FaceOpenType`.

type FaceOpenType

type FaceOpenType interface {
	Face
	truetype.FaceVariable

	// Returns true if the font has Graphite capabilities.
	// Note that tables validity will still be checked in `NewFont`,
	// using the table from the returned `truetype.Font`.
	// Override this method to disable Graphite functionalities.
	IsGraphite() (*truetype.Font, bool)

	// LayoutTables fetches the OpenType layout tables of the font.
	LayoutTables() truetype.LayoutTables

	// GetGlyphContourPoint retrieves the (X,Y) coordinates (in font units) for a
	// specified contour point in a glyph, or false if not found.
	GetGlyphContourPoint(glyph fonts.GID, pointIndex uint16) (x, y int32, ok bool)

	// VariationGlyph retrieves the glyph ID for a specified Unicode code point
	// followed by a specified Variation Selector code point, or false if not found
	VariationGlyph(ch, varSelector rune) (fonts.GID, bool)
}

FaceOpenType adds support for advanced layout features found in OpenType/Truetype font files. See the package fonts/truetype for more details.

type Feature

type Feature struct {
	Tag tt.Tag
	// Value of the feature: 0 disables the feature, non-zero (usually
	// 1) enables the feature. For features implemented as lookup type 3 (like
	// 'salt') `Value` is a one-based index into the alternates.
	Value uint32
	// The cluster to Start applying this feature setting (inclusive)
	Start int
	// The cluster to End applying this feature setting (exclusive)
	End int
}

Feature holds information about requested feature application. The feature will be applied with the given value to all glyphs which are in clusters between `start` (inclusive) and `end` (exclusive). Setting start to `FeatureGlobalStart` and end to `FeatureGlobalEnd` specifies that the feature always applies to the entire buffer.

func ParseFeature

func ParseFeature(feature string) (Feature, error)

ParseFeature parses one feature string (usually coming from a comma-separated list of font features).

Features can be enabled or disabled, either globally or limited to
specific character ranges.  The format for specifying feature settings
follows.  All valid CSS font-feature-settings values other than 'normal'
and the global values are also accepted, though not documented below.
CSS string escapes are not supported.

The range indices refer to the positions between Unicode characters,
unless the --utf8-clusters is provided, in which case range indices
refer to UTF-8 byte indices. The position before the first character
is always 0.

The format is Python-esque.  Here is how it all works:

  Syntax:       Value:    Start:    End:

Setting value:
  "kern"        1         0         ∞         // Turn feature on
  "+kern"       1         0         ∞         // Turn feature on
  "-kern"       0         0         ∞         // Turn feature off
  "kern=0"      0         0         ∞         // Turn feature off
  "kern=1"      1         0         ∞         // Turn feature on
  "aalt=2"      2         0         ∞         // Choose 2nd alternate

Setting index:
  "kern[]"      1         0         ∞         // Turn feature on
  "kern[:]"     1         0         ∞         // Turn feature on
  "kern[5:]"    1         5         ∞         // Turn feature on, partial
  "kern[:5]"    1         0         5         // Turn feature on, partial
  "kern[3:5]"   1         3         5         // Turn feature on, range
  "kern[3]"     1         3         3+1       // Turn feature on, single char

Mixing it all:

  "aalt[3:5]=2" 2         3         5         // Turn 2nd alternate on for range

type Font

type Font struct {

	// Point size of the font. Set to zero to unset.
	// This is used in AAT layout, when applying 'trak' table.
	Ptem float32

	// Horizontal and vertical scale of the font.
	// The resulting positions are computed with: fontUnit * Scale / faceUpem,
	// where faceUpem is given by the face.
	//
	// Given a device resolution (in dpi) and a point size, the scale to
	// get result in pixels is given by : pointSize * dpi / 72
	XScale, YScale int32

	// Horizontal and vertical pixels-per-em (ppem) of the font.
	// Is is used to select bitmap sizes and to perform some OpenType
	// positioning.
	XPpem, YPpem uint16
	// contains filtered or unexported fields
}

Font is used internally as a light wrapper around the provided Face.

While a font face is generally the in-memory representation of a static font file, `Font` handles dynamic attributes like size, width and other parameters (pixels-per-em, points-per-em, variation settings).

Font are constructed with `NewFont` and adjusted by accessing the fields XPpem, YPpem, Ptem, XScale, YScale and with the method `SetVarCoordsDesign` for variable fonts.

func NewFont

func NewFont(face Face) *Font

NewFont constructs a new font object from the specified face.

The scale is set to the face Upem, meaning that by default the output results will be expressed in font units.

When appropriate, it will load the additional information required for OpenType and Graphite layout, which will influence the shaping plan used in `Buffer.Shape`.

The `face` object should not be modified after this call.

func (*Font) ExtentsForDirection

func (f *Font) ExtentsForDirection(direction Direction) fonts.FontExtents

ExtentsForDirection fetches the extents for a font in a text segment of the specified direction, applying the scaling.

Calls the appropriate direction-specific variant (horizontal or vertical) depending on the value of `direction`.

func (*Font) Face

func (f *Font) Face() fonts.Face

Face returns the underlying face. Note that field is readonly, since some caching may happen in the `NewFont` constructor.

func (*Font) GetOTGlyphClass

func (f *Font) GetOTGlyphClass(glyph fonts.GID) uint32

GetOTGlyphClass fetches the GDEF class of the requested glyph in the specified face, or 0 if not found.

func (*Font) GetOTLayoutTables

func (f *Font) GetOTLayoutTables() *tt.LayoutTables

GetOTLayoutTables returns the OpenType layout tables, or nil if the underlying face is not a FaceOpenType. The returned tables should not be modified.

func (*Font) GetOTLigatureCarets

func (f *Font) GetOTLigatureCarets(direction Direction, glyph fonts.GID) []Position

GetOTLigatureCarets fetches a list of the caret positions defined for a ligature glyph in the GDEF table of the font (or nil if not found).

func (*Font) GlyphAdvanceForDirection

func (f *Font) GlyphAdvanceForDirection(glyph fonts.GID, dir Direction) (x, y Position)

GlyphAdvanceForDirection fetches the advance for a glyph ID from the specified font, in a text segment of the specified direction.

Calls the appropriate direction-specific variant (horizontal or vertical) depending on the value of `dir`.

func (*Font) GlyphExtents

func (f *Font) GlyphExtents(glyph fonts.GID) (out GlyphExtents, ok bool)

GlyphExtents fetches the GlyphExtents data for a glyph ID in the specified font, or false if not found

func (*Font) GlyphHAdvance

func (f *Font) GlyphHAdvance(glyph fonts.GID) Position

GlyphHAdvance fetches the advance for a glyph ID in the font, for horizontal text segments.

func (*Font) LineMetric

func (f *Font) LineMetric(metric fonts.LineMetric) (int32, bool)

LineMetric fetches the given metric, applying potential variations and scaling.

func (*Font) SetVarCoordsDesign

func (f *Font) SetVarCoordsDesign(coords []float32)

SetVarCoordsDesign applies a list of variation coordinates, in design-space units, to the font.

type GlyphExtents

type GlyphExtents struct {
	XBearing int32
	YBearing int32
	Width    int32
	Height   int32
}

GlyphExtents is the same as fonts.GlyphExtents but with int type

type GlyphInfo

type GlyphInfo struct {
	// Cluster is the index of the character in the original text that corresponds
	// to this `GlyphInfo`, or whatever the client passes to `Buffer.Add()`.
	// More than one glyph can have the same `Cluster` value,
	// if they resulted from the same character (e.g. one to many glyph substitution),
	// and when more than one character gets merged in the same glyph (e.g. many to one glyph substitution)
	// the glyph will have the smallest Cluster value of them.
	// By default some characters are merged into the same Cluster
	// (e.g. combining marks have the same Cluster as their bases)
	// even if they are separate glyphs.
	// See Buffer.ClusterLevel for more fine-grained Cluster handling.
	Cluster int

	// Glyph is the result of the selection of concrete glyph
	// after shaping, and refers to the font used.
	Glyph fonts.GID

	// Mask exposes glyph attributes (see the constants).
	// It is also used internally during the shaping.
	Mask GlyphMask
	// contains filtered or unexported fields
}

GlyphInfo holds information about the glyphs and their relation to input text. They are internally created from user input, and the shaping sets the `Glyph` field.

func (GlyphInfo) String

func (info GlyphInfo) String() string

String returns a simple description of the glyph of the form Glyph=Cluster(mask)

type GlyphMask

type GlyphMask = uint32
const (
	// Indicates that if input text is broken at the beginning of the cluster this glyph is part of,
	// then both sides need to be re-shaped, as the result might be different.
	// On the flip side, it means that when this flag is not present,
	// then it's safe to break the glyph-run at the beginning of this cluster,
	// and the two sides represent the exact same result one would get
	// if breaking input text at the beginning of this cluster and shaping the two sides
	// separately.
	// This can be used to optimize paragraph layout, by avoiding re-shaping
	// of each line after line-breaking, or limiting the reshaping to a small piece around the
	// breaking point only.
	GlyphUnsafeToBreak GlyphMask = 0x00000001
)

type GlyphPosition

type GlyphPosition struct {
	// How much the line advances after drawing this glyph when setting
	// text in horizontal direction.
	XAdvance Position
	// How much the glyph moves on the X-axis before drawing it, this
	// should not affect how much the line advances.
	XOffset Position

	// How much the line advances after drawing this glyph when setting
	// text in vertical direction.
	YAdvance Position
	// How much the glyph moves on the Y-axis before drawing it, this
	// should not affect how much the line advances.
	YOffset Position
	// contains filtered or unexported fields
}

GlyphPosition holds the positions of the glyph in both horizontal and vertical directions. All positions are relative to the current point.

type Position

type Position = int32

Position stores a position, scaled according to the `Font` scale parameters.

type SegmentProperties

type SegmentProperties struct {
	// Languages are crucial for selecting which OpenType feature to apply to
	// the buffer which can result in applying language-specific behavior.
	// Languages are orthogonal to the scripts, and though they are related,
	// they are different concepts and should not be confused with each other.
	Language language.Language

	// Script is crucial for choosing the proper shaping behavior for scripts that
	// require it (e.g. Arabic) and the OpenType features defined in the font
	// to be applied.
	//
	// See the package language for predefined values.
	Script language.Script

	// Direction is the text flow direction of the buffer. No shaping can happen without
	// setting direction, and it controls the visual direction for the
	// output glyphs; for RTL direction the glyphs will be reversed. Many layout
	// features depend on the proper setting of the direction, for example,
	// reversing RTL text before shaping, then shaping with LTR direction is not
	// the same as keeping the text in logical order and shaping with RTL
	// direction.
	Direction Direction
}

SegmentProperties holds various text properties of a `Buffer`.

type ShapingOptions

type ShapingOptions uint16

ShapingOptions controls some fine tunning of the shaping (see the constants).

const (
	// Flag indicating that special handling of the beginning
	// of text paragraph can be applied to this buffer. Should usually
	// be set, unless you are passing to the buffer only part
	// of the text without the full context.
	Bot ShapingOptions = 1 << iota
	// Flag indicating that special handling of the end of text
	// paragraph can be applied to this buffer, similar to
	// `Bot`.
	Eot
	// Flag indication that character with Default_Ignorable
	// Unicode property should use the corresponding glyph
	// from the font, instead of hiding them (done by
	// replacing them with the space glyph and zeroing the
	// advance width.)  This flag takes precedence over
	// `RemoveDefaultIgnorables`.
	PreserveDefaultIgnorables
	// Flag indication that character with Default_Ignorable
	// Unicode property should be removed from glyph string
	// instead of hiding them (done by replacing them with the
	// space glyph and zeroing the advance width.)
	// `PreserveDefaultIgnorables` takes
	// precedence over this flag.
	RemoveDefaultIgnorables
	// Flag indicating that a dotted circle should
	// not be inserted in the rendering of incorrect
	// character sequences (such at <0905 093E>).
	DoNotinsertDottedCircle
)

Directories

Path Synopsis
Generator of the mapping from OpenType tags to BCP 47 tags && vice versa.
Generator of the mapping from OpenType tags to BCP 47 tags && vice versa.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL