aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/text.rs
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-09-17 05:50:41 -0600
committerbors-servo <metajack+bors@gmail.com>2015-09-17 05:50:41 -0600
commit6cd098da302db85975d0967ddee836f04eae3bd5 (patch)
tree79222a11adefbf19268838fb0f41fa692e244203 /components/layout/text.rs
parent9e914ca0db2820b365c06deedb8b5325c63c007b (diff)
parent757e2cf4e54e4a4ac1668066d6c280ae577851ab (diff)
downloadservo-6cd098da302db85975d0967ddee836f04eae3bd5.tar.gz
servo-6cd098da302db85975d0967ddee836f04eae3bd5.zip
Auto merge of #7644 - pcwalton:carrot, r=mbrubeck
layout: Draw the insertion point in input elements. Known issues: * The caret doesn't show up if there's no text present, because we don't create text runs in that case. This should be a followup. * Text runs don't support decomposing ligatures into their constituent subglyphs for advance computation, so the caret won't appear inside a ligature. This is a text run bug. r? @mbrubeck <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7644) <!-- Reviewable:end -->
Diffstat (limited to 'components/layout/text.rs')
-rw-r--r--components/layout/text.rs45
1 files changed, 38 insertions, 7 deletions
diff --git a/components/layout/text.rs b/components/layout/text.rs
index 856017c7f56..4657dc86e23 100644
--- a/components/layout/text.rs
+++ b/components/layout/text.rs
@@ -176,9 +176,12 @@ impl TextRunScanner {
let (mut run_info_list, mut run_info) = (Vec::new(), RunInfo::new());
for (fragment_index, in_fragment) in self.clump.iter().enumerate() {
let mut mapping = RunMapping::new(&run_info_list[..], &run_info, fragment_index);
- let text = match in_fragment.specific {
+ let text;
+ let insertion_point;
+ match in_fragment.specific {
SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => {
- &text_fragment_info.text
+ text = &text_fragment_info.text;
+ insertion_point = text_fragment_info.insertion_point;
}
_ => panic!("Expected an unscanned text fragment!"),
};
@@ -208,6 +211,7 @@ impl TextRunScanner {
mapping.flush(&mut mappings,
&mut run_info,
&**text,
+ insertion_point,
compression,
text_transform,
&mut last_whitespace,
@@ -239,6 +243,7 @@ impl TextRunScanner {
mapping.flush(&mut mappings,
&mut run_info,
&**text,
+ insertion_point,
compression,
text_transform,
&mut last_whitespace,
@@ -275,7 +280,13 @@ impl TextRunScanner {
options.flags.insert(RTL_FLAG);
}
let mut font = fontgroup.fonts.get(run_info.font_index).unwrap().borrow_mut();
- Arc::new(TextRun::new(&mut *font, run_info.text, &options, run_info.bidi_level))
+ ScannedTextRun {
+ run: Arc::new(TextRun::new(&mut *font,
+ run_info.text,
+ &options,
+ run_info.bidi_level)),
+ insertion_point: run_info.insertion_point,
+ }
}).collect::<Vec<_>>()
};
@@ -296,19 +307,20 @@ impl TextRunScanner {
};
let mut mapping = mappings.next().unwrap();
- let run = runs[mapping.text_run_index].clone();
+ let scanned_run = runs[mapping.text_run_index].clone();
let requires_line_break_afterward_if_wrapping_on_newlines =
- run.text.char_at_reverse(mapping.byte_range.end()) == '\n';
+ scanned_run.run.text.char_at_reverse(mapping.byte_range.end()) == '\n';
if requires_line_break_afterward_if_wrapping_on_newlines {
mapping.char_range.extend_by(CharIndex(-1));
}
let text_size = old_fragment.border_box.size;
let mut new_text_fragment_info = box ScannedTextFragmentInfo::new(
- run,
+ scanned_run.run,
mapping.char_range,
text_size,
+ &scanned_run.insertion_point,
requires_line_break_afterward_if_wrapping_on_newlines);
let new_metrics = new_text_fragment_info.run.metrics_for_range(&mapping.char_range);
@@ -382,6 +394,7 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
let new_fragment = {
let mut first_fragment = fragments.front_mut().unwrap();
let string_before;
+ let insertion_point_before;
{
let unscanned_text_fragment_info = match first_fragment.specific {
SpecificFragmentInfo::UnscannedText(ref mut unscanned_text_fragment_info) => {
@@ -403,12 +416,14 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
string_before =
unscanned_text_fragment_info.text[..(position + 1)].to_owned();
+ insertion_point_before = unscanned_text_fragment_info.insertion_point;
unscanned_text_fragment_info.text =
unscanned_text_fragment_info.text[(position + 1)..].to_owned().into_boxed_str();
}
first_fragment.transform(first_fragment.border_box.size,
SpecificFragmentInfo::UnscannedText(
- UnscannedTextFragmentInfo::from_text(string_before)))
+ UnscannedTextFragmentInfo::new(string_before,
+ insertion_point_before)))
};
fragments.push_front(new_fragment);
@@ -418,6 +433,8 @@ fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragm
struct RunInfo {
/// The text that will go in this text run.
text: String,
+ /// The insertion point in this text run, if applicable.
+ insertion_point: Option<CharIndex>,
/// The index of the applicable font in the font group.
font_index: usize,
/// A cached copy of the number of Unicode characters in the text run.
@@ -430,6 +447,7 @@ impl RunInfo {
fn new() -> RunInfo {
RunInfo {
text: String::new(),
+ insertion_point: None,
font_index: 0,
character_length: 0,
bidi_level: 0,
@@ -472,6 +490,7 @@ impl RunMapping {
mappings: &mut Vec<RunMapping>,
run_info: &mut RunInfo,
text: &str,
+ insertion_point: Option<CharIndex>,
compression: CompressionMode,
text_transform: text_transform::T,
last_whitespace: &mut bool,
@@ -489,6 +508,12 @@ impl RunMapping {
old_byte_length,
text_transform);
+ // Record the position of the insertion point if necessary.
+ if let Some(insertion_point) = insertion_point {
+ run_info.insertion_point =
+ Some(CharIndex(run_info.character_length as isize + insertion_point.0))
+ }
+
run_info.character_length = run_info.character_length + character_count;
*start_position = end_position;
@@ -570,3 +595,9 @@ fn apply_style_transform_if_necessary(string: &mut String,
}
}
+#[derive(Clone)]
+struct ScannedTextRun {
+ run: Arc<TextRun>,
+ insertion_point: Option<CharIndex>,
+}
+