TextDisplay

Struct TextDisplay 

Source
pub struct TextDisplay { /* private fields */ }
Expand description

Text type-setting object (low-level, without text and configuration)

This struct caches type-setting data at multiple levels of preparation. Its end result is a sequence of type-set glyphs.

It is usually recommended to use Text instead, which includes the source text, type-setting configuration and status tracking.

§Status of preparation

Stages of preparation are as follows:

  1. Ensure all required fonts are loaded.

  2. Call Self::prepare_runs to break text into level runs, then shape these runs into glyph runs (unwrapped but with weak break points).

    This method must be called again if the text, text direction or font_id change. If only the text size (dpem) changes, it is sufficient to instead call Self::resize_runs.

  3. Optionally, Self::measure_width and Self::measure_height may be used at this point to determine size requirements.

  4. Call Self::prepare_lines to wrap text and perform re-ordering (where lines are bi-directional) and horizontal alignment.

    This must be called again if any of wrap_width, width_bound or h_align change.

  5. Call Self::vertically_align to set or adjust vertical alignment. (Not technically required if alignment is always top.)

All methods are idempotent (that is, they may be called multiple times without affecting the result). Later stages of preparation do not affect earlier stages, but if an earlier stage is repeated to account for adjusted configuration then later stages must also be repeated.

This struct does not track the state of preparation. It is recommended to use Text or a custom wrapper for that purpose. Failure to observe the correct sequence is memory-safe but may cause panic or an unexpected result.

§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 a text 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 forwards or backwards should be done via a library such as unicode-segmentation which provides a GraphemeCursor to step back or forward one “grapheme”, in logical text order. 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.

Navigating glyphs left or right in display-order is not currently supported.

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

Source

pub fn text_glyph_pos(&self, index: usize) -> MarkerPosIter

Find the starting position (top-left) of the glyph at the given index

Requires status: text is fully prepared for display.

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.

Source

pub fn glyphs<F>(&self, f: F)
where F: FnMut(FaceId, f32, Glyph),

Yield a sequence of positioned glyphs

Requires status: text is fully prepared for display.

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().unwrap_or(0));
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.

Source

pub fn glyphs_with_effects<X, F, G>( &self, effects: &[Effect<X>], default_aux: X, f: F, g: G, )
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

Requires status: text is fully prepared for display.

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

pub fn highlight_range( &self, range: Range<usize>, f: &mut dyn FnMut(Vec2, Vec2), )

Yield a sequence of rectangles to highlight a given text range

Requires status: text is fully prepared for display.

Calls f(top_left, bottom_right) for each highlighting rectangle.

Source§

impl TextDisplay

Source

pub fn resize_runs<F>(&mut self, text: &F, dpem: f32)
where F: FormattableText + ?Sized,

Update font size

Requires status: level runs have been prepared and are valid in all ways except size (dpem).

This updates the result of TextDisplay::prepare_runs due to change in font size.

Source

pub fn prepare_runs<F>( &mut self, text: &F, direction: Direction, font_id: FontId, dpem: f32, ) -> Result<(), InvalidFontId>
where F: FormattableText + ?Sized,

Break text into level runs

Requires status: none.

Must be called again if any of text, direction or font_id change. If only dpem changes, Self::resize_runs may be called instead.

The text is broken into a set of contiguous “level runs”. These runs are maximal slices of the text which do not contain explicit line breaks and have a single text direction according to the Unicode Bidirectional Algorithm.

Source§

impl TextDisplay

Source

pub fn measure_width(&self, max_width: f32) -> f32

Measure required width, up to some max_width

Requires status: level runs have been prepared.

This method allows calculation of the width requirement of a text object without full wrapping and glyph placement. Whenever the requirement exceeds max_width, the algorithm stops early, returning max_width.

The return value is unaffected by alignment and wrap configuration.

Source

pub fn measure_height(&self, wrap_width: f32) -> f32

Measure required vertical height, wrapping as configured

Requires status: level runs have been prepared.

This method performs most required preparation steps of the TextDisplay. Remaining prepartion should be fast.

Source

pub fn prepare_lines( &mut self, wrap_width: f32, width_bound: f32, h_align: Align, ) -> f32

Prepare lines (“wrap”)

Requires status: level runs have been prepared.

This does text layout, including wrapping and horizontal alignment but excluding vertical alignment.

Returns the required height.

Source

pub fn vertically_align(&mut self, bound: f32, v_align: Align)

Vertically align lines

Requires status: lines have been wrapped.

Source§

impl TextDisplay

Source

pub fn num_lines(&self) -> usize

Get the number of lines (after wrapping)

Requires status: lines have been wrapped.

Source

pub fn bounding_box(&self) -> (Vec2, Vec2)

Get the size of the required bounding box

Requires status: lines have been wrapped.

Returns the position of the upper-left and lower-right corners of a bounding box on content. Alignment and input bounds do affect the result.

Source

pub fn find_line(&self, index: usize) -> Option<(usize, Range<usize>)>

Find the line containing text index

Requires status: lines have been wrapped.

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).

Source

pub fn line_range(&self, line: usize) -> Option<Range<usize>>

Get the range of a line, by line number

Requires status: lines have been wrapped.

Source

pub fn text_is_rtl(&self, text: &str, direction: Direction) -> bool

Get the base directionality of the text

Requires status: none.

Source

pub fn line_is_rtl(&self, line: usize) -> Option<bool>

Get the directionality of the current line

Requires status: lines have been wrapped.

Returns:

  • None if text is empty
  • 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.

Source

pub fn text_index_nearest(&self, pos: Vec2) -> usize

Find the text index for the glyph nearest the given pos

Requires status: text is fully prepared for display.

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.

Source

pub fn line_index_nearest(&self, line: usize, x: f32) -> Option<usize>

Find the text index nearest horizontal-coordinate x on line

Requires status: lines have been wrapped.

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 Clone for TextDisplay

Source§

fn clone(&self) -> TextDisplay

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TextDisplay

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for TextDisplay

Source§

fn default() -> TextDisplay

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<S, T> Cast<T> for S
where T: Conv<S>,

Source§

fn cast(self) -> T

Cast from Self to T Read more
Source§

fn try_cast(self) -> Result<T, Error>

Try converting from Self to T Read more
Source§

impl<S, T> CastApprox<T> for S
where T: ConvApprox<S>,

Source§

fn try_cast_approx(self) -> Result<T, Error>

Try approximate conversion from Self to T Read more
Source§

fn cast_approx(self) -> T

Cast approximately from Self to T Read more
Source§

impl<S, T> CastFloat<T> for S
where T: ConvFloat<S>,

Source§

fn cast_trunc(self) -> T

Cast to integer, truncating Read more
Source§

fn cast_nearest(self) -> T

Cast to the nearest integer Read more
Source§

fn cast_floor(self) -> T

Cast the floor to an integer Read more
Source§

fn cast_ceil(self) -> T

Cast the ceiling to an integer Read more
Source§

fn try_cast_trunc(self) -> Result<T, Error>

Try converting to integer with truncation Read more
Source§

fn try_cast_nearest(self) -> Result<T, Error>

Try converting to the nearest integer Read more
Source§

fn try_cast_floor(self) -> Result<T, Error>

Try converting the floor to an integer Read more
Source§

fn try_cast_ceil(self) -> Result<T, Error>

Try convert the ceiling to an integer Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<R, P> ReadPrimitive<R> for P
where R: Read + ReadEndian<P>, P: Default,

Source§

fn read_from_little_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_little_endian().
Source§

fn read_from_big_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_big_endian().
Source§

fn read_from_native_endian(read: &mut R) -> Result<Self, Error>

Read this value from the supplied reader. Same as ReadEndian::read_from_native_endian().
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more