1#[allow(unused_imports)]
6use crate::codegen_prelude::*;
7
8#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, bytemuck :: AnyBitPattern)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[repr(transparent)]
12pub struct MacStyle {
13 bits: u16,
14}
15
16impl MacStyle {
17 pub const BOLD: Self = Self { bits: 0x0001 };
19
20 pub const ITALIC: Self = Self { bits: 0x0002 };
22
23 pub const UNDERLINE: Self = Self { bits: 0x0004 };
25
26 pub const OUTLINE: Self = Self { bits: 0x0008 };
28
29 pub const SHADOW: Self = Self { bits: 0x0010 };
31
32 pub const CONDENSED: Self = Self { bits: 0x0020 };
34
35 pub const EXTENDED: Self = Self { bits: 0x0040 };
37}
38
39impl MacStyle {
40 #[inline]
42 pub const fn empty() -> Self {
43 Self { bits: 0 }
44 }
45
46 #[inline]
48 pub const fn all() -> Self {
49 Self {
50 bits: Self::BOLD.bits
51 | Self::ITALIC.bits
52 | Self::UNDERLINE.bits
53 | Self::OUTLINE.bits
54 | Self::SHADOW.bits
55 | Self::CONDENSED.bits
56 | Self::EXTENDED.bits,
57 }
58 }
59
60 #[inline]
62 pub const fn bits(&self) -> u16 {
63 self.bits
64 }
65
66 #[inline]
69 pub const fn from_bits(bits: u16) -> Option<Self> {
70 if (bits & !Self::all().bits()) == 0 {
71 Some(Self { bits })
72 } else {
73 None
74 }
75 }
76
77 #[inline]
80 pub const fn from_bits_truncate(bits: u16) -> Self {
81 Self {
82 bits: bits & Self::all().bits,
83 }
84 }
85
86 #[inline]
88 pub const fn is_empty(&self) -> bool {
89 self.bits() == Self::empty().bits()
90 }
91
92 #[inline]
94 pub const fn intersects(&self, other: Self) -> bool {
95 !(Self {
96 bits: self.bits & other.bits,
97 })
98 .is_empty()
99 }
100
101 #[inline]
103 pub const fn contains(&self, other: Self) -> bool {
104 (self.bits & other.bits) == other.bits
105 }
106
107 #[inline]
109 pub fn insert(&mut self, other: Self) {
110 self.bits |= other.bits;
111 }
112
113 #[inline]
115 pub fn remove(&mut self, other: Self) {
116 self.bits &= !other.bits;
117 }
118
119 #[inline]
121 pub fn toggle(&mut self, other: Self) {
122 self.bits ^= other.bits;
123 }
124
125 #[inline]
136 #[must_use]
137 pub const fn intersection(self, other: Self) -> Self {
138 Self {
139 bits: self.bits & other.bits,
140 }
141 }
142
143 #[inline]
154 #[must_use]
155 pub const fn union(self, other: Self) -> Self {
156 Self {
157 bits: self.bits | other.bits,
158 }
159 }
160
161 #[inline]
174 #[must_use]
175 pub const fn difference(self, other: Self) -> Self {
176 Self {
177 bits: self.bits & !other.bits,
178 }
179 }
180}
181
182impl std::ops::BitOr for MacStyle {
183 type Output = Self;
184
185 #[inline]
187 fn bitor(self, other: MacStyle) -> Self {
188 Self {
189 bits: self.bits | other.bits,
190 }
191 }
192}
193
194impl std::ops::BitOrAssign for MacStyle {
195 #[inline]
197 fn bitor_assign(&mut self, other: Self) {
198 self.bits |= other.bits;
199 }
200}
201
202impl std::ops::BitXor for MacStyle {
203 type Output = Self;
204
205 #[inline]
207 fn bitxor(self, other: Self) -> Self {
208 Self {
209 bits: self.bits ^ other.bits,
210 }
211 }
212}
213
214impl std::ops::BitXorAssign for MacStyle {
215 #[inline]
217 fn bitxor_assign(&mut self, other: Self) {
218 self.bits ^= other.bits;
219 }
220}
221
222impl std::ops::BitAnd for MacStyle {
223 type Output = Self;
224
225 #[inline]
227 fn bitand(self, other: Self) -> Self {
228 Self {
229 bits: self.bits & other.bits,
230 }
231 }
232}
233
234impl std::ops::BitAndAssign for MacStyle {
235 #[inline]
237 fn bitand_assign(&mut self, other: Self) {
238 self.bits &= other.bits;
239 }
240}
241
242impl std::ops::Sub for MacStyle {
243 type Output = Self;
244
245 #[inline]
247 fn sub(self, other: Self) -> Self {
248 Self {
249 bits: self.bits & !other.bits,
250 }
251 }
252}
253
254impl std::ops::SubAssign for MacStyle {
255 #[inline]
257 fn sub_assign(&mut self, other: Self) {
258 self.bits &= !other.bits;
259 }
260}
261
262impl std::ops::Not for MacStyle {
263 type Output = Self;
264
265 #[inline]
267 fn not(self) -> Self {
268 Self { bits: !self.bits } & Self::all()
269 }
270}
271
272impl std::fmt::Debug for MacStyle {
273 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
274 let members: &[(&str, Self)] = &[
275 ("BOLD", Self::BOLD),
276 ("ITALIC", Self::ITALIC),
277 ("UNDERLINE", Self::UNDERLINE),
278 ("OUTLINE", Self::OUTLINE),
279 ("SHADOW", Self::SHADOW),
280 ("CONDENSED", Self::CONDENSED),
281 ("EXTENDED", Self::EXTENDED),
282 ];
283 let mut first = true;
284 for (name, value) in members {
285 if self.contains(*value) {
286 if !first {
287 f.write_str(" | ")?;
288 }
289 first = false;
290 f.write_str(name)?;
291 }
292 }
293 if first {
294 f.write_str("(empty)")?;
295 }
296 Ok(())
297 }
298}
299
300impl std::fmt::Binary for MacStyle {
301 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
302 std::fmt::Binary::fmt(&self.bits, f)
303 }
304}
305
306impl std::fmt::Octal for MacStyle {
307 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
308 std::fmt::Octal::fmt(&self.bits, f)
309 }
310}
311
312impl std::fmt::LowerHex for MacStyle {
313 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
314 std::fmt::LowerHex::fmt(&self.bits, f)
315 }
316}
317
318impl std::fmt::UpperHex for MacStyle {
319 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
320 std::fmt::UpperHex::fmt(&self.bits, f)
321 }
322}
323
324impl font_types::Scalar for MacStyle {
325 type Raw = <u16 as font_types::Scalar>::Raw;
326 fn to_raw(self) -> Self::Raw {
327 self.bits().to_raw()
328 }
329 fn from_raw(raw: Self::Raw) -> Self {
330 let t = <u16>::from_raw(raw);
331 Self::from_bits_truncate(t)
332 }
333}
334
335#[cfg(feature = "experimental_traverse")]
336impl<'a> From<MacStyle> for FieldType<'a> {
337 fn from(src: MacStyle) -> FieldType<'a> {
338 src.bits().into()
339 }
340}
341
342#[derive(Debug, Clone, Copy)]
345#[doc(hidden)]
346pub struct HeadMarker {}
347
348impl HeadMarker {
349 pub fn version_byte_range(&self) -> Range<usize> {
350 let start = 0;
351 start..start + MajorMinor::RAW_BYTE_LEN
352 }
353
354 pub fn font_revision_byte_range(&self) -> Range<usize> {
355 let start = self.version_byte_range().end;
356 start..start + Fixed::RAW_BYTE_LEN
357 }
358
359 pub fn checksum_adjustment_byte_range(&self) -> Range<usize> {
360 let start = self.font_revision_byte_range().end;
361 start..start + u32::RAW_BYTE_LEN
362 }
363
364 pub fn magic_number_byte_range(&self) -> Range<usize> {
365 let start = self.checksum_adjustment_byte_range().end;
366 start..start + u32::RAW_BYTE_LEN
367 }
368
369 pub fn flags_byte_range(&self) -> Range<usize> {
370 let start = self.magic_number_byte_range().end;
371 start..start + u16::RAW_BYTE_LEN
372 }
373
374 pub fn units_per_em_byte_range(&self) -> Range<usize> {
375 let start = self.flags_byte_range().end;
376 start..start + u16::RAW_BYTE_LEN
377 }
378
379 pub fn created_byte_range(&self) -> Range<usize> {
380 let start = self.units_per_em_byte_range().end;
381 start..start + LongDateTime::RAW_BYTE_LEN
382 }
383
384 pub fn modified_byte_range(&self) -> Range<usize> {
385 let start = self.created_byte_range().end;
386 start..start + LongDateTime::RAW_BYTE_LEN
387 }
388
389 pub fn x_min_byte_range(&self) -> Range<usize> {
390 let start = self.modified_byte_range().end;
391 start..start + i16::RAW_BYTE_LEN
392 }
393
394 pub fn y_min_byte_range(&self) -> Range<usize> {
395 let start = self.x_min_byte_range().end;
396 start..start + i16::RAW_BYTE_LEN
397 }
398
399 pub fn x_max_byte_range(&self) -> Range<usize> {
400 let start = self.y_min_byte_range().end;
401 start..start + i16::RAW_BYTE_LEN
402 }
403
404 pub fn y_max_byte_range(&self) -> Range<usize> {
405 let start = self.x_max_byte_range().end;
406 start..start + i16::RAW_BYTE_LEN
407 }
408
409 pub fn mac_style_byte_range(&self) -> Range<usize> {
410 let start = self.y_max_byte_range().end;
411 start..start + MacStyle::RAW_BYTE_LEN
412 }
413
414 pub fn lowest_rec_ppem_byte_range(&self) -> Range<usize> {
415 let start = self.mac_style_byte_range().end;
416 start..start + u16::RAW_BYTE_LEN
417 }
418
419 pub fn font_direction_hint_byte_range(&self) -> Range<usize> {
420 let start = self.lowest_rec_ppem_byte_range().end;
421 start..start + i16::RAW_BYTE_LEN
422 }
423
424 pub fn index_to_loc_format_byte_range(&self) -> Range<usize> {
425 let start = self.font_direction_hint_byte_range().end;
426 start..start + i16::RAW_BYTE_LEN
427 }
428
429 pub fn glyph_data_format_byte_range(&self) -> Range<usize> {
430 let start = self.index_to_loc_format_byte_range().end;
431 start..start + i16::RAW_BYTE_LEN
432 }
433}
434
435impl MinByteRange for HeadMarker {
436 fn min_byte_range(&self) -> Range<usize> {
437 0..self.glyph_data_format_byte_range().end
438 }
439}
440
441impl TopLevelTable for Head<'_> {
442 const TAG: Tag = Tag::new(b"head");
444}
445
446impl<'a> FontRead<'a> for Head<'a> {
447 fn read(data: FontData<'a>) -> Result<Self, ReadError> {
448 let mut cursor = data.cursor();
449 cursor.advance::<MajorMinor>();
450 cursor.advance::<Fixed>();
451 cursor.advance::<u32>();
452 cursor.advance::<u32>();
453 cursor.advance::<u16>();
454 cursor.advance::<u16>();
455 cursor.advance::<LongDateTime>();
456 cursor.advance::<LongDateTime>();
457 cursor.advance::<i16>();
458 cursor.advance::<i16>();
459 cursor.advance::<i16>();
460 cursor.advance::<i16>();
461 cursor.advance::<MacStyle>();
462 cursor.advance::<u16>();
463 cursor.advance::<i16>();
464 cursor.advance::<i16>();
465 cursor.advance::<i16>();
466 cursor.finish(HeadMarker {})
467 }
468}
469
470pub type Head<'a> = TableRef<'a, HeadMarker>;
473
474#[allow(clippy::needless_lifetimes)]
475impl<'a> Head<'a> {
476 pub fn version(&self) -> MajorMinor {
478 let range = self.shape.version_byte_range();
479 self.data.read_at(range.start).unwrap()
480 }
481
482 pub fn font_revision(&self) -> Fixed {
484 let range = self.shape.font_revision_byte_range();
485 self.data.read_at(range.start).unwrap()
486 }
487
488 pub fn checksum_adjustment(&self) -> u32 {
494 let range = self.shape.checksum_adjustment_byte_range();
495 self.data.read_at(range.start).unwrap()
496 }
497
498 pub fn magic_number(&self) -> u32 {
500 let range = self.shape.magic_number_byte_range();
501 self.data.read_at(range.start).unwrap()
502 }
503
504 pub fn flags(&self) -> u16 {
506 let range = self.shape.flags_byte_range();
507 self.data.read_at(range.start).unwrap()
508 }
509
510 pub fn units_per_em(&self) -> u16 {
515 let range = self.shape.units_per_em_byte_range();
516 self.data.read_at(range.start).unwrap()
517 }
518
519 pub fn created(&self) -> LongDateTime {
522 let range = self.shape.created_byte_range();
523 self.data.read_at(range.start).unwrap()
524 }
525
526 pub fn modified(&self) -> LongDateTime {
529 let range = self.shape.modified_byte_range();
530 self.data.read_at(range.start).unwrap()
531 }
532
533 pub fn x_min(&self) -> i16 {
535 let range = self.shape.x_min_byte_range();
536 self.data.read_at(range.start).unwrap()
537 }
538
539 pub fn y_min(&self) -> i16 {
541 let range = self.shape.y_min_byte_range();
542 self.data.read_at(range.start).unwrap()
543 }
544
545 pub fn x_max(&self) -> i16 {
547 let range = self.shape.x_max_byte_range();
548 self.data.read_at(range.start).unwrap()
549 }
550
551 pub fn y_max(&self) -> i16 {
553 let range = self.shape.y_max_byte_range();
554 self.data.read_at(range.start).unwrap()
555 }
556
557 pub fn mac_style(&self) -> MacStyle {
559 let range = self.shape.mac_style_byte_range();
560 self.data.read_at(range.start).unwrap()
561 }
562
563 pub fn lowest_rec_ppem(&self) -> u16 {
565 let range = self.shape.lowest_rec_ppem_byte_range();
566 self.data.read_at(range.start).unwrap()
567 }
568
569 pub fn font_direction_hint(&self) -> i16 {
571 let range = self.shape.font_direction_hint_byte_range();
572 self.data.read_at(range.start).unwrap()
573 }
574
575 pub fn index_to_loc_format(&self) -> i16 {
577 let range = self.shape.index_to_loc_format_byte_range();
578 self.data.read_at(range.start).unwrap()
579 }
580
581 pub fn glyph_data_format(&self) -> i16 {
583 let range = self.shape.glyph_data_format_byte_range();
584 self.data.read_at(range.start).unwrap()
585 }
586}
587
588#[cfg(feature = "experimental_traverse")]
589impl<'a> SomeTable<'a> for Head<'a> {
590 fn type_name(&self) -> &str {
591 "Head"
592 }
593 fn get_field(&self, idx: usize) -> Option<Field<'a>> {
594 match idx {
595 0usize => Some(Field::new("version", self.version())),
596 1usize => Some(Field::new("font_revision", self.font_revision())),
597 2usize => Some(Field::new(
598 "checksum_adjustment",
599 self.checksum_adjustment(),
600 )),
601 3usize => Some(Field::new("magic_number", self.magic_number())),
602 4usize => Some(Field::new("flags", self.flags())),
603 5usize => Some(Field::new("units_per_em", self.units_per_em())),
604 6usize => Some(Field::new("created", self.created())),
605 7usize => Some(Field::new("modified", self.modified())),
606 8usize => Some(Field::new("x_min", self.x_min())),
607 9usize => Some(Field::new("y_min", self.y_min())),
608 10usize => Some(Field::new("x_max", self.x_max())),
609 11usize => Some(Field::new("y_max", self.y_max())),
610 12usize => Some(Field::new("mac_style", self.mac_style())),
611 13usize => Some(Field::new("lowest_rec_ppem", self.lowest_rec_ppem())),
612 14usize => Some(Field::new(
613 "font_direction_hint",
614 self.font_direction_hint(),
615 )),
616 15usize => Some(Field::new(
617 "index_to_loc_format",
618 self.index_to_loc_format(),
619 )),
620 16usize => Some(Field::new("glyph_data_format", self.glyph_data_format())),
621 _ => None,
622 }
623 }
624}
625
626#[cfg(feature = "experimental_traverse")]
627#[allow(clippy::needless_lifetimes)]
628impl<'a> std::fmt::Debug for Head<'a> {
629 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
630 (self as &dyn SomeTable<'a>).fmt(f)
631 }
632}