Struct kas_text::TextDisplay
source · pub struct TextDisplay { /* private fields */ }
Expand description
Text display, without source text representation
This struct stores glyph locations and intermediate values used to calculate glyph layout. It does not contain the source text itself or “environment” state used during layout.
In general, it is recommended to use crate::Text
instead, which includes
a representation of the source text and environmental state.
Preparation
This struct tracks the state of preparation (Self::required_action
).
Methods will return a NotReady
error if called without sufficient
preparation.
The struct may be default-constructed.
Text preparation proceeds as follows:
-
Self::prepare_runs
breaks the source text into runs which may be fed to the shaping algorithm. Each run has a single bidi embedding level (direction) and uses a single font face, and contains no explicit line break (except as a terminator).Each run is then fed through the text shaper, resulting in a sequence of type-set glyphs.
-
Optionally,
Self::measure_width
may be used to calculate the required width (mostly useful for short texts which will not wrap). -
Self::prepare_lines
takes the output of the first step and applies line wrapping, line re-ordering (for bi-directional lines) and alignment.This step is separate primarily to allow faster re-wrapping should the text’s wrap width change.
Text navigation
Despite lacking a copy of the underlying text, text-indices may be mapped to glyphs and lines, and vice-versa.
The text range is 0..self.text_len()
. Any index within this range
(inclusive of end point) is valid for usage in all methods taking an index.
Multiple indices may map to the same glyph (e.g. within multi-byte chars,
with combining-diacritics, and with ligatures). In some cases a single index
corresponds to multiple glyph positions (due to line-wrapping or change of
direction in bi-directional text).
Navigating to the start or end of a line can be done with
TextDisplay::find_line
and TextDisplay::line_range
.
Navigating left or right should be done via a library such as
unicode-segmentation
which provides a
GraphemeCursor
to step back or forward one “grapheme”, in logical order. Navigating glyphs
in display-order is not currently supported. Optionally, the direction may
be reversed for right-to-left lines TextDisplay::line_is_rtl
, but note
that the result may be confusing since not all text on the line follows the
line’s base direction and adjacent lines may have different directions.
To navigate “up” and “down” lines, use TextDisplay::text_glyph_pos
to
get the position of the cursor, TextDisplay::find_line
to get the line
number, then TextDisplay::line_index_nearest
to find the new index.
Implementations§
source§impl TextDisplay
impl TextDisplay
sourcepub fn text_glyph_pos(&self, index: usize) -> Result<MarkerPosIter, NotReady>
pub fn text_glyph_pos(&self, index: usize) -> Result<MarkerPosIter, NotReady>
Find the starting position (top-left) of the glyph at the given index
The index should be no greater than the text length. It is not required to be on a code-point boundary. Returns an iterator over matching positions. Length of results is guaranteed to be one of 0, 1 or 2:
- 0 if the index is not included in any run of text (probably only possible within a multi-byte line break or beyond the text length)
- 1 is the normal case
- 2 if the index is at the end of one run of text and at the start
of another; these positions may be the same or may not be (over
line breaks and with bidirectional text). If only a single position
is desired, usually the latter is preferred (via
next_back()
).
The result is not guaranteed to be within Self::bounding_box
.
Depending on the use-case, the caller may need to clamp the resulting
position.
sourcepub fn num_glyphs(&self) -> usize
Available on crate feature num_glyphs
only.
pub fn num_glyphs(&self) -> usize
num_glyphs
only.Get the number of glyphs
This method is a simple memory-read.
sourcepub fn glyphs<F: FnMut(FaceId, f32, Glyph)>(&self, f: F) -> Result<(), NotReady>
pub fn glyphs<F: FnMut(FaceId, f32, Glyph)>(&self, f: F) -> Result<(), NotReady>
Yield a sequence of positioned glyphs
Glyphs are yielded in undefined order by a call to f
. The number of
glyphs yielded will equal TextDisplay::num_glyphs
. The closure f
receives parameters face_id, dpem, glyph
.
This may be used as follows:
let mut text = Text::new("Some example text");
text.prepare();
let mut glyphs = Vec::with_capacity(text.num_glyphs());
text.glyphs(|_, dpem, glyph| glyphs.push((dpem, glyph)));
draw(glyphs);
This method has fairly low cost: O(n)
in the number of glyphs with
low overhead.
sourcepub fn glyphs_with_effects<X, F, G>(
&self,
effects: &[Effect<X>],
default_aux: X,
f: F,
g: G
) -> Result<(), NotReady>where
X: Copy,
F: FnMut(FaceId, f32, Glyph, usize, X),
G: FnMut(f32, f32, f32, f32, usize, X),
pub fn glyphs_with_effects<X, F, G>(
&self,
effects: &[Effect<X>],
default_aux: X,
f: F,
g: G
) -> Result<(), NotReady>where
X: Copy,
F: FnMut(FaceId, f32, Glyph, usize, X),
G: FnMut(f32, f32, f32, f32, usize, X),
Like TextDisplay::glyphs
but with added effects
If the list effects
is empty or has first entry with start > 0
, the
result of Effect::default(default_aux)
is used. The user payload of
type X
is simply passed through to f
and g
calls and may be useful
for color information.
The callback f
receives face_id, dpem, glyph, i, aux
where
dpu
and height
are both measures of the font size (pixels per font
unit and pixels per height, respectively), and i
is the index within
effects
(or usize::MAX
when a default-constructed effect token is
used).
The callback g
receives positioning for each underline/strike-through
segment: x1, x2, y_top, h
where h
is the thickness (height). Note
that it is possible to have h < 1.0
and y_top, y_top + h
to round to
the same number; the renderer is responsible for ensuring such lines
are actually visible. The last parameters are i, aux
as for f
.
Note: this is significantly more computationally expensive than
TextDisplay::glyphs
. Optionally one may choose to cache the result,
though this is not really necessary.
source§impl TextDisplay
impl TextDisplay
sourcepub fn prepare_runs<F: FormattableText + ?Sized>(
&mut self,
text: &F,
direction: Direction,
font_id: FontId,
dpem: f32
) -> Result<(), InvalidFontId>
pub fn prepare_runs<F: FormattableText + ?Sized>(
&mut self,
text: &F,
direction: Direction,
font_id: FontId,
dpem: f32
) -> Result<(), InvalidFontId>
Prepare text runs
This is the first step of preparation: breaking text into runs according to font properties, bidi-levels and line-wrap points.
This method only updates self as required; use Self::require_action
if necessary.
On Action::All
, this prepares runs from scratch; on Action::Resize
existing runs
are resized; afterwards, action is no greater than Action::Wrap
.
Parameters: see crate::Environment
documentation.
source§impl TextDisplay
impl TextDisplay
sourcepub fn measure_width(&self, limit: f32) -> Result<f32, NotReady>
pub fn measure_width(&self, limit: f32) -> Result<f32, NotReady>
Measure the maximum line length without wrapping
This is a significantly faster way to calculate the required line length
than Self::prepare_lines
.
The return value is at most limit
and is unaffected by alignment and
wrap configuration of crate::Environment
.
sourcepub fn prepare_lines(
&mut self,
bounds: Vec2,
wrap: bool,
align: (Align, Align)
) -> Result<Vec2, NotReady>
pub fn prepare_lines(
&mut self,
bounds: Vec2,
wrap: bool,
align: (Align, Align)
) -> Result<Vec2, NotReady>
Prepare lines (“wrap”)
This does text layout, with wrapping if enabled.
Returns:
Err(NotReady)
if required action is greater thanAction::Wrap
Ok(bounding_corner)
on success
source§impl TextDisplay
impl TextDisplay
sourcepub fn required_action(&self) -> Action
pub fn required_action(&self) -> Action
Get required action
sourcepub fn require_action(&mut self, action: Action)
pub fn require_action(&mut self, action: Action)
Require an action
Required actions are tracked internally. This combines internal action
state with that input via max
. It may be used, for example, to mark
that fonts need resizing due to change in environment.
sourcepub fn bounding_box(&self) -> Result<(Vec2, Vec2), NotReady>
pub fn bounding_box(&self) -> Result<(Vec2, Vec2), NotReady>
Get the size of the required bounding box
This is the position of the upper-left and lower-right corners of a bounding box on content. Alignment and input bounds do affect the result.
sourcepub fn find_line(
&self,
index: usize
) -> Result<Option<(usize, Range<usize>)>, NotReady>
pub fn find_line(
&self,
index: usize
) -> Result<Option<(usize, Range<usize>)>, NotReady>
Find the line containing text index
Returns the line number and the text-range of the line.
Returns None
in case index
does not line on or at the end of a line
(which means either that index
is beyond the end of the text or that
index
is within a mult-byte line break).
sourcepub fn line_range(&self, line: usize) -> Result<Option<Range<usize>>, NotReady>
pub fn line_range(&self, line: usize) -> Result<Option<Range<usize>>, NotReady>
Get the range of a line, by line number
sourcepub fn line_is_rtl(&self, line: usize) -> Result<Option<bool>, NotReady>
pub fn line_is_rtl(&self, line: usize) -> Result<Option<bool>, NotReady>
Get the directionality of the current line
Returns:
Err(NotReady)
if text is not preparedOk(None)
if text is emptyOk(Some(line_is_right_to_left))
otherwise
Note: indeterminate lines (e.g. empty lines) have their direction determined from the passed environment, by default left-to-right.
sourcepub fn text_index_nearest(&self, pos: Vec2) -> Result<usize, NotReady>
pub fn text_index_nearest(&self, pos: Vec2) -> Result<usize, NotReady>
Find the text index for the glyph nearest the given pos
This includes the index immediately after the last glyph, thus
result ≤ text.len()
.
Note: if the font’s rect
does not start at the origin, then its top-left
coordinate should first be subtracted from pos
.
sourcepub fn line_index_nearest(
&self,
line: usize,
x: f32
) -> Result<Option<usize>, NotReady>
pub fn line_index_nearest(
&self,
line: usize,
x: f32
) -> Result<Option<usize>, NotReady>
Find the text index nearest horizontal-coordinate x
on line
This is similar to TextDisplay::text_index_nearest
, but allows the
line to be specified explicitly. Returns None
only on invalid line
.
Trait Implementations§
source§impl<T: FormattableText + ?Sized> AsMut<TextDisplay> for Text<T>
impl<T: FormattableText + ?Sized> AsMut<TextDisplay> for Text<T>
source§fn as_mut(&mut self) -> &mut TextDisplay
fn as_mut(&mut self) -> &mut TextDisplay
source§impl<T: FormattableText + ?Sized> AsRef<TextDisplay> for Text<T>
impl<T: FormattableText + ?Sized> AsRef<TextDisplay> for Text<T>
source§fn as_ref(&self) -> &TextDisplay
fn as_ref(&self) -> &TextDisplay
source§impl Clone for TextDisplay
impl Clone for TextDisplay
source§fn clone(&self) -> TextDisplay
fn clone(&self) -> TextDisplay
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more