Coverage Report

Created: 2025-07-23 06:50

/src/fontations/klippa/src/colr.rs
Line
Count
Source (jump to first uncovered line)
1
//! impl subset() for COLR
2
use crate::{
3
    offset::SerializeSubset,
4
    offset_array::SubsetOffsetArray,
5
    serialize::{SerializeErrorFlags, Serializer},
6
    variations::DeltaSetIndexMapSerializePlan,
7
    Plan, Subset, SubsetError, SubsetTable,
8
};
9
use fnv::FnvHashMap;
10
use skrifa::raw::{tables::colr::Affine2x3, ResolveOffset};
11
use write_fonts::{
12
    read::{
13
        collections::IntSet,
14
        tables::{
15
            colr::{
16
                BaseGlyph, BaseGlyphList, BaseGlyphPaint, ClipBox, ClipBoxFormat1, ClipBoxFormat2,
17
                ClipList, ColorLine, ColorStop, Colr, Layer, LayerList, Paint, PaintColrGlyph,
18
                PaintColrLayers, PaintComposite, PaintGlyph, PaintLinearGradient,
19
                PaintRadialGradient, PaintRotate, PaintRotateAroundCenter, PaintScale,
20
                PaintScaleAroundCenter, PaintScaleUniform, PaintScaleUniformAroundCenter,
21
                PaintSkew, PaintSkewAroundCenter, PaintSolid, PaintSweepGradient, PaintTransform,
22
                PaintTranslate, PaintVarLinearGradient, PaintVarRadialGradient, PaintVarRotate,
23
                PaintVarRotateAroundCenter, PaintVarScale, PaintVarScaleAroundCenter,
24
                PaintVarScaleUniform, PaintVarScaleUniformAroundCenter, PaintVarSkew,
25
                PaintVarSkewAroundCenter, PaintVarSolid, PaintVarSweepGradient, PaintVarTransform,
26
                PaintVarTranslate, VarAffine2x3, VarColorLine, VarColorStop,
27
            },
28
            variations::NO_VARIATION_INDEX,
29
        },
30
        FontRef, TopLevelTable,
31
    },
32
    types::{GlyphId, Offset24, Offset32},
33
    FontBuilder,
34
};
35
36
// reference: subset() for COLR in Harfbuzz:
37
// <https://github.com/harfbuzz/harfbuzz/blob/043980a60eb2fe93dd65b8c2f5eaa021fd8653f2/src/OT/Color/COLR/COLR.hh#L2414>
38
impl Subset for Colr<'_> {
39
0
    fn subset(
40
0
        &self,
41
0
        plan: &Plan,
42
0
        _font: &FontRef,
43
0
        s: &mut Serializer,
44
0
        _builder: &mut FontBuilder,
45
0
    ) -> Result<(), SubsetError> {
46
0
        let base_glyph_list = self
47
0
            .base_glyph_list()
48
0
            .transpose()
49
0
            .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?;
50
0
        let subset_to_v0 = downgrade_to_v0(base_glyph_list.as_ref(), plan);
51
0
52
0
        serialize_v0(self, plan, s, subset_to_v0)
53
0
            .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?;
54
55
0
        if subset_to_v0 {
56
0
            return Ok(());
57
0
        }
58
0
59
0
        // set version to 1, format pos = 0
60
0
        s.copy_assign(0, 1_u16);
61
62
        // var_store offset pos = 30
63
0
        if let Some(var_store) = self
64
0
            .item_variation_store()
65
0
            .transpose()
66
0
            .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?
67
        {
68
0
            Offset32::serialize_subset(&var_store, s, plan, &plan.colr_varstore_inner_maps, 30)
69
0
                .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?;
70
0
        }
71
72
        // BaseGlyphList offset pos = 14
73
0
        Offset32::serialize_subset(&base_glyph_list.unwrap(), s, plan, (), 14)
74
0
            .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?;
75
76
        //LayerList offset pos = 18
77
0
        if let Some(layer_list) = self
78
0
            .layer_list()
79
0
            .transpose()
80
0
            .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?
81
        {
82
0
            match Offset32::serialize_subset(&layer_list, s, plan, (), 18) {
83
0
                Ok(()) | Err(SerializeErrorFlags::SERIALIZE_ERROR_EMPTY) => (),
84
                Err(_) => {
85
0
                    return Err(SubsetError::SubsetTableError(Colr::TAG));
86
                }
87
            }
88
0
        }
89
90
        //ClipList offset pos = 22
91
0
        if let Some(clip_list) = self
92
0
            .clip_list()
93
0
            .transpose()
94
0
            .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?
95
        {
96
            // cliplist could be empty after subsetting
97
0
            match Offset32::serialize_subset(&clip_list, s, plan, (), 22) {
98
0
                Ok(()) | Err(SerializeErrorFlags::SERIALIZE_ERROR_EMPTY) => (),
99
                Err(_) => {
100
0
                    return Err(SubsetError::SubsetTableError(Colr::TAG));
101
                }
102
            }
103
0
        }
104
105
        //varIndexMap offset pos = 26
106
0
        if let Some(var_index_map) = self
107
0
            .var_index_map()
108
0
            .transpose()
109
0
            .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?
110
        {
111
0
            if let Some(deltaset_index_map_subset_plan) =
112
0
                create_deltaset_index_map_subset_plan(plan)
113
            {
114
0
                Offset32::serialize_subset(
115
0
                    &var_index_map,
116
0
                    s,
117
0
                    plan,
118
0
                    &deltaset_index_map_subset_plan,
119
0
                    26,
120
0
                )
121
0
                .map_err(|_| SubsetError::SubsetTableError(Colr::TAG))?;
122
0
            }
123
0
        }
124
0
        Ok(())
125
0
    }
126
}
127
128
// serialize header and V0 tables, format is decided by subset_to_v0 flag
129
//ref: <https://github.com/harfbuzz/harfbuzz/blob/bda5b832b0bc0090f7db0577ef501c5ca56f20c8/src/OT/Color/COLR/COLR.hh#L2353>
130
0
fn serialize_v0(
131
0
    colr: &Colr,
132
0
    plan: &Plan,
133
0
    s: &mut Serializer,
134
0
    subset_to_v0: bool,
135
0
) -> Result<(), SerializeErrorFlags> {
136
0
    let num_records = colr.num_base_glyph_records();
137
0
    if num_records == 0 && subset_to_v0 {
138
0
        return Err(SerializeErrorFlags::SERIALIZE_ERROR_EMPTY);
139
0
    }
140
141
0
    let base_glyph_records = colr
142
0
        .base_glyph_records()
143
0
        .transpose()
144
0
        .map_err(|_| SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR)?;
145
146
    // allocate V0 header: min byte size = 14
147
0
    s.allocate_size(14, false)?;
148
149
    // if needed, allocate additional V1 header size = 20
150
0
    if !subset_to_v0 {
151
0
        s.allocate_size(20, false)?;
152
0
    }
153
154
    // all v0 fields are 0, return
155
0
    if base_glyph_records.is_none() {
156
0
        return Ok(());
157
0
    }
158
0
159
0
    let base_glyph_records = base_glyph_records.unwrap();
160
0
    let num_bit_storage = 16 - num_records.leading_zeros() as usize;
161
0
162
0
    let glyph_set = &plan.glyphset_colred;
163
0
    let retained_record_idxes: Vec<usize> =
164
0
        if num_records as usize > glyph_set.len() as usize * num_bit_storage {
165
0
            glyph_set
166
0
                .iter()
167
0
                .filter_map(|g| {
168
0
                    base_glyph_records
169
0
                        .binary_search_by_key(&g.to_u32(), |record| record.glyph_id().to_u32())
170
0
                        .ok()
171
0
                })
172
0
                .collect()
173
        } else {
174
0
            base_glyph_records
175
0
                .iter()
176
0
                .enumerate()
177
0
                .filter_map(|(idx, record)| {
178
0
                    if !glyph_set.contains(GlyphId::from(record.glyph_id())) {
179
0
                        None
180
                    } else {
181
0
                        Some(idx)
182
                    }
183
0
                })
184
0
                .collect()
185
        };
186
187
0
    if retained_record_idxes.is_empty() {
188
0
        if subset_to_v0 {
189
0
            return Err(SerializeErrorFlags::SERIALIZE_ERROR_EMPTY);
190
0
        }
191
0
        return Ok(());
192
0
    }
193
0
194
0
    // serialize base glyph records, offset_pos = 4
195
0
    let mut num_layers = 0;
196
0
    Offset32::serialize_subset(
197
0
        &base_glyph_records,
198
0
        s,
199
0
        plan,
200
0
        (&retained_record_idxes, &mut num_layers),
201
0
        4,
202
0
    )?;
203
204
    //update num base glyph records
205
0
    s.copy_assign(2, retained_record_idxes.len() as u16);
206
0
    //update num layer records
207
0
    s.copy_assign(12, num_layers);
208
209
    //serialize layer records, offset_pos = 8
210
0
    let layer_records = colr
211
0
        .layer_records()
212
0
        .transpose()
213
0
        .map_err(|_| SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR)?
214
0
        .unwrap();
215
0
216
0
    Offset32::serialize_subset(
217
0
        &layer_records,
218
0
        s,
219
0
        plan,
220
0
        (base_glyph_records, &retained_record_idxes),
221
0
        8,
222
0
    )?;
223
224
0
    Ok(())
225
0
}
226
227
impl<'a> SubsetTable<'a> for &[BaseGlyph] {
228
    type ArgsForSubset = (&'a [usize], &'a mut u16);
229
    type Output = ();
230
0
    fn subset(
231
0
        &self,
232
0
        plan: &Plan,
233
0
        s: &mut Serializer,
234
0
        args: Self::ArgsForSubset,
235
0
    ) -> Result<(), SerializeErrorFlags> {
236
0
        let (retained_record_idxes, num_layers) = args;
237
0
        let glyph_map = &plan.glyph_map;
238
0
        for idx in retained_record_idxes {
239
0
            let record = self.get(*idx).unwrap();
240
0
            let old_gid = GlyphId::from(record.glyph_id());
241
0
            let Some(new_gid) = glyph_map.get(&old_gid) else {
242
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
243
            };
244
0
            s.embed(new_gid.to_u32() as u16)?;
245
0
            s.embed(*num_layers)?;
246
247
0
            let record_num_layers = record.num_layers();
248
0
            s.embed(record_num_layers)?;
249
250
0
            *num_layers += record_num_layers;
251
        }
252
0
        Ok(())
253
0
    }
254
}
255
256
impl<'a> SubsetTable<'a> for &[Layer] {
257
    type ArgsForSubset = (&'a [BaseGlyph], &'a [usize]);
258
    type Output = ();
259
0
    fn subset(
260
0
        &self,
261
0
        plan: &Plan,
262
0
        s: &mut Serializer,
263
0
        args: Self::ArgsForSubset,
264
0
    ) -> Result<(), SerializeErrorFlags> {
265
0
        let (base_glyph_records, retained_record_idxes) = args;
266
0
        let glyph_map = &plan.glyph_map;
267
0
        let palettes_map = &plan.colr_palettes;
268
0
        for idx in retained_record_idxes {
269
0
            let record = base_glyph_records.get(*idx).unwrap();
270
0
            let layer_idx = record.first_layer_index() as usize;
271
0
            let record_num_layers = record.num_layers() as usize;
272
273
0
            for i in layer_idx..layer_idx + record_num_layers {
274
0
                let Some(layer_record) = self.get(i) else {
275
0
                    return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
276
                };
277
278
0
                let old_gid = GlyphId::from(layer_record.glyph_id());
279
0
                let Some(new_gid) = glyph_map.get(&old_gid) else {
280
0
                    return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
281
                };
282
0
                let palette_idx = layer_record.palette_index();
283
0
                let Some(new_palette_idx) = palettes_map.get(&palette_idx) else {
284
0
                    return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
285
                };
286
287
0
                s.embed(new_gid.to_u32() as u16)?;
288
0
                s.embed(*new_palette_idx)?;
289
            }
290
        }
291
0
        Ok(())
292
0
    }
293
}
294
295
impl SubsetTable<'_> for BaseGlyphList<'_> {
296
    type ArgsForSubset = ();
297
    type Output = ();
298
299
0
    fn subset(
300
0
        &self,
301
0
        plan: &Plan,
302
0
        s: &mut Serializer,
303
0
        _args: Self::ArgsForSubset,
304
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
305
        // num BaseGlyphPaint initialized to 0
306
0
        let num_pos = s.embed(0_u32)?;
307
308
0
        let mut num = 0_u32;
309
0
        for paint_record in self.base_glyph_paint_records() {
310
0
            if !plan
311
0
                .glyphset_colred
312
0
                .contains(GlyphId::from(paint_record.glyph_id()))
313
            {
314
0
                continue;
315
0
            }
316
0
            paint_record.subset(plan, s, self)?;
317
0
            num += 1;
318
        }
319
320
0
        s.copy_assign(num_pos, num);
321
0
        Ok(())
322
0
    }
323
}
324
325
impl<'a> SubsetTable<'a> for BaseGlyphPaint {
326
    type ArgsForSubset = &'a BaseGlyphList<'a>;
327
    type Output = ();
328
329
0
    fn subset(
330
0
        &self,
331
0
        plan: &Plan,
332
0
        s: &mut Serializer,
333
0
        base_glyph_list: &BaseGlyphList,
334
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
335
0
        let old_gid = GlyphId::from(self.glyph_id());
336
0
        let Some(new_gid) = plan.glyph_map.get(&old_gid) else {
337
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
338
        };
339
340
0
        s.embed(new_gid.to_u32() as u16)?;
341
342
0
        let offset_pos = s.embed(0_u32)?;
343
0
        let Ok(paint) = self.paint(base_glyph_list.offset_data()) else {
344
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
345
        };
346
0
        Offset32::serialize_subset(&paint, s, plan, (), offset_pos)
347
0
    }
348
}
349
350
impl SubsetTable<'_> for LayerList<'_> {
351
    type ArgsForSubset = ();
352
    type Output = ();
353
354
0
    fn subset(
355
0
        &self,
356
0
        plan: &Plan,
357
0
        s: &mut Serializer,
358
0
        _args: Self::ArgsForSubset,
359
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
360
0
        let layers_map = &plan.colrv1_layers;
361
0
        if layers_map.is_empty() {
362
0
            return Err(SerializeErrorFlags::SERIALIZE_ERROR_EMPTY);
363
0
        }
364
0
        s.embed(layers_map.len() as u32)?;
365
366
0
        let paint_offsets = self.paints();
367
0
        let num_layers = self.num_layers();
368
0
        for idx in 0..num_layers {
369
0
            if !layers_map.contains_key(&idx) {
370
0
                continue;
371
0
            }
372
0
            paint_offsets.subset_offset(idx as usize, s, plan, ())?;
373
        }
374
0
        Ok(())
375
0
    }
376
}
377
378
impl SubsetTable<'_> for ClipList<'_> {
379
    type ArgsForSubset = ();
380
    type Output = ();
381
382
0
    fn subset(
383
0
        &self,
384
0
        plan: &Plan,
385
0
        s: &mut Serializer,
386
0
        _args: Self::ArgsForSubset,
387
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
388
0
        let glyph_set = &plan.glyphset_colred;
389
0
        let glyph_map = &plan.glyph_map;
390
0
        let retained_first_gid = glyph_set.first().unwrap().to_u32();
391
0
        let retained_last_gid = glyph_set.last().unwrap().to_u32();
392
0
393
0
        let mut new_gids_set = IntSet::empty();
394
0
        let mut new_gids_offset_map = FnvHashMap::default();
395
0
        for clip in self.clips() {
396
0
            let start_gid = clip.start_glyph_id().to_u32();
397
0
            let end_gid = clip.end_glyph_id().to_u32();
398
0
            if end_gid < retained_first_gid || start_gid > retained_last_gid {
399
0
                continue;
400
0
            }
401
0
            let offset = clip.clip_box_offset();
402
0
            for gid in start_gid..=end_gid {
403
0
                let g = GlyphId::from(gid);
404
0
                if !glyph_set.contains(g) {
405
0
                    continue;
406
0
                }
407
408
0
                let Some(new_gid) = glyph_map.get(&g) else {
409
0
                    continue;
410
                };
411
412
0
                let new_gid = new_gid.to_u32() as u16;
413
0
                new_gids_set.insert(new_gid);
414
0
                new_gids_offset_map.insert(new_gid, offset);
415
            }
416
        }
417
418
0
        if new_gids_set.is_empty() {
419
0
            return Err(SerializeErrorFlags::SERIALIZE_ERROR_EMPTY);
420
0
        }
421
0
422
0
        s.embed(self.format())?;
423
0
        let num_clips_pos = s.embed(0_u32)?;
424
0
        let num_clips = serialize_clips(self, s, plan, &new_gids_set, &new_gids_offset_map)?;
425
0
        s.copy_assign(num_clips_pos, num_clips);
426
0
        Ok(())
427
0
    }
428
}
429
430
0
fn serialize_clips(
431
0
    clip_list: &ClipList,
432
0
    s: &mut Serializer,
433
0
    plan: &Plan,
434
0
    gids_set: &IntSet<u16>,
435
0
    gids_offset_map: &FnvHashMap<u16, Offset24>,
436
0
) -> Result<u32, SerializeErrorFlags> {
437
0
    let mut count = 0;
438
0
439
0
    let mut start_gid = gids_set.first().unwrap();
440
0
    let mut prev_gid = start_gid;
441
0
442
0
    let mut prev_offset = gids_offset_map.get(&start_gid).unwrap();
443
444
0
    for g in gids_set.iter().skip(1) {
445
0
        let offset = gids_offset_map.get(&g).unwrap();
446
0
        if g == prev_gid + 1 && offset == prev_offset {
447
0
            prev_gid = g;
448
0
            continue;
449
0
        }
450
451
0
        let clip_box: ClipBox = prev_offset
452
0
            .resolve(clip_list.offset_data())
453
0
            .map_err(|_| SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR)?;
454
455
0
        serialize_clip(s, plan, start_gid, prev_gid, &clip_box)?;
456
0
        count += 1;
457
0
458
0
        start_gid = g;
459
0
        prev_gid = g;
460
0
        prev_offset = offset;
461
    }
462
463
    // last one
464
0
    let clip_box: ClipBox = prev_offset
465
0
        .resolve(clip_list.offset_data())
466
0
        .map_err(|_| SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR)?;
467
468
0
    serialize_clip(s, plan, start_gid, prev_gid, &clip_box)?;
469
0
    count += 1;
470
0
471
0
    Ok(count)
472
0
}
473
474
0
fn serialize_clip(
475
0
    s: &mut Serializer,
476
0
    plan: &Plan,
477
0
    start: u16,
478
0
    end: u16,
479
0
    clip_box: &ClipBox,
480
0
) -> Result<(), SerializeErrorFlags> {
481
0
    s.embed(start)?;
482
0
    s.embed(end)?;
483
0
    let offset_pos = s.embed_bytes(&[0_u8; 3])?;
484
0
    Offset24::serialize_subset(clip_box, s, plan, (), offset_pos)
485
0
}
486
487
impl SubsetTable<'_> for ClipBox<'_> {
488
    type ArgsForSubset = ();
489
    type Output = ();
490
491
0
    fn subset(
492
0
        &self,
493
0
        plan: &Plan,
494
0
        s: &mut Serializer,
495
0
        args: Self::ArgsForSubset,
496
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
497
0
        match self {
498
0
            Self::Format1(item) => item.subset(plan, s, args),
499
0
            Self::Format2(item) => item.subset(plan, s, args),
500
        }
501
0
    }
502
}
503
504
impl SubsetTable<'_> for ClipBoxFormat1<'_> {
505
    type ArgsForSubset = ();
506
    type Output = ();
507
508
0
    fn subset(
509
0
        &self,
510
0
        _plan: &Plan,
511
0
        s: &mut Serializer,
512
0
        _args: Self::ArgsForSubset,
513
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
514
0
        s.embed_bytes(self.min_table_bytes()).map(|_| ())
515
0
    }
516
}
517
518
impl SubsetTable<'_> for ClipBoxFormat2<'_> {
519
    type ArgsForSubset = ();
520
    type Output = ();
521
522
0
    fn subset(
523
0
        &self,
524
0
        plan: &Plan,
525
0
        s: &mut Serializer,
526
0
        _args: Self::ArgsForSubset,
527
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
528
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
529
530
0
        let varidx_base = self.var_index_base();
531
0
        if varidx_base != NO_VARIATION_INDEX {
532
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
533
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
534
            };
535
            // update VarIdxBase
536
0
            s.copy_assign(
537
0
                start_pos + self.shape().var_index_base_byte_range().start,
538
0
                *new_varidx,
539
0
            );
540
0
        }
541
0
        Ok(())
542
0
    }
543
}
544
545
0
fn create_deltaset_index_map_subset_plan(plan: &Plan) -> Option<DeltaSetIndexMapSerializePlan> {
546
0
    let deltaset_idx_varidx_map = &plan.colr_new_deltaset_idx_varidx_map;
547
0
    let count = deltaset_idx_varidx_map.len();
548
0
    if count == 0 {
549
0
        return None;
550
0
    }
551
0
552
0
    let mut last_idx = count as u32 - 1;
553
0
    let last_varidx = deltaset_idx_varidx_map.get(&last_idx).unwrap();
554
555
0
    for i in (0..last_idx).rev() {
556
0
        let var_idx = deltaset_idx_varidx_map.get(&i).unwrap();
557
0
        if var_idx != last_varidx {
558
0
            break;
559
0
        }
560
0
        last_idx = i;
561
    }
562
0
    let map_count = last_idx + 1;
563
0
    let mut outer_bit_count = 1;
564
0
    let mut inner_bit_count = 1;
565
566
0
    for idx in 0..map_count {
567
0
        let var_idx = deltaset_idx_varidx_map.get(&idx).unwrap();
568
0
569
0
        let outer = var_idx >> 16;
570
0
        let bit_count = 32 - outer.leading_zeros();
571
0
        outer_bit_count = outer_bit_count.max(bit_count);
572
0
573
0
        let inner = var_idx & 0xFFFF;
574
0
        let bit_count = 32 - inner.leading_zeros();
575
0
        inner_bit_count = inner_bit_count.max(bit_count);
576
0
    }
577
0
    Some(DeltaSetIndexMapSerializePlan::new(
578
0
        outer_bit_count as u8,
579
0
        inner_bit_count as u8,
580
0
        &plan.colr_new_deltaset_idx_varidx_map,
581
0
        map_count,
582
0
    ))
583
0
}
584
585
impl SubsetTable<'_> for ColorStop {
586
    type ArgsForSubset = ();
587
    type Output = ();
588
589
0
    fn subset(
590
0
        &self,
591
0
        plan: &Plan,
592
0
        s: &mut Serializer,
593
0
        _args: Self::ArgsForSubset,
594
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
595
0
        s.embed(self.stop_offset())?;
596
0
        let palette_idx = self.palette_index();
597
0
        let Some(new_idx) = plan.colr_palettes.get(&palette_idx) else {
598
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
599
        };
600
0
        s.embed(*new_idx)?;
601
0
        s.embed(self.alpha()).map(|_| ())
602
0
    }
603
}
604
605
impl SubsetTable<'_> for VarColorStop {
606
    type ArgsForSubset = ();
607
    type Output = ();
608
609
0
    fn subset(
610
0
        &self,
611
0
        plan: &Plan,
612
0
        s: &mut Serializer,
613
0
        _args: Self::ArgsForSubset,
614
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
615
0
        s.embed(self.stop_offset())?;
616
0
        let palette_idx = self.palette_index();
617
0
        let Some(new_idx) = plan.colr_palettes.get(&palette_idx) else {
618
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
619
        };
620
0
        s.embed(*new_idx)?;
621
0
        s.embed(self.alpha())?;
622
623
0
        let varidx_base = self.var_index_base();
624
0
        if varidx_base != NO_VARIATION_INDEX {
625
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
626
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
627
            };
628
            // update VarIdxBase
629
0
            s.embed(*new_varidx)?;
630
0
        }
631
0
        s.embed(varidx_base).map(|_| ())
632
0
    }
633
}
634
635
impl SubsetTable<'_> for ColorLine<'_> {
636
    type ArgsForSubset = ();
637
    type Output = ();
638
639
0
    fn subset(
640
0
        &self,
641
0
        plan: &Plan,
642
0
        s: &mut Serializer,
643
0
        _args: Self::ArgsForSubset,
644
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
645
0
        s.embed(self.extend())?;
646
0
        s.embed(self.num_stops())?;
647
648
0
        for stop in self.color_stops() {
649
0
            stop.subset(plan, s, ())?;
650
        }
651
0
        Ok(())
652
0
    }
653
}
654
655
impl SubsetTable<'_> for VarColorLine<'_> {
656
    type ArgsForSubset = ();
657
    type Output = ();
658
659
0
    fn subset(
660
0
        &self,
661
0
        plan: &Plan,
662
0
        s: &mut Serializer,
663
0
        _args: Self::ArgsForSubset,
664
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
665
0
        s.embed(self.extend())?;
666
0
        s.embed(self.num_stops())?;
667
668
0
        for stop in self.color_stops() {
669
0
            stop.subset(plan, s, ())?;
670
        }
671
0
        Ok(())
672
0
    }
673
}
674
675
impl SubsetTable<'_> for Paint<'_> {
676
    type ArgsForSubset = ();
677
    type Output = ();
678
679
0
    fn subset(
680
0
        &self,
681
0
        plan: &Plan,
682
0
        s: &mut Serializer,
683
0
        args: Self::ArgsForSubset,
684
0
    ) -> Result<Self::Output, SerializeErrorFlags> {
685
0
        match self {
686
0
            Self::ColrLayers(item) => item.subset(plan, s, args),
687
0
            Self::Solid(item) => item.subset(plan, s, args),
688
0
            Self::VarSolid(item) => item.subset(plan, s, args),
689
0
            Self::LinearGradient(item) => item.subset(plan, s, args),
690
0
            Self::VarLinearGradient(item) => item.subset(plan, s, args),
691
0
            Self::RadialGradient(item) => item.subset(plan, s, args),
692
0
            Self::VarRadialGradient(item) => item.subset(plan, s, args),
693
0
            Self::SweepGradient(item) => item.subset(plan, s, args),
694
0
            Self::VarSweepGradient(item) => item.subset(plan, s, args),
695
0
            Self::Glyph(item) => item.subset(plan, s, args),
696
0
            Self::ColrGlyph(item) => item.subset(plan, s, args),
697
0
            Self::Transform(item) => item.subset(plan, s, args),
698
0
            Self::VarTransform(item) => item.subset(plan, s, args),
699
0
            Self::Translate(item) => item.subset(plan, s, args),
700
0
            Self::VarTranslate(item) => item.subset(plan, s, args),
701
0
            Self::Scale(item) => item.subset(plan, s, args),
702
0
            Self::VarScale(item) => item.subset(plan, s, args),
703
0
            Self::ScaleAroundCenter(item) => item.subset(plan, s, args),
704
0
            Self::VarScaleAroundCenter(item) => item.subset(plan, s, args),
705
0
            Self::ScaleUniform(item) => item.subset(plan, s, args),
706
0
            Self::VarScaleUniform(item) => item.subset(plan, s, args),
707
0
            Self::ScaleUniformAroundCenter(item) => item.subset(plan, s, args),
708
0
            Self::VarScaleUniformAroundCenter(item) => item.subset(plan, s, args),
709
0
            Self::Rotate(item) => item.subset(plan, s, args),
710
0
            Self::VarRotate(item) => item.subset(plan, s, args),
711
0
            Self::RotateAroundCenter(item) => item.subset(plan, s, args),
712
0
            Self::VarRotateAroundCenter(item) => item.subset(plan, s, args),
713
0
            Self::Skew(item) => item.subset(plan, s, args),
714
0
            Self::VarSkew(item) => item.subset(plan, s, args),
715
0
            Self::SkewAroundCenter(item) => item.subset(plan, s, args),
716
0
            Self::VarSkewAroundCenter(item) => item.subset(plan, s, args),
717
0
            Self::Composite(item) => item.subset(plan, s, args),
718
        }
719
0
    }
720
}
721
722
impl SubsetTable<'_> for PaintColrLayers<'_> {
723
    type ArgsForSubset = ();
724
    type Output = ();
725
726
0
    fn subset(
727
0
        &self,
728
0
        plan: &Plan,
729
0
        s: &mut Serializer,
730
0
        _args: Self::ArgsForSubset,
731
0
    ) -> Result<(), SerializeErrorFlags> {
732
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
733
734
0
        let old_layer_idx = self.first_layer_index();
735
0
        let Some(new_layer_idx) = plan.colrv1_layers.get(&old_layer_idx) else {
736
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
737
        };
738
0
        s.copy_assign(start_pos + 2, *new_layer_idx);
739
0
        Ok(())
740
0
    }
741
}
742
743
impl SubsetTable<'_> for PaintSolid<'_> {
744
    type ArgsForSubset = ();
745
    type Output = ();
746
747
0
    fn subset(
748
0
        &self,
749
0
        plan: &Plan,
750
0
        s: &mut Serializer,
751
0
        _args: Self::ArgsForSubset,
752
0
    ) -> Result<(), SerializeErrorFlags> {
753
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
754
0
        let palette_idx = self.palette_index();
755
0
        let Some(new_idx) = plan.colr_palettes.get(&palette_idx) else {
756
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
757
        };
758
0
        s.copy_assign(start_pos + 1, *new_idx);
759
0
        Ok(())
760
0
    }
761
}
762
763
impl SubsetTable<'_> for PaintVarSolid<'_> {
764
    type ArgsForSubset = ();
765
    type Output = ();
766
767
0
    fn subset(
768
0
        &self,
769
0
        plan: &Plan,
770
0
        s: &mut Serializer,
771
0
        _args: Self::ArgsForSubset,
772
0
    ) -> Result<(), SerializeErrorFlags> {
773
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
774
0
        let palette_idx = self.palette_index();
775
0
        let Some(new_idx) = plan.colr_palettes.get(&palette_idx) else {
776
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
777
        };
778
0
        s.copy_assign(start_pos + 1, *new_idx);
779
0
780
0
        let varidx_base = self.var_index_base();
781
0
        if varidx_base != NO_VARIATION_INDEX {
782
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
783
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
784
            };
785
            // update VarIdxBase
786
0
            s.copy_assign(start_pos + 5, *new_varidx);
787
0
        }
788
0
        Ok(())
789
0
    }
790
}
791
792
impl SubsetTable<'_> for PaintLinearGradient<'_> {
793
    type ArgsForSubset = ();
794
    type Output = ();
795
796
0
    fn subset(
797
0
        &self,
798
0
        plan: &Plan,
799
0
        s: &mut Serializer,
800
0
        _args: Self::ArgsForSubset,
801
0
    ) -> Result<(), SerializeErrorFlags> {
802
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
803
804
0
        let Ok(color_line) = self.color_line() else {
805
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
806
        };
807
        //colorline offset pos = 1
808
0
        Offset24::serialize_subset(&color_line, s, plan, (), start_pos + 1)
809
0
    }
810
}
811
812
impl SubsetTable<'_> for PaintVarLinearGradient<'_> {
813
    type ArgsForSubset = ();
814
    type Output = ();
815
816
0
    fn subset(
817
0
        &self,
818
0
        plan: &Plan,
819
0
        s: &mut Serializer,
820
0
        _args: Self::ArgsForSubset,
821
0
    ) -> Result<(), SerializeErrorFlags> {
822
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
823
824
0
        let Ok(color_line) = self.color_line() else {
825
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
826
        };
827
        //colorline offset pos = 1
828
0
        Offset24::serialize_subset(&color_line, s, plan, (), start_pos + 1)?;
829
830
0
        let varidx_base = self.var_index_base();
831
0
        if varidx_base != NO_VARIATION_INDEX {
832
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
833
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
834
            };
835
            // update VarIdxBase
836
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
837
0
            s.copy_assign(pos, *new_varidx);
838
0
        }
839
0
        Ok(())
840
0
    }
841
}
842
843
impl SubsetTable<'_> for PaintRadialGradient<'_> {
844
    type ArgsForSubset = ();
845
    type Output = ();
846
847
0
    fn subset(
848
0
        &self,
849
0
        plan: &Plan,
850
0
        s: &mut Serializer,
851
0
        _args: Self::ArgsForSubset,
852
0
    ) -> Result<(), SerializeErrorFlags> {
853
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
854
855
0
        let Ok(color_line) = self.color_line() else {
856
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
857
        };
858
        //colorline offset pos = 1
859
0
        Offset24::serialize_subset(&color_line, s, plan, (), start_pos + 1)
860
0
    }
861
}
862
863
impl SubsetTable<'_> for PaintVarRadialGradient<'_> {
864
    type ArgsForSubset = ();
865
    type Output = ();
866
867
0
    fn subset(
868
0
        &self,
869
0
        plan: &Plan,
870
0
        s: &mut Serializer,
871
0
        _args: Self::ArgsForSubset,
872
0
    ) -> Result<(), SerializeErrorFlags> {
873
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
874
875
0
        let Ok(color_line) = self.color_line() else {
876
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
877
        };
878
        //colorline offset pos = 1
879
0
        Offset24::serialize_subset(&color_line, s, plan, (), start_pos + 1)?;
880
881
0
        let varidx_base = self.var_index_base();
882
0
        if varidx_base != NO_VARIATION_INDEX {
883
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
884
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
885
            };
886
            // update VarIdxBase
887
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
888
0
            s.copy_assign(pos, *new_varidx);
889
0
        }
890
0
        Ok(())
891
0
    }
892
}
893
894
impl SubsetTable<'_> for PaintSweepGradient<'_> {
895
    type ArgsForSubset = ();
896
    type Output = ();
897
898
0
    fn subset(
899
0
        &self,
900
0
        plan: &Plan,
901
0
        s: &mut Serializer,
902
0
        _args: Self::ArgsForSubset,
903
0
    ) -> Result<(), SerializeErrorFlags> {
904
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
905
906
0
        let Ok(color_line) = self.color_line() else {
907
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
908
        };
909
        //colorline offset pos = 1
910
0
        Offset24::serialize_subset(&color_line, s, plan, (), start_pos + 1)
911
0
    }
912
}
913
914
impl SubsetTable<'_> for PaintVarSweepGradient<'_> {
915
    type ArgsForSubset = ();
916
    type Output = ();
917
918
0
    fn subset(
919
0
        &self,
920
0
        plan: &Plan,
921
0
        s: &mut Serializer,
922
0
        _args: Self::ArgsForSubset,
923
0
    ) -> Result<(), SerializeErrorFlags> {
924
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
925
926
0
        let Ok(color_line) = self.color_line() else {
927
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
928
        };
929
        //colorline offset pos = 1
930
0
        Offset24::serialize_subset(&color_line, s, plan, (), start_pos + 1)?;
931
932
0
        let varidx_base = self.var_index_base();
933
0
        if varidx_base != NO_VARIATION_INDEX {
934
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
935
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
936
            };
937
            // update VarIdxBase
938
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
939
0
            s.copy_assign(pos, *new_varidx);
940
0
        }
941
0
        Ok(())
942
0
    }
943
}
944
945
impl SubsetTable<'_> for PaintGlyph<'_> {
946
    type ArgsForSubset = ();
947
    type Output = ();
948
949
0
    fn subset(
950
0
        &self,
951
0
        plan: &Plan,
952
0
        s: &mut Serializer,
953
0
        _args: Self::ArgsForSubset,
954
0
    ) -> Result<(), SerializeErrorFlags> {
955
0
        s.embed(self.format())?;
956
0
        let offset_pos = s.embed_bytes(&[0_u8; 3])?;
957
958
0
        let old_gid = GlyphId::from(self.glyph_id());
959
0
        let Some(new_gid) = plan.glyph_map.get(&old_gid) else {
960
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
961
        };
962
0
        s.embed(new_gid.to_u32() as u16)?;
963
964
0
        let Ok(paint) = self.paint() else {
965
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
966
        };
967
0
        Offset24::serialize_subset(&paint, s, plan, (), offset_pos)
968
0
    }
969
}
970
971
impl SubsetTable<'_> for PaintColrGlyph<'_> {
972
    type ArgsForSubset = ();
973
    type Output = ();
974
975
0
    fn subset(
976
0
        &self,
977
0
        plan: &Plan,
978
0
        s: &mut Serializer,
979
0
        _args: Self::ArgsForSubset,
980
0
    ) -> Result<(), SerializeErrorFlags> {
981
0
        s.embed(self.format())?;
982
983
0
        let old_gid = GlyphId::from(self.glyph_id());
984
0
        let Some(new_gid) = plan.glyph_map.get(&old_gid) else {
985
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
986
        };
987
0
        s.embed(new_gid.to_u32() as u16).map(|_| ())
988
0
    }
989
}
990
991
impl SubsetTable<'_> for Affine2x3<'_> {
992
    type ArgsForSubset = ();
993
    type Output = ();
994
995
0
    fn subset(
996
0
        &self,
997
0
        _plan: &Plan,
998
0
        s: &mut Serializer,
999
0
        _args: Self::ArgsForSubset,
1000
0
    ) -> Result<(), SerializeErrorFlags> {
1001
0
        s.embed_bytes(self.min_table_bytes()).map(|_| ())
1002
0
    }
1003
}
1004
1005
impl SubsetTable<'_> for VarAffine2x3<'_> {
1006
    type ArgsForSubset = ();
1007
    type Output = ();
1008
1009
0
    fn subset(
1010
0
        &self,
1011
0
        plan: &Plan,
1012
0
        s: &mut Serializer,
1013
0
        _args: Self::ArgsForSubset,
1014
0
    ) -> Result<(), SerializeErrorFlags> {
1015
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1016
0
        let varidx_base = self.var_index_base();
1017
0
        if varidx_base != NO_VARIATION_INDEX {
1018
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1019
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1020
            };
1021
            // update VarIdxBase
1022
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1023
0
            s.copy_assign(pos, *new_varidx);
1024
0
        }
1025
0
        Ok(())
1026
0
    }
1027
}
1028
1029
impl SubsetTable<'_> for PaintTransform<'_> {
1030
    type ArgsForSubset = ();
1031
    type Output = ();
1032
1033
0
    fn subset(
1034
0
        &self,
1035
0
        plan: &Plan,
1036
0
        s: &mut Serializer,
1037
0
        _args: Self::ArgsForSubset,
1038
0
    ) -> Result<(), SerializeErrorFlags> {
1039
0
        s.embed(self.format())?;
1040
1041
0
        let paint_pos = s.embed_bytes(&[0_u8; 3])?;
1042
0
        let transform_pos = s.embed_bytes(&[0_u8; 3])?;
1043
1044
0
        let Ok(paint) = self.paint() else {
1045
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1046
        };
1047
0
        Offset24::serialize_subset(&paint, s, plan, (), paint_pos)?;
1048
1049
0
        let Ok(affine) = self.transform() else {
1050
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1051
        };
1052
0
        Offset24::serialize_subset(&affine, s, plan, (), transform_pos)
1053
0
    }
1054
}
1055
1056
impl SubsetTable<'_> for PaintVarTransform<'_> {
1057
    type ArgsForSubset = ();
1058
    type Output = ();
1059
1060
0
    fn subset(
1061
0
        &self,
1062
0
        plan: &Plan,
1063
0
        s: &mut Serializer,
1064
0
        _args: Self::ArgsForSubset,
1065
0
    ) -> Result<(), SerializeErrorFlags> {
1066
0
        s.embed(self.format())?;
1067
1068
0
        let paint_pos = s.embed_bytes(&[0_u8; 3])?;
1069
0
        let transform_pos = s.embed_bytes(&[0_u8; 3])?;
1070
1071
0
        let Ok(paint) = self.paint() else {
1072
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1073
        };
1074
0
        Offset24::serialize_subset(&paint, s, plan, (), paint_pos)?;
1075
1076
0
        let Ok(affine) = self.transform() else {
1077
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1078
        };
1079
0
        Offset24::serialize_subset(&affine, s, plan, (), transform_pos)
1080
0
    }
1081
}
1082
1083
impl SubsetTable<'_> for PaintTranslate<'_> {
1084
    type ArgsForSubset = ();
1085
    type Output = ();
1086
1087
0
    fn subset(
1088
0
        &self,
1089
0
        plan: &Plan,
1090
0
        s: &mut Serializer,
1091
0
        _args: Self::ArgsForSubset,
1092
0
    ) -> Result<(), SerializeErrorFlags> {
1093
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1094
0
        let Ok(paint) = self.paint() else {
1095
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1096
        };
1097
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1098
0
    }
1099
}
1100
1101
impl SubsetTable<'_> for PaintVarTranslate<'_> {
1102
    type ArgsForSubset = ();
1103
    type Output = ();
1104
1105
0
    fn subset(
1106
0
        &self,
1107
0
        plan: &Plan,
1108
0
        s: &mut Serializer,
1109
0
        _args: Self::ArgsForSubset,
1110
0
    ) -> Result<(), SerializeErrorFlags> {
1111
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1112
0
        let Ok(paint) = self.paint() else {
1113
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1114
        };
1115
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1116
1117
0
        let varidx_base = self.var_index_base();
1118
0
        if varidx_base != NO_VARIATION_INDEX {
1119
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1120
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1121
            };
1122
            // update VarIdxBase
1123
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1124
0
            s.copy_assign(pos, *new_varidx);
1125
0
        }
1126
0
        Ok(())
1127
0
    }
1128
}
1129
1130
impl SubsetTable<'_> for PaintScale<'_> {
1131
    type ArgsForSubset = ();
1132
    type Output = ();
1133
1134
0
    fn subset(
1135
0
        &self,
1136
0
        plan: &Plan,
1137
0
        s: &mut Serializer,
1138
0
        _args: Self::ArgsForSubset,
1139
0
    ) -> Result<(), SerializeErrorFlags> {
1140
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1141
0
        let Ok(paint) = self.paint() else {
1142
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1143
        };
1144
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1145
0
    }
1146
}
1147
1148
impl SubsetTable<'_> for PaintVarScale<'_> {
1149
    type ArgsForSubset = ();
1150
    type Output = ();
1151
1152
0
    fn subset(
1153
0
        &self,
1154
0
        plan: &Plan,
1155
0
        s: &mut Serializer,
1156
0
        _args: Self::ArgsForSubset,
1157
0
    ) -> Result<(), SerializeErrorFlags> {
1158
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1159
0
        let Ok(paint) = self.paint() else {
1160
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1161
        };
1162
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1163
1164
0
        let varidx_base = self.var_index_base();
1165
0
        if varidx_base != NO_VARIATION_INDEX {
1166
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1167
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1168
            };
1169
            // update VarIdxBase
1170
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1171
0
            s.copy_assign(pos, *new_varidx);
1172
0
        }
1173
0
        Ok(())
1174
0
    }
1175
}
1176
1177
impl SubsetTable<'_> for PaintScaleAroundCenter<'_> {
1178
    type ArgsForSubset = ();
1179
    type Output = ();
1180
1181
0
    fn subset(
1182
0
        &self,
1183
0
        plan: &Plan,
1184
0
        s: &mut Serializer,
1185
0
        _args: Self::ArgsForSubset,
1186
0
    ) -> Result<(), SerializeErrorFlags> {
1187
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1188
0
        let Ok(paint) = self.paint() else {
1189
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1190
        };
1191
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1192
0
    }
1193
}
1194
1195
impl SubsetTable<'_> for PaintVarScaleAroundCenter<'_> {
1196
    type ArgsForSubset = ();
1197
    type Output = ();
1198
1199
0
    fn subset(
1200
0
        &self,
1201
0
        plan: &Plan,
1202
0
        s: &mut Serializer,
1203
0
        _args: Self::ArgsForSubset,
1204
0
    ) -> Result<(), SerializeErrorFlags> {
1205
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1206
0
        let Ok(paint) = self.paint() else {
1207
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1208
        };
1209
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1210
1211
0
        let varidx_base = self.var_index_base();
1212
0
        if varidx_base != NO_VARIATION_INDEX {
1213
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1214
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1215
            };
1216
            // update VarIdxBase
1217
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1218
0
            s.copy_assign(pos, *new_varidx);
1219
0
        }
1220
0
        Ok(())
1221
0
    }
1222
}
1223
1224
impl SubsetTable<'_> for PaintScaleUniform<'_> {
1225
    type ArgsForSubset = ();
1226
    type Output = ();
1227
1228
0
    fn subset(
1229
0
        &self,
1230
0
        plan: &Plan,
1231
0
        s: &mut Serializer,
1232
0
        _args: Self::ArgsForSubset,
1233
0
    ) -> Result<(), SerializeErrorFlags> {
1234
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1235
0
        let Ok(paint) = self.paint() else {
1236
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1237
        };
1238
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1239
0
    }
1240
}
1241
1242
impl SubsetTable<'_> for PaintVarScaleUniform<'_> {
1243
    type ArgsForSubset = ();
1244
    type Output = ();
1245
1246
0
    fn subset(
1247
0
        &self,
1248
0
        plan: &Plan,
1249
0
        s: &mut Serializer,
1250
0
        _args: Self::ArgsForSubset,
1251
0
    ) -> Result<(), SerializeErrorFlags> {
1252
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1253
0
        let Ok(paint) = self.paint() else {
1254
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1255
        };
1256
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1257
1258
0
        let varidx_base = self.var_index_base();
1259
0
        if varidx_base != NO_VARIATION_INDEX {
1260
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1261
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1262
            };
1263
            // update VarIdxBase
1264
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1265
0
            s.copy_assign(pos, *new_varidx);
1266
0
        }
1267
0
        Ok(())
1268
0
    }
1269
}
1270
1271
impl SubsetTable<'_> for PaintScaleUniformAroundCenter<'_> {
1272
    type ArgsForSubset = ();
1273
    type Output = ();
1274
1275
0
    fn subset(
1276
0
        &self,
1277
0
        plan: &Plan,
1278
0
        s: &mut Serializer,
1279
0
        _args: Self::ArgsForSubset,
1280
0
    ) -> Result<(), SerializeErrorFlags> {
1281
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1282
0
        let Ok(paint) = self.paint() else {
1283
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1284
        };
1285
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1286
0
    }
1287
}
1288
1289
impl SubsetTable<'_> for PaintVarScaleUniformAroundCenter<'_> {
1290
    type ArgsForSubset = ();
1291
    type Output = ();
1292
1293
0
    fn subset(
1294
0
        &self,
1295
0
        plan: &Plan,
1296
0
        s: &mut Serializer,
1297
0
        _args: Self::ArgsForSubset,
1298
0
    ) -> Result<(), SerializeErrorFlags> {
1299
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1300
0
        let Ok(paint) = self.paint() else {
1301
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1302
        };
1303
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1304
1305
0
        let varidx_base = self.var_index_base();
1306
0
        if varidx_base != NO_VARIATION_INDEX {
1307
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1308
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1309
            };
1310
            // update VarIdxBase
1311
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1312
0
            s.copy_assign(pos, *new_varidx);
1313
0
        }
1314
0
        Ok(())
1315
0
    }
1316
}
1317
1318
impl SubsetTable<'_> for PaintRotate<'_> {
1319
    type ArgsForSubset = ();
1320
    type Output = ();
1321
1322
0
    fn subset(
1323
0
        &self,
1324
0
        plan: &Plan,
1325
0
        s: &mut Serializer,
1326
0
        _args: Self::ArgsForSubset,
1327
0
    ) -> Result<(), SerializeErrorFlags> {
1328
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1329
0
        let Ok(paint) = self.paint() else {
1330
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1331
        };
1332
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1333
0
    }
1334
}
1335
1336
impl SubsetTable<'_> for PaintVarRotate<'_> {
1337
    type ArgsForSubset = ();
1338
    type Output = ();
1339
1340
0
    fn subset(
1341
0
        &self,
1342
0
        plan: &Plan,
1343
0
        s: &mut Serializer,
1344
0
        _args: Self::ArgsForSubset,
1345
0
    ) -> Result<(), SerializeErrorFlags> {
1346
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1347
0
        let Ok(paint) = self.paint() else {
1348
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1349
        };
1350
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1351
1352
0
        let varidx_base = self.var_index_base();
1353
0
        if varidx_base != NO_VARIATION_INDEX {
1354
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1355
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1356
            };
1357
            // update VarIdxBase
1358
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1359
0
            s.copy_assign(pos, *new_varidx);
1360
0
        }
1361
0
        Ok(())
1362
0
    }
1363
}
1364
1365
impl SubsetTable<'_> for PaintRotateAroundCenter<'_> {
1366
    type ArgsForSubset = ();
1367
    type Output = ();
1368
1369
0
    fn subset(
1370
0
        &self,
1371
0
        plan: &Plan,
1372
0
        s: &mut Serializer,
1373
0
        _args: Self::ArgsForSubset,
1374
0
    ) -> Result<(), SerializeErrorFlags> {
1375
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1376
0
        let Ok(paint) = self.paint() else {
1377
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1378
        };
1379
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1380
0
    }
1381
}
1382
1383
impl SubsetTable<'_> for PaintVarRotateAroundCenter<'_> {
1384
    type ArgsForSubset = ();
1385
    type Output = ();
1386
1387
0
    fn subset(
1388
0
        &self,
1389
0
        plan: &Plan,
1390
0
        s: &mut Serializer,
1391
0
        _args: Self::ArgsForSubset,
1392
0
    ) -> Result<(), SerializeErrorFlags> {
1393
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1394
0
        let Ok(paint) = self.paint() else {
1395
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1396
        };
1397
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1398
1399
0
        let varidx_base = self.var_index_base();
1400
0
        if varidx_base != NO_VARIATION_INDEX {
1401
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1402
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1403
            };
1404
            // update VarIdxBase
1405
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1406
0
            s.copy_assign(pos, *new_varidx);
1407
0
        }
1408
0
        Ok(())
1409
0
    }
1410
}
1411
1412
impl SubsetTable<'_> for PaintSkew<'_> {
1413
    type ArgsForSubset = ();
1414
    type Output = ();
1415
1416
0
    fn subset(
1417
0
        &self,
1418
0
        plan: &Plan,
1419
0
        s: &mut Serializer,
1420
0
        _args: Self::ArgsForSubset,
1421
0
    ) -> Result<(), SerializeErrorFlags> {
1422
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1423
0
        let Ok(paint) = self.paint() else {
1424
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1425
        };
1426
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1427
0
    }
1428
}
1429
1430
impl SubsetTable<'_> for PaintVarSkew<'_> {
1431
    type ArgsForSubset = ();
1432
    type Output = ();
1433
1434
0
    fn subset(
1435
0
        &self,
1436
0
        plan: &Plan,
1437
0
        s: &mut Serializer,
1438
0
        _args: Self::ArgsForSubset,
1439
0
    ) -> Result<(), SerializeErrorFlags> {
1440
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1441
0
        let Ok(paint) = self.paint() else {
1442
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1443
        };
1444
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1445
1446
0
        let varidx_base = self.var_index_base();
1447
0
        if varidx_base != NO_VARIATION_INDEX {
1448
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1449
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1450
            };
1451
            // update VarIdxBase
1452
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1453
0
            s.copy_assign(pos, *new_varidx);
1454
0
        }
1455
0
        Ok(())
1456
0
    }
1457
}
1458
1459
impl SubsetTable<'_> for PaintSkewAroundCenter<'_> {
1460
    type ArgsForSubset = ();
1461
    type Output = ();
1462
1463
0
    fn subset(
1464
0
        &self,
1465
0
        plan: &Plan,
1466
0
        s: &mut Serializer,
1467
0
        _args: Self::ArgsForSubset,
1468
0
    ) -> Result<(), SerializeErrorFlags> {
1469
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1470
0
        let Ok(paint) = self.paint() else {
1471
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1472
        };
1473
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)
1474
0
    }
1475
}
1476
1477
impl SubsetTable<'_> for PaintVarSkewAroundCenter<'_> {
1478
    type ArgsForSubset = ();
1479
    type Output = ();
1480
1481
0
    fn subset(
1482
0
        &self,
1483
0
        plan: &Plan,
1484
0
        s: &mut Serializer,
1485
0
        _args: Self::ArgsForSubset,
1486
0
    ) -> Result<(), SerializeErrorFlags> {
1487
0
        let start_pos = s.embed_bytes(self.min_table_bytes())?;
1488
0
        let Ok(paint) = self.paint() else {
1489
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1490
        };
1491
0
        Offset24::serialize_subset(&paint, s, plan, (), start_pos + 1)?;
1492
1493
0
        let varidx_base = self.var_index_base();
1494
0
        if varidx_base != NO_VARIATION_INDEX {
1495
0
            let Some((new_varidx, _)) = plan.colr_varidx_delta_map.get(&varidx_base) else {
1496
0
                return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER));
1497
            };
1498
            // update VarIdxBase
1499
0
            let pos = start_pos + self.shape().var_index_base_byte_range().start;
1500
0
            s.copy_assign(pos, *new_varidx);
1501
0
        }
1502
0
        Ok(())
1503
0
    }
1504
}
1505
1506
impl SubsetTable<'_> for PaintComposite<'_> {
1507
    type ArgsForSubset = ();
1508
    type Output = ();
1509
1510
0
    fn subset(
1511
0
        &self,
1512
0
        plan: &Plan,
1513
0
        s: &mut Serializer,
1514
0
        _args: Self::ArgsForSubset,
1515
0
    ) -> Result<(), SerializeErrorFlags> {
1516
0
        s.embed(self.format())?;
1517
0
        let src_paint_pos = s.embed_bytes(&[0_u8; 3])?;
1518
0
        s.embed(self.composite_mode())?;
1519
0
        let backdrop_paint_pos = s.embed_bytes(&[0_u8; 3])?;
1520
1521
0
        let Ok(src_paint) = self.source_paint() else {
1522
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1523
        };
1524
0
        Offset24::serialize_subset(&src_paint, s, plan, (), src_paint_pos)?;
1525
1526
0
        let Ok(backdrop_paint) = self.backdrop_paint() else {
1527
0
            return Err(s.set_err(SerializeErrorFlags::SERIALIZE_ERROR_READ_ERROR));
1528
        };
1529
0
        Offset24::serialize_subset(&backdrop_paint, s, plan, (), backdrop_paint_pos)
1530
0
    }
1531
}
1532
1533
// downgrade to v0 if we have no v1 glyphs to retain
1534
0
fn downgrade_to_v0(base_glyph_list: Option<&BaseGlyphList>, plan: &Plan) -> bool {
1535
0
    if base_glyph_list.is_none() {
1536
0
        return true;
1537
0
    }
1538
1539
0
    for paint_record in base_glyph_list.unwrap().base_glyph_paint_records() {
1540
0
        if plan
1541
0
            .glyphset_colred
1542
0
            .contains(GlyphId::from(paint_record.glyph_id()))
1543
        {
1544
0
            return false;
1545
0
        }
1546
    }
1547
0
    true
1548
0
}
1549
1550
#[cfg(test)]
1551
mod test {
1552
    use super::*;
1553
    use write_fonts::{read::TableProvider, types::GlyphId};
1554
    #[test]
1555
    fn test_subset_colr_retain_all() {
1556
        let ttf: &[u8] = include_bytes!("../test-data/fonts/TwemojiMozilla.subset.ttf");
1557
        let font = FontRef::new(ttf).unwrap();
1558
        let colr = font.colr().unwrap();
1559
1560
        let mut builder = FontBuilder::new();
1561
1562
        let mut plan = Plan::default();
1563
1564
        plan.glyphset_colred
1565
            .insert_range(GlyphId::NOTDEF..=GlyphId::from(6_u32));
1566
1567
        plan.glyph_map.insert(GlyphId::NOTDEF, GlyphId::NOTDEF);
1568
        plan.glyph_map
1569
            .insert(GlyphId::from(1_u32), GlyphId::from(1_u32));
1570
        plan.glyph_map
1571
            .insert(GlyphId::from(2_u32), GlyphId::from(2_u32));
1572
        plan.glyph_map
1573
            .insert(GlyphId::from(3_u32), GlyphId::from(3_u32));
1574
        plan.glyph_map
1575
            .insert(GlyphId::from(4_u32), GlyphId::from(4_u32));
1576
        plan.glyph_map
1577
            .insert(GlyphId::from(5_u32), GlyphId::from(5_u32));
1578
        plan.glyph_map
1579
            .insert(GlyphId::from(6_u32), GlyphId::from(6_u32));
1580
1581
        plan.colr_palettes.insert(2, 0);
1582
        plan.colr_palettes.insert(11, 1);
1583
1584
        let mut s = Serializer::new(1024);
1585
        assert_eq!(s.start_serialize(), Ok(()));
1586
        let ret = colr.subset(&plan, &font, &mut s, &mut builder);
1587
        assert!(ret.is_ok());
1588
        assert!(!s.in_error());
1589
        s.end_serialize();
1590
1591
        let subsetted_data = s.copy_bytes();
1592
        let expected_data: [u8; 42] = [
1593
            0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x04,
1594
            0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06,
1595
            0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02,
1596
        ];
1597
        assert_eq!(subsetted_data, expected_data);
1598
    }
1599
1600
    #[test]
1601
    fn test_subset_colr_keep_one_colr_glyph() {
1602
        let ttf: &[u8] = include_bytes!("../test-data/fonts/TwemojiMozilla.subset.ttf");
1603
        let font = FontRef::new(ttf).unwrap();
1604
        let colr = font.colr().unwrap();
1605
1606
        let mut builder = FontBuilder::new();
1607
1608
        let mut plan = Plan::default();
1609
1610
        plan.glyphset_colred.insert(GlyphId::NOTDEF);
1611
        plan.glyphset_colred.insert(GlyphId::from(2_u32));
1612
        plan.glyphset_colred.insert(GlyphId::from(4_u32));
1613
        plan.glyphset_colred.insert(GlyphId::from(5_u32));
1614
1615
        plan.glyph_map.insert(GlyphId::NOTDEF, GlyphId::NOTDEF);
1616
        plan.glyph_map
1617
            .insert(GlyphId::from(2_u32), GlyphId::from(1_u32));
1618
        plan.glyph_map
1619
            .insert(GlyphId::from(4_u32), GlyphId::from(2_u32));
1620
        plan.glyph_map
1621
            .insert(GlyphId::from(5_u32), GlyphId::from(3_u32));
1622
1623
        plan.colr_palettes.insert(2, 0);
1624
        plan.colr_palettes.insert(11, 1);
1625
1626
        let mut s = Serializer::new(1024);
1627
        assert_eq!(s.start_serialize(), Ok(()));
1628
        let ret = colr.subset(&plan, &font, &mut s, &mut builder);
1629
        assert!(ret.is_ok());
1630
        assert!(!s.in_error());
1631
        s.end_serialize();
1632
1633
        let subsetted_data = s.copy_bytes();
1634
        let expected_data: [u8; 28] = [
1635
            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x02,
1636
            0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
1637
        ];
1638
        assert_eq!(subsetted_data, expected_data);
1639
    }
1640
1641
    #[test]
1642
    fn test_subset_colr_keep_mixed_glyph() {
1643
        let ttf: &[u8] = include_bytes!("../test-data/fonts/TwemojiMozilla.subset.ttf");
1644
        let font = FontRef::new(ttf).unwrap();
1645
        let colr = font.colr().unwrap();
1646
1647
        let mut builder = FontBuilder::new();
1648
1649
        let mut plan = Plan::default();
1650
1651
        plan.glyphset_colred.insert(GlyphId::NOTDEF);
1652
        plan.glyphset_colred.insert(GlyphId::from(1_u32));
1653
        plan.glyphset_colred.insert(GlyphId::from(3_u32));
1654
        plan.glyphset_colred.insert(GlyphId::from(4_u32));
1655
        plan.glyphset_colred.insert(GlyphId::from(6_u32));
1656
1657
        plan.glyph_map.insert(GlyphId::NOTDEF, GlyphId::NOTDEF);
1658
        plan.glyph_map
1659
            .insert(GlyphId::from(1_u32), GlyphId::from(1_u32));
1660
        plan.glyph_map
1661
            .insert(GlyphId::from(3_u32), GlyphId::from(2_u32));
1662
        plan.glyph_map
1663
            .insert(GlyphId::from(4_u32), GlyphId::from(3_u32));
1664
        plan.glyph_map
1665
            .insert(GlyphId::from(6_u32), GlyphId::from(4_u32));
1666
1667
        plan.colr_palettes.insert(2, 0);
1668
        plan.colr_palettes.insert(11, 1);
1669
1670
        let mut s = Serializer::new(1024);
1671
        assert_eq!(s.start_serialize(), Ok(()));
1672
        let ret = colr.subset(&plan, &font, &mut s, &mut builder);
1673
        assert!(ret.is_ok());
1674
        assert!(!s.in_error());
1675
        s.end_serialize();
1676
1677
        let subsetted_data = s.copy_bytes();
1678
        let expected_data: [u8; 28] = [
1679
            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x02,
1680
            0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
1681
        ];
1682
        assert_eq!(subsetted_data, expected_data);
1683
    }
1684
1685
    #[test]
1686
    fn test_subset_colr_keep_no_colr_glyph() {
1687
        let ttf: &[u8] = include_bytes!("../test-data/fonts/TwemojiMozilla.subset.ttf");
1688
        let font = FontRef::new(ttf).unwrap();
1689
        let colr = font.colr().unwrap();
1690
1691
        let mut builder = FontBuilder::new();
1692
1693
        let mut plan = Plan::default();
1694
1695
        plan.glyphset_colred.insert(GlyphId::NOTDEF);
1696
        plan.glyphset_colred.insert(GlyphId::from(1_u32));
1697
1698
        plan.glyph_map.insert(GlyphId::NOTDEF, GlyphId::NOTDEF);
1699
        plan.glyph_map
1700
            .insert(GlyphId::from(1_u32), GlyphId::from(1_u32));
1701
1702
        let mut s = Serializer::new(1024);
1703
        assert_eq!(s.start_serialize(), Ok(()));
1704
        let ret = colr.subset(&plan, &font, &mut s, &mut builder);
1705
        assert!(ret.is_err());
1706
        assert!(!s.in_error());
1707
        s.end_serialize();
1708
    }
1709
}