swash/scale/
color.rs

1use super::super::{
2    palette::{ColorPalette, ColorPalettes},
3    FontRef, GlyphId,
4};
5use super::internal::{raw_tag, Bytes, RawFont, RawTag};
6
7const COLR: RawTag = raw_tag(b"COLR");
8const CPAL: RawTag = raw_tag(b"CPAL");
9
10#[derive(Copy, Clone, Default)]
11pub struct ColorProxy {
12    pub colr: u32,
13    pub cpal: u32,
14}
15
16impl ColorProxy {
17    pub fn from_font(font: &FontRef) -> Self {
18        Self {
19            colr: font.table_offset(COLR),
20            cpal: font.table_offset(CPAL),
21        }
22    }
23
24    pub fn layers<'a>(&self, data: &'a [u8], glyph_id: GlyphId) -> Option<Layers<'a>> {
25        let b = Bytes::with_offset(data, self.colr as usize)?;
26        let count = b.read::<u16>(2)? as usize;
27        let base_offset = b.read::<u32>(4)? as usize;
28        let mut l = 0;
29        let mut h = count;
30        while l < h {
31            use core::cmp::Ordering::*;
32            let i = l + (h - l) / 2;
33            let rec = base_offset + i * 6;
34            let id = b.read::<u16>(rec)?;
35            match glyph_id.cmp(&id) {
36                Less => h = i,
37                Greater => l = i + 1,
38                Equal => {
39                    let first = b.read::<u16>(rec + 2)? as usize;
40                    let offset = b.read::<u32>(8)? as usize + first * 4;
41                    let len = b.read::<u16>(rec + 4)?;
42                    return Some(Layers {
43                        data: b,
44                        offset,
45                        len,
46                    });
47                }
48            }
49        }
50        None
51    }
52
53    // Unused when render feature is disabled.
54    #[allow(dead_code)]
55    pub fn palette<'a>(&self, font: &FontRef<'a>, index: u16) -> Option<ColorPalette<'a>> {
56        if self.cpal != 0 {
57            ColorPalettes::from_font_and_offset(font, self.cpal).nth(index as usize)
58        } else {
59            None
60        }
61    }
62}
63
64#[derive(Copy, Clone)]
65pub struct Layers<'a> {
66    data: Bytes<'a>,
67    offset: usize,
68    len: u16,
69}
70
71impl<'a> Layers<'a> {
72    pub fn len(&self) -> u16 {
73        self.len
74    }
75
76    pub fn get(&self, index: u16) -> Option<Layer> {
77        let b = &self.data;
78        let base = self.offset + index as usize * 4;
79        let glyph_id = b.read::<u16>(base)?;
80        let color_index = b.read::<u16>(base + 2)?;
81        Some(Layer {
82            glyph_id,
83            color_index: if color_index != 0xFFFF {
84                Some(color_index)
85            } else {
86                None
87            },
88        })
89    }
90}
91
92#[derive(Copy, Clone)]
93pub struct Layer {
94    pub glyph_id: GlyphId,
95    pub color_index: Option<u16>,
96}