Skip to content

Commit f1b831c

Browse files
committed
Replace fns Text{,Display}::text_is_rtl
Note: the removed fn line_is_rtl was incorrect for BiDi text
1 parent 800cff9 commit f1b831c

File tree

3 files changed

+23
-64
lines changed

3 files changed

+23
-64
lines changed

src/display/mod.rs

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
//! Text prepared for display
77
8+
use crate::conv::to_usize;
89
#[allow(unused)]
910
use crate::{Status, Text};
10-
use crate::conv::to_usize;
11-
use crate::{Direction, Vec2, shaper};
11+
use crate::{Vec2, shaper};
1212
use smallvec::SmallVec;
1313
use tinyvec::TinyVec;
1414

@@ -105,6 +105,7 @@ pub struct TextDisplay {
105105
wrapped_runs: TinyVec<[RunPart; 1]>,
106106
/// Visual (wrapped) lines, in visual and logical order
107107
lines: TinyVec<[Line; 1]>,
108+
is_rtl: bool,
108109
l_bound: f32,
109110
r_bound: f32,
110111
}
@@ -117,7 +118,7 @@ fn size_of_elts() {
117118
assert_eq!(size_of::<shaper::GlyphRun>(), 112);
118119
assert_eq!(size_of::<RunPart>(), 24);
119120
assert_eq!(size_of::<Line>(), 24);
120-
assert_eq!(size_of::<TextDisplay>(), 200);
121+
assert_eq!(size_of::<TextDisplay>(), 208);
121122
}
122123

123124
impl Default for TextDisplay {
@@ -126,6 +127,7 @@ impl Default for TextDisplay {
126127
runs: Default::default(),
127128
wrapped_runs: Default::default(),
128129
lines: Default::default(),
130+
is_rtl: false,
129131
l_bound: 0.0,
130132
r_bound: 0.0,
131133
}
@@ -201,45 +203,13 @@ impl TextDisplay {
201203

202204
/// Get the base directionality of the text
203205
///
204-
/// [Requires status][Self#status-of-preparation]: none.
205-
pub fn text_is_rtl(&self, text: &str, direction: Direction) -> bool {
206-
let (is_auto, mut is_rtl) = match direction {
207-
Direction::Ltr => (false, false),
208-
Direction::Rtl => (false, true),
209-
Direction::Auto => (true, false),
210-
Direction::AutoRtl => (true, true),
211-
};
212-
213-
if is_auto {
214-
match unicode_bidi::get_base_direction(text) {
215-
unicode_bidi::Direction::Ltr => is_rtl = false,
216-
unicode_bidi::Direction::Rtl => is_rtl = true,
217-
unicode_bidi::Direction::Mixed => (),
218-
}
219-
}
220-
221-
is_rtl
222-
}
223-
224-
/// Get the directionality of the current line
225-
///
226-
/// [Requires status][Self#status-of-preparation]: lines have been wrapped.
227-
///
228-
/// Returns:
206+
/// [Requires status][Self#status-of-preparation]: run-breaking is complete.
229207
///
230-
/// - `None` if text is empty
231-
/// - `Some(line_is_right_to_left)` otherwise
232-
///
233-
/// Note: indeterminate lines (e.g. empty lines) have their direction
234-
/// determined from the passed environment, by default left-to-right.
235-
pub fn line_is_rtl(&self, line: usize) -> Option<bool> {
236-
if let Some(line) = self.lines.get(line) {
237-
let first_run = line.run_range.start();
238-
let glyph_run = to_usize(self.wrapped_runs[first_run].glyph_run);
239-
Some(self.runs[glyph_run].level.is_rtl())
240-
} else {
241-
None
242-
}
208+
/// This returns the direction inferred from the `text` and [`Direction`]
209+
/// used during run-breaking. See also [`Direction::text_is_rtl`].
210+
#[inline]
211+
pub fn text_is_rtl(&self) -> bool {
212+
self.is_rtl
243213
}
244214

245215
/// Find the text index for the glyph nearest the given `pos`

src/display/text_runs.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ impl TextDisplay {
213213
Direction::Rtl => Some(RTL_LEVEL),
214214
};
215215
let info = BidiInfo::new(text, default_para_level);
216+
self.is_rtl = info
217+
.paragraphs
218+
.first()
219+
.map(|p| p.level.is_rtl())
220+
.unwrap_or_default();
216221
let levels = info.levels;
217222
assert_eq!(text.len(), levels.len());
218223

src/text.rs

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -310,23 +310,15 @@ impl<T: FormattableText + ?Sized> Text<T> {
310310

311311
/// Get the base directionality of the text
312312
///
313-
/// This does not require that the text is prepared.
313+
/// This returns the direction inferred during run-breaking if available,
314+
/// falling back to [`Direction::text_is_rtl`].
315+
#[inline]
314316
pub fn text_is_rtl(&self) -> bool {
315-
let cached_is_rtl = match self.line_is_rtl(0) {
316-
Ok(None) => Some(self.direction == Direction::Rtl),
317-
Ok(Some(is_rtl)) => Some(is_rtl),
318-
Err(NotReady) => None,
319-
};
320-
#[cfg(not(debug_assertions))]
321-
if let Some(cached) = cached_is_rtl {
322-
return cached;
323-
}
324-
325-
let is_rtl = self.display.text_is_rtl(self.as_str(), self.direction);
326-
if let Some(cached) = cached_is_rtl {
327-
debug_assert_eq!(cached, is_rtl);
317+
if self.status >= Status::ResizeLevelRuns {
318+
self.display.text_is_rtl()
319+
} else {
320+
self.direction.text_is_rtl(&self.text.as_str())
328321
}
329-
is_rtl
330322
}
331323

332324
/// Return the sequence of effect tokens
@@ -509,14 +501,6 @@ impl<T: FormattableText + ?Sized> Text<T> {
509501
Ok(self.wrapped_display()?.find_line(index))
510502
}
511503

512-
/// Get the directionality of the current line
513-
///
514-
/// See [`TextDisplay::line_is_rtl`].
515-
#[inline]
516-
pub fn line_is_rtl(&self, line: usize) -> Result<Option<bool>, NotReady> {
517-
Ok(self.wrapped_display()?.line_is_rtl(line))
518-
}
519-
520504
/// Find the text index for the glyph nearest the given `pos`
521505
///
522506
/// See [`TextDisplay::text_index_nearest`].

0 commit comments

Comments
 (0)