Don't panic when no font is found for a TextRun (#30581)

Instead of panicking when no found is found for a TextRun, instead print
a warning. This prevents panics on pages with very large font sizes.
This commit is contained in:
Martin Robinson 2023-10-19 18:59:54 +02:00 committed by GitHub
parent fd31da9102
commit d7207122c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 28 deletions

View file

@ -14,7 +14,7 @@ use gfx::font::{self, FontMetrics, FontRef, RunMetrics, ShapingFlags, ShapingOpt
use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::TextRun;
use gfx::text::util::{self, CompressionMode};
use log::debug;
use log::{debug, warn};
use range::Range;
use servo_atoms::Atom;
use style::computed_values::text_rendering::T as TextRendering;
@ -368,10 +368,16 @@ impl TextRunScanner {
}
// If no font is found (including fallbacks), there's no way we can render.
let font = run_info
let font = match run_info
.font
.or_else(|| font_group.borrow_mut().first(&mut font_context))
.expect("No font found for text run!");
{
Some(font) => font,
None => {
result.push(None);
continue;
},
};
let (run, break_at_zero) = TextRun::new(
&mut *font.borrow_mut(),
@ -380,13 +386,13 @@ impl TextRunScanner {
run_info.bidi_level,
linebreaker,
);
result.push((
result.push(Some((
ScannedTextRun {
run: Arc::new(run),
insertion_point: run_info.insertion_point,
},
break_at_zero,
))
)))
}
result
};
@ -417,7 +423,14 @@ impl TextRunScanner {
},
};
let mapping = mappings.next().unwrap();
let (scanned_run, break_at_zero) = runs[mapping.text_run_index].clone();
let run = runs[mapping.text_run_index].clone();
let (scanned_run, break_at_zero) = match run {
Some(run) => run,
None => {
warn!("Could not find found for TextRun!");
continue;
},
};
let mut byte_range = Range::new(
ByteIndex(mapping.byte_range.begin() as isize),

View file

@ -8,6 +8,7 @@ use app_units::Au;
use atomic_refcell::AtomicRef;
use gfx::text::glyph::GlyphStore;
use gfx::text::text_run::GlyphRun;
use log::warn;
use serde::Serialize;
use servo_arc::Arc;
use style::computed_values::white_space::T as WhiteSpace;
@ -739,12 +740,17 @@ impl InlineFormattingContext {
add!(last_fragment, inline_end);
},
InlineLevelBox::TextRun(text_run) => {
let result = text_run
.break_and_shape(self.layout_context, &mut self.linebreaker);
let BreakAndShapeResult {
runs,
break_at_start,
..
} = text_run
.break_and_shape(self.layout_context, &mut self.linebreaker);
} = match result {
Ok(result) => result,
Err(_) => return,
};
if break_at_start {
self.line_break_opportunity()
}
@ -1223,7 +1229,7 @@ impl TextRun {
&self,
layout_context: &LayoutContext,
linebreaker: &mut Option<LineBreakLeafIter>,
) -> BreakAndShapeResult {
) -> Result<BreakAndShapeResult, &'static str> {
use gfx::font::ShapingFlags;
use style::computed_values::text_rendering::T as TextRendering;
use style::computed_values::word_break::T as WordBreak;
@ -1250,10 +1256,10 @@ impl TextRun {
crate::context::with_thread_local_font_context(layout_context, |font_context| {
let font_group = font_context.font_group(font_style);
let font = font_group
.borrow_mut()
.first(font_context)
.expect("could not find font");
let font = match font_group.borrow_mut().first(font_context) {
Some(font) => font,
None => return Err("Could not find find for TextRun."),
};
let mut font = font.borrow_mut();
let word_spacing = &inherited_text_style.word_spacing;
@ -1282,12 +1288,12 @@ impl TextRun {
linebreaker,
);
BreakAndShapeResult {
Ok(BreakAndShapeResult {
font_metrics: (&font.metrics).into(),
font_key: font.font_key,
runs,
break_at_start,
}
})
})
}
@ -1313,12 +1319,19 @@ impl TextRun {
layout_context: &LayoutContext,
ifc: &mut InlineFormattingContextState,
) {
let result = self.break_and_shape(layout_context, &mut ifc.linebreaker);
let BreakAndShapeResult {
font_metrics,
font_key,
runs,
break_at_start,
} = self.break_and_shape(layout_context, &mut ifc.linebreaker);
} = match result {
Ok(result) => result,
Err(string) => {
warn!("Could not render TextRun: {string}");
return;
},
};
let white_space = self.parent_style.get_inherited_text().white_space;
let add_glyphs_to_current_line = |ifc: &mut InlineFormattingContextState,
@ -1679,10 +1692,13 @@ fn line_height(parent_style: &ComputedValues, font_metrics: &FontMetrics) -> Len
fn line_gap_from_style(layout_context: &LayoutContext, style: &ComputedValues) -> Length {
crate::context::with_thread_local_font_context(layout_context, |font_context| {
let font_group = font_context.font_group(style.clone_font());
let font = font_group
.borrow_mut()
.first(font_context)
.expect("could not find font");
let font = match font_group.borrow_mut().first(font_context) {
Some(font) => font,
None => {
warn!("Could not find find for TextRun.");
return Length::zero();
},
};
let font_metrics: FontMetrics = (&font.borrow().metrics).into();
font_metrics.line_gap
})
@ -1691,10 +1707,13 @@ fn line_gap_from_style(layout_context: &LayoutContext, style: &ComputedValues) -
fn line_height_from_style(layout_context: &LayoutContext, style: &ComputedValues) -> Length {
crate::context::with_thread_local_font_context(layout_context, |font_context| {
let font_group = font_context.font_group(style.clone_font());
let font = font_group
.borrow_mut()
.first(font_context)
.expect("could not find font");
let font = match font_group.borrow_mut().first(font_context) {
Some(font) => font,
None => {
warn!("Could not find find for TextRun.");
return Length::zero();
},
};
let font_metrics: FontMetrics = (&font.borrow().metrics).into();
line_height(style, &font_metrics)
})

View file

@ -1,2 +0,0 @@
[ellisize-rtl-text-crash.html]
expected: CRASH

View file

@ -1,2 +0,0 @@
[ellisize-rtl-text-crash.html]
expected: CRASH