From b40db5b55d5035f3cae3078d0c92f75b6b49f9fd Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Wed, 11 Jan 2017 09:04:03 +0100 Subject: Position insertion point in input field with mouse --- components/gfx/text/glyph.rs | 21 +++++++++++++++++++++ components/gfx/text/text_run.rs | 15 +++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'components/gfx/text') diff --git a/components/gfx/text/glyph.rs b/components/gfx/text/glyph.rs index 5628547a417..73a66ff19bf 100644 --- a/components/gfx/text/glyph.rs +++ b/components/gfx/text/glyph.rs @@ -546,6 +546,27 @@ impl<'a> GlyphStore { } } + // Scan the glyphs for a given range until we reach a given advance. Returns the index + // and advance of the glyph in the range at the given advance, if reached. Otherwise, returns the + // the number of glyphs and the advance for the given range. + #[inline] + pub fn range_index_of_advance(&self, range: &Range, advance: Au, extra_word_spacing: Au) -> (usize, Au) { + let mut index = 0; + let mut current_advance = Au(0); + for glyph in self.iter_glyphs_for_byte_range(range) { + if glyph.char_is_space() { + current_advance += glyph.advance() + extra_word_spacing + } else { + current_advance += glyph.advance() + } + if current_advance > advance { + break; + } + index += 1; + } + (index, current_advance) + } + #[inline] pub fn advance_for_byte_range(&self, range: &Range, extra_word_spacing: Au) -> Au { if range.begin() == ByteIndex(0) && range.end() == self.len() { diff --git a/components/gfx/text/text_run.rs b/components/gfx/text/text_run.rs index db65dc49142..0f487a4b70e 100644 --- a/components/gfx/text/text_run.rs +++ b/components/gfx/text/text_run.rs @@ -304,6 +304,21 @@ impl<'a> TextRun { }) } + /// Returns the index in the range of the first glyph advancing over given advance + pub fn range_index_of_advance(&self, range: &Range, advance: Au) -> usize { + // TODO(Issue #199): alter advance direction for RTL + // TODO(Issue #98): using inter-char and inter-word spacing settings when measuring text + let mut remaining = advance; + self.natural_word_slices_in_range(range) + .map(|slice| { + let (slice_index, slice_advance) = + slice.glyphs.range_index_of_advance(&slice.range, remaining, self.extra_word_spacing); + remaining -= slice_advance; + slice_index + }) + .sum() + } + /// Returns an iterator that will iterate over all slices of glyphs that represent natural /// words in the given range. pub fn natural_word_slices_in_range(&'a self, range: &Range) -- cgit v1.2.3