mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Don't perform font matching for control characters
We can encounter control characters here, for example when processing a <pre> element which contains newlines. Control characters are inherently non-printing, therefore if we try to call find_by_codepoint for these characters we will end up triggering an unnecessary font fallback search.
This commit is contained in:
parent
691c6c6f1a
commit
4403bcddfe
1 changed files with 52 additions and 50 deletions
|
@ -215,61 +215,63 @@ impl TextRunScanner {
|
||||||
|
|
||||||
let (mut start_position, mut end_position) = (0, 0);
|
let (mut start_position, mut end_position) = (0, 0);
|
||||||
for (byte_index, character) in text.char_indices() {
|
for (byte_index, character) in text.char_indices() {
|
||||||
let font = font_group.borrow_mut().find_by_codepoint(&mut font_context, character);
|
if !character.is_control() {
|
||||||
|
let font = font_group.borrow_mut().find_by_codepoint(&mut font_context, character);
|
||||||
|
|
||||||
let bidi_level = match bidi_levels {
|
let bidi_level = match bidi_levels {
|
||||||
Some(levels) => levels[*paragraph_bytes_processed],
|
Some(levels) => levels[*paragraph_bytes_processed],
|
||||||
None => bidi::Level::ltr(),
|
None => bidi::Level::ltr(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Break the run if the new character has a different explicit script than the
|
// Break the run if the new character has a different explicit script than the
|
||||||
// previous characters.
|
// previous characters.
|
||||||
//
|
//
|
||||||
// TODO: Special handling of paired punctuation characters.
|
// TODO: Special handling of paired punctuation characters.
|
||||||
// http://www.unicode.org/reports/tr24/#Common
|
// http://www.unicode.org/reports/tr24/#Common
|
||||||
let script = get_script(character);
|
let script = get_script(character);
|
||||||
let compatible_script = is_compatible(script, run_info.script);
|
let compatible_script = is_compatible(script, run_info.script);
|
||||||
if compatible_script && !is_specific(run_info.script) && is_specific(script) {
|
if compatible_script && !is_specific(run_info.script) && is_specific(script) {
|
||||||
run_info.script = script;
|
run_info.script = script;
|
||||||
}
|
|
||||||
|
|
||||||
let selected = match selection {
|
|
||||||
Some(range) => range.contains(ByteIndex(byte_index as isize)),
|
|
||||||
None => false
|
|
||||||
};
|
|
||||||
|
|
||||||
// Now, if necessary, flush the mapping we were building up.
|
|
||||||
let flush_run = !run_info.has_font(&font) ||
|
|
||||||
run_info.bidi_level != bidi_level ||
|
|
||||||
!compatible_script;
|
|
||||||
let new_mapping_needed = flush_run || mapping.selected != selected;
|
|
||||||
|
|
||||||
if new_mapping_needed {
|
|
||||||
// We ignore empty mappings at the very start of a fragment.
|
|
||||||
// The run info values are uninitialized at this point so
|
|
||||||
// flushing an empty mapping is pointless.
|
|
||||||
if end_position > 0 {
|
|
||||||
mapping.flush(&mut mappings,
|
|
||||||
&mut run_info,
|
|
||||||
&**text,
|
|
||||||
compression,
|
|
||||||
text_transform,
|
|
||||||
&mut last_whitespace,
|
|
||||||
&mut start_position,
|
|
||||||
end_position);
|
|
||||||
}
|
}
|
||||||
if run_info.text.len() > 0 {
|
|
||||||
if flush_run {
|
let selected = match selection {
|
||||||
run_info.flush(&mut run_info_list, &mut insertion_point);
|
Some(range) => range.contains(ByteIndex(byte_index as isize)),
|
||||||
run_info = RunInfo::new();
|
None => false
|
||||||
|
};
|
||||||
|
|
||||||
|
// Now, if necessary, flush the mapping we were building up.
|
||||||
|
let flush_run = !run_info.has_font(&font) ||
|
||||||
|
run_info.bidi_level != bidi_level ||
|
||||||
|
!compatible_script;
|
||||||
|
let new_mapping_needed = flush_run || mapping.selected != selected;
|
||||||
|
|
||||||
|
if new_mapping_needed {
|
||||||
|
// We ignore empty mappings at the very start of a fragment.
|
||||||
|
// The run info values are uninitialized at this point so
|
||||||
|
// flushing an empty mapping is pointless.
|
||||||
|
if end_position > 0 {
|
||||||
|
mapping.flush(&mut mappings,
|
||||||
|
&mut run_info,
|
||||||
|
&**text,
|
||||||
|
compression,
|
||||||
|
text_transform,
|
||||||
|
&mut last_whitespace,
|
||||||
|
&mut start_position,
|
||||||
|
end_position);
|
||||||
}
|
}
|
||||||
mapping = RunMapping::new(&run_info_list[..],
|
if run_info.text.len() > 0 {
|
||||||
fragment_index);
|
if flush_run {
|
||||||
|
run_info.flush(&mut run_info_list, &mut insertion_point);
|
||||||
|
run_info = RunInfo::new();
|
||||||
|
}
|
||||||
|
mapping = RunMapping::new(&run_info_list[..],
|
||||||
|
fragment_index);
|
||||||
|
}
|
||||||
|
run_info.font = font;
|
||||||
|
run_info.bidi_level = bidi_level;
|
||||||
|
run_info.script = script;
|
||||||
|
mapping.selected = selected;
|
||||||
}
|
}
|
||||||
run_info.font = font;
|
|
||||||
run_info.bidi_level = bidi_level;
|
|
||||||
run_info.script = script;
|
|
||||||
mapping.selected = selected;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consume this character.
|
// Consume this character.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue