Skip to content

Commit adbcf69

Browse files
committed
Allow disabling using color tables for fonts
1 parent 97d9f48 commit adbcf69

File tree

12 files changed

+80
-53
lines changed

12 files changed

+80
-53
lines changed

crates/krilla/src/font/bitmap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ mod tests {
451451
#[visreg(document, pdfium, mupdf, pdfbox, ghostscript, poppler, quartz)]
452452
fn noto_color_emoji_cbdt(document: &mut Document) {
453453
let font_data = NOTO_COLOR_EMOJI_CBDT.clone();
454-
all_glyphs_to_pdf(font_data, None, false, document);
454+
all_glyphs_to_pdf(font_data, None, false, true, document);
455455
}
456456

457457
#[cfg(target_os = "macos")]
@@ -461,6 +461,6 @@ mod tests {
461461

462462
let font_data =
463463
Arc::new(std::fs::read("/System/Library/Fonts/Apple Color Emoji.ttc").unwrap());
464-
all_glyphs_to_pdf(font_data, None, false, document);
464+
all_glyphs_to_pdf(font_data, None, false, true, document);
465465
}
466466
}

crates/krilla/src/font/colr.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,13 +480,13 @@ mod tests {
480480
.map(|n| (GlyphId::new(n), "".to_string()))
481481
.collect::<Vec<_>>();
482482

483-
all_glyphs_to_pdf(font_data, Some(glyphs), false, document);
483+
all_glyphs_to_pdf(font_data, Some(glyphs), false, true, document);
484484
}
485485

486486
#[visreg]
487487
fn colr_context_color(surface: &mut Surface) {
488488
let font_data = COLR_TEST_GLYPHS.clone();
489-
let font = Font::new(font_data, 0).unwrap();
489+
let font = Font::new(font_data, 0, true).unwrap();
490490

491491
let text = [
492492
0xf0b00, 0xf0b01, 0xf0b02, 0xf0b03, 0xf0b04, 0xf0b05, 0xf0b06, 0xf0b07,
@@ -570,6 +570,6 @@ mod tests {
570570
#[visreg(document, pdfium, mupdf, pdfbox, ghostscript, poppler, quartz)]
571571
fn noto_color_emoji_colr(document: &mut Document) {
572572
let font_data = NOTO_COLOR_EMOJI_COLR.clone();
573-
all_glyphs_to_pdf(font_data, None, false, document);
573+
all_glyphs_to_pdf(font_data, None, false, true, document);
574574
}
575575
}

crates/krilla/src/font/mod.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,24 @@ pub use skrifa::GlyphId;
5151
pub struct Font(Arc<Prehashed<Repr>>);
5252

5353
impl Font {
54-
/// Create a new font from some data. The `index` indicates the index that should be
54+
/// Create a new font from some data.
55+
///
56+
/// The `index` indicates the index that should be
5557
/// associated with this font for TrueType collections, otherwise this value should be
5658
/// set to 0. The location indicates the variation axes that should be associated with
5759
/// the font.
5860
///
61+
/// The `allow_color` property allows you to specify whether krilla should render the font
62+
/// as a color font. When setting this property to false, krilla will always only use the
63+
/// `glyf`/`CFF` tables of the font. If you don't know what this means, just set it to `true`.
64+
///
5965
/// Returns `None` if the index is invalid or the font couldn't be read.
60-
pub fn new(data: Arc<dyn AsRef<[u8]> + Send + Sync>, index: u32) -> Option<Self> {
61-
let font_info = FontInfo::new(data.as_ref().as_ref(), index)?;
66+
pub fn new(
67+
data: Arc<dyn AsRef<[u8]> + Send + Sync>,
68+
index: u32,
69+
allow_color: bool,
70+
) -> Option<Self> {
71+
let font_info = FontInfo::new(data.as_ref().as_ref(), index, allow_color)?;
6272

6373
Font::new_with_info(data, Arc::new(font_info))
6474
}
@@ -108,6 +118,10 @@ impl Font {
108118
self.0.font_info.ascent.get()
109119
}
110120

121+
pub(crate) fn allow_color(&self) -> bool {
122+
self.0.font_info.allow_color
123+
}
124+
111125
pub(crate) fn weight(&self) -> f32 {
112126
self.0.font_info.weight.get()
113127
}
@@ -182,6 +196,7 @@ pub(crate) struct FontInfo {
182196
global_bbox: RectWrapper,
183197
postscript_name: Option<String>,
184198
ascent: FiniteF32,
199+
allow_color: bool,
185200
descent: FiniteF32,
186201
cap_height: Option<FiniteF32>,
187202
is_monospaced: bool,
@@ -208,7 +223,7 @@ impl Hash for Repr {
208223
}
209224

210225
impl FontInfo {
211-
pub(crate) fn new(data: &[u8], index: u32) -> Option<Self> {
226+
pub(crate) fn new(data: &[u8], index: u32, allow_color: bool) -> Option<Self> {
212227
let font_ref = FontRef::from_index(data, index).ok()?;
213228
let checksum = font_ref.head().ok()?.checksum_adjustment();
214229

@@ -252,6 +267,7 @@ impl FontInfo {
252267
index,
253268
checksum,
254269
location,
270+
allow_color,
255271
units_per_em,
256272
postscript_name,
257273
ascent,

crates/krilla/src/font/svg.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,19 @@ mod tests {
8080
#[visreg(document, all)]
8181
fn twitter_color_emoji(document: &mut Document) {
8282
let font_data = TWITTER_COLOR_EMOJI.clone();
83-
all_glyphs_to_pdf(font_data, None, false, document);
83+
all_glyphs_to_pdf(font_data, None, false, true, document);
84+
}
85+
86+
#[visreg(document)]
87+
fn twitter_color_emoji_no_color(document: &mut Document) {
88+
let font_data = TWITTER_COLOR_EMOJI.clone();
89+
all_glyphs_to_pdf(font_data, None, false, false, document);
8490
}
8591

8692
#[visreg]
8793
fn svg_extra(surface: &mut Surface) {
8894
let font_data = SVG_EXTRA.clone();
89-
let font = Font::new(font_data, 0).unwrap();
95+
let font = Font::new(font_data, 0, true).unwrap();
9096

9197
surface.fill_text(
9298
Point::from_xy(0., 30.0),

crates/krilla/src/object/font/cid_font.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ mod tests {
357357

358358
#[snapshot]
359359
fn cid_font_noto_sans_two_glyphs(sc: &mut SerializerContext) {
360-
let font = Font::new(NOTO_SANS.clone(), 0).unwrap();
360+
let font = Font::new(NOTO_SANS.clone(), 0, true).unwrap();
361361
let container = sc.create_or_get_font_container(font.clone());
362362
let mut font_container = container.borrow_mut();
363363

@@ -374,7 +374,7 @@ mod tests {
374374

375375
#[visreg(all)]
376376
fn cid_font_noto_sans_simple_text(surface: &mut Surface) {
377-
let font = Font::new(NOTO_SANS.clone(), 0).unwrap();
377+
let font = Font::new(NOTO_SANS.clone(), 0, true).unwrap();
378378
surface.fill_text(
379379
Point::from_xy(0.0, 100.0),
380380
Fill::default(),
@@ -389,7 +389,7 @@ mod tests {
389389

390390
#[visreg(all)]
391391
fn cid_font_latin_modern_simple_text(surface: &mut Surface) {
392-
let font = Font::new(LATIN_MODERN_ROMAN.clone(), 0).unwrap();
392+
let font = Font::new(LATIN_MODERN_ROMAN.clone(), 0, true).unwrap();
393393
surface.fill_text(
394394
Point::from_xy(0.0, 100.0),
395395
Fill::default(),
@@ -404,7 +404,7 @@ mod tests {
404404

405405
#[visreg(all)]
406406
fn cid_font_noto_arabic_simple_text(surface: &mut Surface) {
407-
let font = Font::new(NOTO_SANS_ARABIC.clone(), 0).unwrap();
407+
let font = Font::new(NOTO_SANS_ARABIC.clone(), 0, true).unwrap();
408408
surface.fill_text(
409409
Point::from_xy(0.0, 100.0),
410410
Fill::default(),
@@ -419,7 +419,7 @@ mod tests {
419419

420420
#[snapshot]
421421
fn cid_font_latin_modern_four_glyphs(sc: &mut SerializerContext) {
422-
let font = Font::new(LATIN_MODERN_ROMAN.clone(), 0).unwrap();
422+
let font = Font::new(LATIN_MODERN_ROMAN.clone(), 0, true).unwrap();
423423
let container = sc.create_or_get_font_container(font.clone());
424424
let mut font_container = container.borrow_mut();
425425

@@ -445,9 +445,9 @@ mod tests {
445445

446446
let font_data =
447447
Arc::new(std::fs::read("/System/Library/Fonts/Supplemental/Songti.ttc").unwrap());
448-
let font_1 = Font::new(font_data.clone(), 0).unwrap();
449-
let font_2 = Font::new(font_data.clone(), 3).unwrap();
450-
let font_3 = Font::new(font_data, 6).unwrap();
448+
let font_1 = Font::new(font_data.clone(), 0, true).unwrap();
449+
let font_2 = Font::new(font_data.clone(), 3, true).unwrap();
450+
let font_3 = Font::new(font_data, 6, true).unwrap();
451451

452452
surface.fill_text(
453453
Point::from_xy(0.0, 75.0),

crates/krilla/src/object/font/type3_font.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ mod tests {
552552
#[test]
553553
fn type3_more_than_256_glyphs() {
554554
let mut sc = SerializerContext::new(SerializeSettings::settings_1());
555-
let font = Font::new(TWITTER_COLOR_EMOJI.clone(), 0).unwrap();
555+
let font = Font::new(TWITTER_COLOR_EMOJI.clone(), 0, true).unwrap();
556556
let container = sc.create_or_get_font_container(font.clone());
557557
let mut font_container = container.borrow_mut();
558558

@@ -586,7 +586,7 @@ mod tests {
586586

587587
#[snapshot(single_page, settings_1)]
588588
fn type3_color_glyphs(page: &mut Page) {
589-
let font = Font::new(TWITTER_COLOR_EMOJI.clone(), 0).unwrap();
589+
let font = Font::new(TWITTER_COLOR_EMOJI.clone(), 0, true).unwrap();
590590
let mut surface = page.surface();
591591

592592
surface.fill_text(
@@ -603,7 +603,7 @@ mod tests {
603603

604604
#[snapshot(single_page, settings_17)]
605605
fn type3_pdf_14(page: &mut Page) {
606-
let font = Font::new(TWITTER_COLOR_EMOJI.clone(), 0).unwrap();
606+
let font = Font::new(TWITTER_COLOR_EMOJI.clone(), 0, true).unwrap();
607607
let mut surface = page.surface();
608608

609609
surface.fill_text(

crates/krilla/src/serialize.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,11 +425,15 @@ impl SerializerContext {
425425
// For now, we make the simplifying assumption that a font is either mapped
426426
// to a series of Type3 fonts or to a single CID font, but not a mix of both.
427427
let font_ref = font.font_ref();
428-
let use_type3 = font_ref.svg().is_ok()
429-
|| font_ref.colr().is_ok()
430-
|| font_ref.sbix().is_ok()
431-
|| font_ref.cbdt().is_ok()
432-
|| font_ref.ebdt().is_ok();
428+
let use_type3 = if !font.allow_color() {
429+
false
430+
} else {
431+
font_ref.svg().is_ok()
432+
|| font_ref.colr().is_ok()
433+
|| font_ref.sbix().is_ok()
434+
|| font_ref.cbdt().is_ok()
435+
|| font_ref.ebdt().is_ok()
436+
};
433437

434438
if use_type3 {
435439
Rc::new(RefCell::new(FontContainer::Type3(Type3FontMapper::new(
@@ -487,7 +491,7 @@ impl SerializerContext {
487491
// cheaper, and then check whether we already have a corresponding font object in the cache.
488492
// If not, we still need to construct it.
489493
if let Some((font_data, index)) = unsafe { db.make_shared_face_data(id) } {
490-
if let Some(font_info) = FontInfo::new(font_data.as_ref().as_ref(), index) {
494+
if let Some(font_info) = FontInfo::new(font_data.as_ref().as_ref(), index, true) {
491495
let font_info = Arc::new(font_info);
492496
let font = self
493497
.font_cache

crates/krilla/src/surface.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ mod tests {
658658

659659
#[visreg]
660660
fn text_direction_ltr(surface: &mut Surface) {
661-
let font = Font::new(NOTO_SANS_CJK.clone(), 0).unwrap();
661+
let font = Font::new(NOTO_SANS_CJK.clone(), 0, true).unwrap();
662662
surface.fill_text(
663663
Point::from_xy(0.0, 100.0),
664664
Fill::default(),
@@ -673,7 +673,7 @@ mod tests {
673673

674674
#[visreg]
675675
fn text_direction_rtl(surface: &mut Surface) {
676-
let font = Font::new(NOTO_SANS_CJK.clone(), 0).unwrap();
676+
let font = Font::new(NOTO_SANS_CJK.clone(), 0, true).unwrap();
677677
surface.fill_text(
678678
Point::from_xy(0.0, 100.0),
679679
Fill::default(),
@@ -688,7 +688,7 @@ mod tests {
688688

689689
#[visreg]
690690
fn text_direction_ttb(surface: &mut Surface) {
691-
let font = Font::new(NOTO_SANS_CJK.clone(), 0).unwrap();
691+
let font = Font::new(NOTO_SANS_CJK.clone(), 0, true).unwrap();
692692
surface.fill_text(
693693
Point::from_xy(100.0, 0.0),
694694
Fill::default(),
@@ -703,7 +703,7 @@ mod tests {
703703

704704
#[visreg]
705705
fn text_direction_btt(surface: &mut Surface) {
706-
let font = Font::new(NOTO_SANS_CJK.clone(), 0).unwrap();
706+
let font = Font::new(NOTO_SANS_CJK.clone(), 0, true).unwrap();
707707
surface.fill_text(
708708
Point::from_xy(100.0, 0.0),
709709
Fill::default(),
@@ -783,7 +783,7 @@ mod tests {
783783
surface.fill_text(
784784
Point::from_xy(0.0, 50.0),
785785
Fill::default(),
786-
Font::new(NOTO_SANS.clone(), 0).unwrap(),
786+
Font::new(NOTO_SANS.clone(), 0, true).unwrap(),
787787
16.0,
788788
&[],
789789
"hi there",
@@ -797,7 +797,7 @@ mod tests {
797797
surface.stroke_text(
798798
Point::from_xy(0.0, 50.0),
799799
Stroke::default(),
800-
Font::new(NOTO_SANS.clone(), 0).unwrap(),
800+
Font::new(NOTO_SANS.clone(), 0, true).unwrap(),
801801
16.0,
802802
&[],
803803
"hi there",
@@ -811,7 +811,7 @@ mod tests {
811811
surface.fill_text(
812812
Point::from_xy(0.0, 50.0),
813813
Fill::default(),
814-
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0).unwrap(),
814+
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0, true).unwrap(),
815815
16.0,
816816
&[],
817817
"यह कुछ जटिल पाठ है.",
@@ -825,7 +825,7 @@ mod tests {
825825
surface.fill_text(
826826
Point::from_xy(0.0, 50.0),
827827
Fill::default(),
828-
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0).unwrap(),
828+
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0, true).unwrap(),
829829
16.0,
830830
&[],
831831
"यु॒धा नर॑ ऋ॒ष्वा ",
@@ -839,7 +839,7 @@ mod tests {
839839
surface.fill_text(
840840
Point::from_xy(0.0, 50.0),
841841
Fill::default(),
842-
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0).unwrap(),
842+
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0, true).unwrap(),
843843
16.0,
844844
&[],
845845
"आ रु॒क्मैरा यु॒धा नर॑ ऋ॒ष्वा ऋ॒ष्टीर॑सृक्षत ।",
@@ -853,7 +853,7 @@ mod tests {
853853
surface.fill_text(
854854
Point::from_xy(0.0, 50.0),
855855
Fill::default(),
856-
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0).unwrap(),
856+
Font::new(NOTO_SANS_DEVANAGARI.clone(), 0, true).unwrap(),
857857
16.0,
858858
&[],
859859
"अन्वे॑नाँ॒ अह॑ वि॒द्युतो॑ म॒रुतो॒ जज्झ॑तीरव भनर॑र्त॒ त्मना॑ दि॒वः ॥",
@@ -956,7 +956,7 @@ mod tests {
956956
}
957957

958958
fn text_with_fill_impl(surface: &mut Surface, outlined: bool) {
959-
let font = Font::new(NOTO_SANS.clone(), 0).unwrap();
959+
let font = Font::new(NOTO_SANS.clone(), 0, true).unwrap();
960960
surface.fill_text(
961961
Point::from_xy(0.0, 80.0),
962962
red_fill(0.5),
@@ -995,7 +995,7 @@ mod tests {
995995
TextDirection::Auto,
996996
);
997997

998-
let noto_font = Font::new(NOTO_COLOR_EMOJI_COLR.clone(), 0).unwrap();
998+
let noto_font = Font::new(NOTO_COLOR_EMOJI_COLR.clone(), 0, true).unwrap();
999999

10001000
surface.fill_text(
10011001
Point::from_xy(0.0, 140.0),
@@ -1031,7 +1031,7 @@ mod tests {
10311031
}
10321032

10331033
fn text_with_stroke_impl(surface: &mut Surface, outlined: bool) {
1034-
let font = Font::new(NOTO_SANS.clone(), 0).unwrap();
1034+
let font = Font::new(NOTO_SANS.clone(), 0, true).unwrap();
10351035
surface.stroke_text(
10361036
Point::from_xy(0.0, 80.0),
10371037
red_stroke(0.5, 1.0),
@@ -1070,7 +1070,7 @@ mod tests {
10701070
TextDirection::Auto,
10711071
);
10721072

1073-
let font = Font::new(NOTO_COLOR_EMOJI_COLR.clone(), 0).unwrap();
1073+
let font = Font::new(NOTO_COLOR_EMOJI_COLR.clone(), 0, true).unwrap();
10741074

10751075
surface.stroke_text(
10761076
Point::from_xy(0.0, 140.0),
@@ -1091,7 +1091,7 @@ mod tests {
10911091

10921092
#[visreg]
10931093
fn text_zalgo(surface: &mut Surface) {
1094-
let font = Font::new(NOTO_SANS.clone(), 0).unwrap();
1094+
let font = Font::new(NOTO_SANS.clone(), 0, true).unwrap();
10951095
surface.fill_text(
10961096
Point::from_xy(0.0, 100.0),
10971097
Fill::default(),
@@ -1106,7 +1106,7 @@ mod tests {
11061106

11071107
#[visreg]
11081108
fn text_zalgo_outlined(surface: &mut Surface) {
1109-
let font = Font::new(NOTO_SANS.clone(), 0).unwrap();
1109+
let font = Font::new(NOTO_SANS.clone(), 0, true).unwrap();
11101110
surface.fill_text(
11111111
Point::from_xy(0.0, 100.0),
11121112
Fill::default(),

crates/krilla/src/tagging.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,7 +949,7 @@ mod tests {
949949
impl SurfaceExt for Surface<'_> {
950950
fn fill_text_(&mut self, y: f32, content: &str) {
951951
let font_data = NOTO_SANS.clone();
952-
let font = Font::new(font_data, 0).unwrap();
952+
let font = Font::new(font_data, 0, true).unwrap();
953953

954954
self.fill_text(
955955
tiny_skia_path::Point::from_xy(0.0, y),

0 commit comments

Comments
 (0)