fontconfig_cache_parser/
data.rs

1//! Definitions of fontconfig's raw serialized format.
2//!
3//! Fontconfig's cache format is defined by writing out C structs byte-for-byte.
4//! This module gives a rust definition for some of those structs (more may be
5//! supported in the future). Since the fontconfig structs include offsets to other
6//! structs, you cannot do much with the raw data itself: you need to interpret
7//! that data in the context of its location in the cache. See the [`ptr`](crate::ptr)
8//! module for more details.
9//!
10//! In any case, you are unlikely to need access to the raw serialized format, as this
11//! crate defines more convenient wrappers around this raw format.
12
13use bytemuck::AnyBitPattern;
14use std::os::raw::{c_int, c_uint};
15
16use crate::{
17    ptr::{Offset, PtrOffset},
18    CharSetLeaf,
19};
20
21/// The fontconfig cache header, in the raw serialized format.
22#[derive(AnyBitPattern, Copy, Clone, Debug)]
23#[repr(C)]
24pub struct CacheData {
25    /// The magic 4 bytes marking the data as a fontconfig cache.
26    pub magic: c_uint,
27    /// The cache format version. We support versions 7 and 8.
28    pub version: c_int,
29    /// The size of the cache.
30    pub size: isize,
31    /// This cache caches the data of all fonts in some directory.
32    /// Here is (an offset to) the name of that directory.
33    pub dir: Offset<u8>,
34    /// Here is an offset to an array of offsets to the names of
35    /// subdirectories.
36    pub dirs: Offset<Offset<u8>>,
37    /// How many subdirectories are there?
38    pub dirs_count: c_int,
39    /// An offset to the set of fonts in this cache.
40    pub set: Offset<FontSetData>,
41    /// A "checksum" of this cache (but really just a timestamp).
42    pub checksum: c_int,
43    /// Another "checksum" of this cache (but really just a more precise timestamp).
44    pub checksum_nano: c_int,
45}
46
47/// A set of fonts, in the raw serialized format.
48#[derive(AnyBitPattern, Copy, Clone, Debug)]
49#[repr(C)]
50pub struct FontSetData {
51    /// The number of fonts in this set.
52    pub nfont: c_int,
53    // Capacity of the font array. Uninteresting for the serialized format.
54    _sfont: c_int,
55    /// Pointer to an array of fonts.
56    ///
57    /// All the offsets here (both outer and inner) are relative to this `FontSetData`.
58    pub fonts: PtrOffset<PtrOffset<PatternData>>,
59}
60
61/// The raw serialized format of a [`Pattern`](crate::Pattern).
62#[derive(AnyBitPattern, Copy, Clone, Debug)]
63#[repr(C)]
64pub struct PatternData {
65    /// The number of elements in this pattern.
66    pub num: c_int,
67    // The capacity of the elements array. For serialized data, it's probably
68    // the same as `num`.
69    _size: c_int,
70    /// The offset of the element array.
71    pub elts_offset: Offset<PatternEltData>,
72    ref_count: c_int,
73}
74
75/// A single element of a [`Pattern`](crate::Pattern), in the raw serialized format.
76#[derive(AnyBitPattern, Copy, Clone, Debug)]
77#[repr(C)]
78pub struct PatternEltData {
79    /// The object type tag.
80    pub object: c_int,
81    /// Offset of the linked list of values.
82    pub values: PtrOffset<ValueListData>,
83}
84
85/// A linked list of [`Value`](crate::Value)s, in the raw serialized format.
86#[derive(AnyBitPattern, Copy, Clone, Debug)]
87#[repr(C)]
88pub struct ValueListData {
89    /// An offset to the next element in the linked list.
90    pub next: PtrOffset<ValueListData>,
91    /// The value of the current list element.
92    pub value: ValueData,
93    binding: c_int,
94}
95
96/// Fontconfig's `FcValue` data type, in the raw serialized format.
97#[derive(AnyBitPattern, Copy, Clone)]
98#[repr(C)]
99pub struct ValueData {
100    /// The value's type tag.
101    pub ty: c_int,
102    /// The value's value.
103    pub val: ValueUnion,
104}
105
106impl std::fmt::Debug for ValueData {
107    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108        f.write_fmt(format_args!("{}", self.ty))
109        // TODO: write the rest
110    }
111}
112
113/// A dynamically typed value, as a raw union.
114///
115/// Many of fontconfig's values are stored as a tagged union. But because
116/// there's no layout guarantees for tagged unions in rust, we read them
117/// in the C layout, as a combination of `c_int` tag and an untagged union.
118///
119/// This is the untagged union part.
120#[repr(C)]
121#[derive(AnyBitPattern, Copy, Clone)]
122#[allow(missing_docs)]
123pub union ValueUnion {
124    pub s: PtrOffset<u8>,
125    pub i: c_int,
126    pub b: c_int,
127    pub d: f64,
128    pub m: PtrOffset<()>, // TODO
129    pub c: PtrOffset<CharSetData>,
130    pub f: PtrOffset<()>,
131    pub l: PtrOffset<()>, // TODO
132    pub r: PtrOffset<()>, // TODO
133}
134
135/// A set of code points, in the raw serialized format.
136///
137/// # Implementation details
138///
139/// This charset is implemented as a bunch of bitsets. Each bitset (a [`CharSetLeaf`](crate::CharSetLeaf))
140/// has 256 bits, and so it represents the least significant byte of the codepoint. Associated to each
141/// leaf is a 16-bit offset, representing the next two least-significant bytes of the codepoint.
142/// (In particular, this can represent any subset of the numbers `0` through `0x00FFFFFF`, which is
143/// big enough for the unicode range.)
144#[derive(AnyBitPattern, Copy, Clone, Debug)]
145#[repr(C)]
146pub struct CharSetData {
147    // Reference count. Not interesting for us.
148    ref_count: c_int,
149    /// Length of both of the following arrays
150    pub num: c_int,
151    /// Array of offsets to leaves. Each offset is relative to the start of the array, not the
152    /// start of this struct!
153    pub leaves: Offset<Offset<CharSetLeaf>>,
154    /// Array having the same length as `leaves`, and storing the 16-bit offsets of each leaf.
155    pub numbers: Offset<u16>,
156}