1use alloc::{string::String, vec::Vec};
2use core::convert::TryFrom;
3
4use crate::ttf_parser::GlyphId;
5
6use crate::{script, Direction, Face, Language, Mask, Script};
7use crate::unicode::{CharExt, GeneralCategory, GeneralCategoryExt, Space};
8
9const CONTEXT_LENGTH: usize = 5;
10
11
12pub mod glyph_flag {
13 pub const UNSAFE_TO_BREAK: u32 = 0x00000001;
29
30 pub const DEFINED: u32 = 0x00000001; }
33
34
35#[repr(C)]
39#[derive(Clone, Copy, Default, Debug)]
40pub struct GlyphPosition {
41 pub x_advance: i32,
44 pub y_advance: i32,
47 pub x_offset: i32,
50 pub y_offset: i32,
53 var: u32,
54}
55
56unsafe impl bytemuck::Zeroable for GlyphPosition {}
57unsafe impl bytemuck::Pod for GlyphPosition {}
58
59impl GlyphPosition {
60 #[inline]
61 pub(crate) fn attach_chain(&self) -> i16 {
62 let v: &[i16; 2] = bytemuck::cast_ref(&self.var);
65 v[0]
66 }
67
68 #[inline]
69 pub(crate) fn set_attach_chain(&mut self, n: i16) {
70 let v: &mut [i16; 2] = bytemuck::cast_mut(&mut self.var);
71 v[0] = n;
72 }
73
74 #[inline]
75 pub(crate) fn attach_type(&self) -> u8 {
76 let v: &[u8; 4] = bytemuck::cast_ref(&self.var);
79 v[2]
80 }
81
82 #[inline]
83 pub(crate) fn set_attach_type(&mut self, n: u8) {
84 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var);
85 v[2] = n;
86 }
87}
88
89
90#[repr(C)]
92#[derive(Clone, Copy, Default, Debug)]
93pub struct GlyphInfo {
94 pub glyph_id: u32,
101 pub(crate) mask: Mask,
102 pub cluster: u32,
106 pub(crate) var1: u32,
107 pub(crate) var2: u32,
108}
109
110unsafe impl bytemuck::Zeroable for GlyphInfo {}
111unsafe impl bytemuck::Pod for GlyphInfo {}
112
113const IS_LIG_BASE: u8 = 0x10;
114
115impl GlyphInfo {
116 pub fn unsafe_to_break(&self) -> bool {
127 self.mask & glyph_flag::UNSAFE_TO_BREAK != 0
128 }
129
130 #[inline]
131 pub(crate) fn as_char(&self) -> char {
132 char::try_from(self.glyph_id).unwrap()
133 }
134
135 #[inline]
136 pub(crate) fn as_glyph(&self) -> GlyphId {
137 debug_assert!(self.glyph_id <= u32::from(u16::MAX));
138 GlyphId(self.glyph_id as u16)
139 }
140
141 #[inline]
145 fn unicode_props(&self) -> u16 {
146 let v: &[u16; 2] = bytemuck::cast_ref(&self.var2);
147 v[0]
148 }
149
150 #[inline]
151 fn set_unicode_props(&mut self, n: u16) {
152 let v: &mut [u16; 2] = bytemuck::cast_mut(&mut self.var2);
153 v[0] = n;
154 }
155
156 pub(crate) fn init_unicode_props(&mut self, scratch_flags: &mut BufferScratchFlags) {
157 let u = self.as_char();
158 let gc = u.general_category();
159 let mut props = gc.to_rb() as u16;
160
161 if u as u32 >= 0x80 {
162 *scratch_flags |= BufferScratchFlags::HAS_NON_ASCII;
163
164 if u.is_default_ignorable() {
165 props |= UnicodeProps::IGNORABLE.bits;
166 *scratch_flags |= BufferScratchFlags::HAS_DEFAULT_IGNORABLES;
167
168 match u as u32 {
169 0x200C => props |= UnicodeProps::CF_ZWNJ.bits,
170 0x200D => props |= UnicodeProps::CF_ZWJ.bits,
171
172 0x180B..=0x180D => props |= UnicodeProps::HIDDEN.bits,
180
181 0xE0020..=0xE007F => props |= UnicodeProps::HIDDEN.bits,
184
185 0x034F => {
188 props |= UnicodeProps::HIDDEN.bits;
189 *scratch_flags |= BufferScratchFlags::HAS_CGJ;
190 }
191
192 _ => {}
193 }
194 }
195
196 if gc.is_mark() {
197 props |= UnicodeProps::CONTINUATION.bits;
198 props |= (u.modified_combining_class() as u16) << 8;
199 }
200 }
201
202 self.set_unicode_props(props);
203 }
204
205 #[inline]
206 pub(crate) fn general_category(&self) -> GeneralCategory {
207 let n = self.unicode_props() & UnicodeProps::GENERAL_CATEGORY.bits;
208 GeneralCategory::from_rb(n as u32)
209 }
210
211 #[inline]
212 pub(crate) fn set_general_category(&mut self, gc: GeneralCategory) {
213 let gc = gc.to_rb();
214 let n = (gc as u16) | (self.unicode_props() & (0xFF & !UnicodeProps::GENERAL_CATEGORY.bits));
215 self.set_unicode_props(n);
216 }
217
218 #[inline]
219 pub(crate) fn space_fallback(&self) -> Option<Space> {
220 if self.general_category() == GeneralCategory::SpaceSeparator {
221 let n = (self.unicode_props() >> 8) as u8;
222 Some(n)
223 } else {
224 None
225 }
226 }
227
228 #[inline]
229 pub(crate) fn set_space_fallback(&mut self, space: Space) {
230 if self.general_category() == GeneralCategory::SpaceSeparator {
231 let n = ((space as u16) << 8) | (self.unicode_props() & 0xFF);
232 self.set_unicode_props(n);
233 }
234 }
235
236 #[inline]
237 pub(crate) fn is_unicode_mark(&self) -> bool {
238 self.general_category().is_mark()
239 }
240
241 #[inline]
242 pub(crate) fn is_zwnj(&self) -> bool {
243 self.general_category() == GeneralCategory::Format
244 && (self.unicode_props() & UnicodeProps::CF_ZWNJ.bits != 0)
245 }
246
247 #[inline]
248 pub(crate) fn is_zwj(&self) -> bool {
249 self.general_category() == GeneralCategory::Format
250 && (self.unicode_props() & UnicodeProps::CF_ZWJ.bits != 0)
251 }
252
253 #[inline]
254 pub(crate) fn modified_combining_class(&self) -> u8 {
255 if self.is_unicode_mark() {
256 (self.unicode_props() >> 8) as u8
257 } else {
258 0
259 }
260 }
261
262 #[inline]
263 pub(crate) fn set_modified_combining_class(&mut self, mcc: u8) {
264 if self.is_unicode_mark() {
265 let n = ((mcc as u16) << 8) | (self.unicode_props() & 0xFF);
266 self.set_unicode_props(n);
267 }
268 }
269
270 #[inline]
271 pub(crate) fn is_hidden(&self) -> bool {
272 self.unicode_props() & UnicodeProps::HIDDEN.bits != 0
273 }
274
275 #[inline]
276 pub(crate) fn unhide(&mut self) {
277 let mut n = self.unicode_props();
278 n &= !UnicodeProps::HIDDEN.bits;
279 self.set_unicode_props(n);
280 }
281
282 #[inline]
283 pub(crate) fn set_continuation(&mut self) {
284 let mut n = self.unicode_props();
285 n |= UnicodeProps::CONTINUATION.bits;
286 self.set_unicode_props(n);
287 }
288
289 #[inline]
290 pub(crate) fn reset_continuation(&mut self) {
291 let mut n = self.unicode_props();
292 n &= !UnicodeProps::CONTINUATION.bits;
293 self.set_unicode_props(n);
294 }
295
296 #[inline]
297 pub(crate) fn is_continuation(&self) -> bool {
298 self.unicode_props() & UnicodeProps::CONTINUATION.bits != 0
299 }
300
301 #[inline]
302 pub(crate) fn is_default_ignorable(&self) -> bool {
303 let n = self.unicode_props() & UnicodeProps::IGNORABLE.bits;
304 n != 0 && !self.is_ligated()
305 }
306
307 #[inline]
333 pub(crate) fn lig_props(&self) -> u8 {
334 let v: &[u8; 4] = bytemuck::cast_ref(&self.var1);
335 v[2]
336 }
337
338 #[inline]
339 pub(crate) fn set_lig_props(&mut self, n: u8) {
340 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var1);
341 v[2] = n;
342 }
343
344 pub(crate) fn set_lig_props_for_ligature(&mut self, lig_id: u8, lig_num_comps: u8) {
345 self.set_lig_props((lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F));
346 }
347
348 pub(crate) fn set_lig_props_for_mark(&mut self, lig_id: u8, lig_comp: u8) {
349 self.set_lig_props((lig_id << 5) | (lig_comp & 0x0F));
350 }
351
352 pub(crate) fn set_lig_props_for_component(&mut self, lig_comp: u8) {
353 self.set_lig_props_for_mark(0, lig_comp)
354 }
355
356 #[inline]
357 pub(crate) fn lig_id(&self) -> u8 {
358 self.lig_props() >> 5
359 }
360
361 #[inline]
362 pub(crate) fn is_ligated_internal(&self) -> bool {
363 self.lig_props() & IS_LIG_BASE != 0
364 }
365
366 #[inline]
367 pub(crate) fn lig_comp(&self) -> u8 {
368 if self.is_ligated_internal() {
369 0
370 } else {
371 self.lig_props() & 0x0F
372 }
373 }
374
375 #[inline]
376 pub(crate) fn lig_num_comps(&self) -> u8 {
377 if self.glyph_props() & GlyphPropsFlags::LIGATURE.bits != 0 && self.is_ligated_internal() {
378 self.lig_props() & 0x0F
379 } else {
380 1
381 }
382 }
383
384 #[inline]
388 pub(crate) fn glyph_props(&self) -> u16 {
389 let v: &[u16; 2] = bytemuck::cast_ref(&self.var1);
390 v[0]
391 }
392
393 #[inline]
394 pub(crate) fn set_glyph_props(&mut self, n: u16) {
395 let v: &mut [u16; 2] = bytemuck::cast_mut(&mut self.var1);
396 v[0] = n;
397 }
398
399 #[inline]
400 pub(crate) fn is_base_glyph(&self) -> bool {
401 self.glyph_props() & GlyphPropsFlags::BASE_GLYPH.bits != 0
402 }
403
404 #[inline]
405 pub(crate) fn is_ligature(&self) -> bool {
406 self.glyph_props() & GlyphPropsFlags::LIGATURE.bits != 0
407 }
408
409 #[inline]
410 pub(crate) fn is_mark(&self) -> bool {
411 self.glyph_props() & GlyphPropsFlags::MARK.bits != 0
412 }
413
414 #[inline]
415 pub(crate) fn is_substituted(&self) -> bool {
416 self.glyph_props() & GlyphPropsFlags::SUBSTITUTED.bits != 0
417 }
418
419 #[inline]
420 pub(crate) fn is_ligated(&self) -> bool {
421 self.glyph_props() & GlyphPropsFlags::LIGATED.bits != 0
422 }
423
424 #[inline]
425 pub(crate) fn is_multiplied(&self) -> bool {
426 self.glyph_props() & GlyphPropsFlags::MULTIPLIED.bits != 0
427 }
428
429 #[inline]
430 pub(crate) fn is_ligated_and_didnt_multiply(&self) -> bool {
431 self.is_ligated() && !self.is_multiplied()
432 }
433
434 #[inline]
435 pub(crate) fn clear_ligated_and_multiplied(&mut self) {
436 let mut n = self.glyph_props();
437 n &= !(GlyphPropsFlags::LIGATED | GlyphPropsFlags::MULTIPLIED).bits;
438 self.set_glyph_props(n);
439 }
440
441 #[inline]
442 pub(crate) fn clear_substituted(&mut self) {
443 let mut n = self.glyph_props();
444 n &= !GlyphPropsFlags::SUBSTITUTED.bits;
445 self.set_glyph_props(n);
446 }
447
448 #[inline]
452 pub(crate) fn syllable(&self) -> u8 {
453 let v: &[u8; 4] = bytemuck::cast_ref(&self.var1);
454 v[3]
455 }
456
457 #[inline]
458 pub(crate) fn set_syllable(&mut self, n: u8) {
459 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var1);
460 v[3] = n;
461 }
462
463 #[inline]
467 pub(crate) fn glyph_index(&mut self) -> u32 {
468 self.var1
469 }
470
471 #[inline]
472 pub(crate) fn set_glyph_index(&mut self, n: u32) {
473 self.var1 = n;
474 }
475}
476
477
478#[allow(missing_docs)]
480#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
481pub enum BufferClusterLevel {
482 MonotoneGraphemes,
483 MonotoneCharacters,
484 Characters,
485}
486
487impl Default for BufferClusterLevel {
488 #[inline]
489 fn default() -> Self {
490 BufferClusterLevel::MonotoneGraphemes
491 }
492}
493
494
495pub struct Buffer {
496 pub flags: BufferFlags,
498 pub cluster_level: BufferClusterLevel,
499 pub invisible: Option<GlyphId>,
500 pub scratch_flags: BufferScratchFlags,
501 pub max_len: usize,
503 pub max_ops: i32,
505
506 pub direction: Direction,
508 pub script: Option<Script>,
509 pub language: Option<Language>,
510
511 pub successful: bool,
513 have_output: bool,
515 pub have_separate_output: bool,
516 pub have_positions: bool,
518
519 pub idx: usize,
520 pub len: usize,
521 pub out_len: usize,
522
523 pub info: Vec<GlyphInfo>,
524 pub pos: Vec<GlyphPosition>,
525
526 serial: u32,
527
528 pub context: [[char; CONTEXT_LENGTH]; 2],
532 pub context_len: [usize; 2],
533}
534
535impl Buffer {
536 pub const MAX_LEN_FACTOR: usize = 32;
537 pub const MAX_LEN_MIN: usize = 8192;
538 pub const MAX_LEN_DEFAULT: usize = 0x3FFFFFFF;
540
541 pub const MAX_OPS_FACTOR: i32 = 64;
542 pub const MAX_OPS_MIN: i32 = 1024;
543 pub const MAX_OPS_DEFAULT: i32 = 0x1FFFFFFF;
545
546 pub fn new() -> Self {
548 Buffer {
549 flags: BufferFlags::empty(),
550 cluster_level: BufferClusterLevel::default(),
551 invisible: None,
552 scratch_flags: BufferScratchFlags::default(),
553 max_len: Self::MAX_LEN_DEFAULT,
554 max_ops: Self::MAX_OPS_DEFAULT,
555 direction: Direction::Invalid,
556 script: None,
557 language: None,
558 successful: true,
559 have_output: false,
560 have_positions: false,
561 idx: 0,
562 len: 0,
563 out_len: 0,
564 info: Vec::new(),
565 pos: Vec::new(),
566 have_separate_output: false,
567 serial: 0,
568 context: [['\0', '\0', '\0', '\0', '\0'], ['\0', '\0', '\0', '\0', '\0']],
569 context_len: [0, 0],
570 }
571 }
572
573 #[inline]
574 pub fn info_slice(&self) -> &[GlyphInfo] {
575 &self.info[..self.len]
576 }
577
578 #[inline]
579 pub fn info_slice_mut(&mut self) -> &mut [GlyphInfo] {
580 &mut self.info[..self.len]
581 }
582
583 #[inline]
584 pub fn out_info(&self) -> &[GlyphInfo] {
585 if self.have_separate_output {
586 bytemuck::cast_slice(self.pos.as_slice())
587 } else {
588 &self.info
589 }
590 }
591
592 #[inline]
593 pub fn out_info_mut(&mut self) -> &mut [GlyphInfo] {
594 if self.have_separate_output {
595 bytemuck::cast_slice_mut(self.pos.as_mut_slice())
596 } else {
597 &mut self.info
598 }
599 }
600
601 #[inline]
602 fn set_out_info(&mut self, i: usize, info: GlyphInfo) {
603 self.out_info_mut()[i] = info;
604 }
605
606 #[inline]
607 pub fn cur(&self, i: usize) -> &GlyphInfo {
608 &self.info[self.idx + i]
609 }
610
611 #[inline]
612 pub fn cur_mut(&mut self, i: usize) -> &mut GlyphInfo {
613 let idx = self.idx + i;
614 &mut self.info[idx]
615 }
616
617 #[inline]
618 pub fn cur_pos_mut(&mut self) -> &mut GlyphPosition {
619 let i = self.idx;
620 &mut self.pos[i]
621 }
622
623 #[inline]
624 pub fn prev(&self) -> &GlyphInfo {
625 let idx = self.out_len.saturating_sub(1);
626 &self.out_info()[idx]
627 }
628
629 #[inline]
630 pub fn prev_mut(&mut self) -> &mut GlyphInfo {
631 let idx = self.out_len.saturating_sub(1);
632 &mut self.out_info_mut()[idx]
633 }
634
635 fn clear(&mut self) {
636 self.direction = Direction::Invalid;
637 self.script = None;
638 self.language = None;
639 self.scratch_flags = BufferScratchFlags::default();
640
641 self.successful = true;
642 self.have_output = false;
643 self.have_positions = false;
644
645 self.idx = 0;
646 self.info.clear();
647 self.pos.clear();
648 self.len = 0;
649 self.out_len = 0;
650 self.have_separate_output = false;
651
652 self.serial = 0;
653
654 self.context = [['\0', '\0', '\0', '\0', '\0'], ['\0', '\0', '\0', '\0', '\0']];
655 self.context_len = [0, 0];
656 }
657
658 #[inline]
659 pub fn backtrack_len(&self) -> usize {
660 if self.have_output { self.out_len } else { self.idx }
661 }
662
663 #[inline]
664 pub fn lookahead_len(&self) -> usize {
665 self.len - self.idx
666 }
667
668 #[inline]
669 fn next_serial(&mut self) -> u32 {
670 self.serial += 1;
671 self.serial
672 }
673
674 fn add(&mut self, codepoint: u32, cluster: u32) {
675 self.ensure(self.len + 1);
676
677 let i = self.len;
678 self.info[i] = GlyphInfo {
679 glyph_id: codepoint,
680 mask: 0,
681 cluster,
682 var1: 0,
683 var2: 0,
684 };
685
686 self.len += 1;
687 }
688
689 #[inline]
690 pub fn reverse(&mut self) {
691 if self.is_empty() {
692 return;
693 }
694
695 self.reverse_range(0, self.len);
696 }
697
698 pub fn reverse_range(&mut self, start: usize, end: usize) {
699 if end - start < 2 {
700 return;
701 }
702
703 self.info[start..end].reverse();
704 if self.have_positions {
705 self.pos[start..end].reverse();
706 }
707 }
708
709 #[inline]
710 fn reset_clusters(&mut self) {
711 for (i, info) in self.info.iter_mut().enumerate() {
712 info.cluster = i as u32;
713 }
714 }
715
716 pub fn guess_segment_properties(&mut self) {
717 if self.script.is_none() {
718 for info in &self.info {
719 match info.as_char().script() {
720 crate::script::COMMON
721 | crate::script::INHERITED
722 | crate::script::UNKNOWN => {}
723 s => {
724 self.script = Some(s);
725 break;
726 }
727 }
728 }
729 }
730
731 if self.direction == Direction::Invalid {
732 if let Some(script) = self.script {
733 self.direction = Direction::from_script(script).unwrap_or_default();
734 }
735
736 if self.direction == Direction::Invalid {
737 self.direction = Direction::LeftToRight;
738 }
739 }
740
741 }
743
744 pub fn swap_buffers(&mut self) {
745 if !self.successful {
746 return;
747 }
748
749 assert!(self.have_output);
750 self.have_output = false;
751
752 if self.have_separate_output {
753 let info: Vec<GlyphPosition> = bytemuck::cast_vec(core::mem::take(&mut self.info));
755 let pos: Vec<GlyphInfo> = bytemuck::cast_vec(core::mem::take(&mut self.pos));
756 self.pos = info;
757 self.info = pos;
758 }
759
760 core::mem::swap(&mut self.len, &mut self.out_len);
761
762 self.idx = 0;
763 }
764
765 pub fn remove_output(&mut self) {
766 self.have_output = false;
767 self.have_positions = false;
768
769 self.out_len = 0;
770 self.have_separate_output = false;
771 }
772
773 pub fn clear_output(&mut self) {
774 self.have_output = true;
775 self.have_positions = false;
776
777 self.out_len = 0;
778 self.have_separate_output = false;
779 }
780
781 pub fn clear_positions(&mut self) {
782 self.have_output = false;
783 self.have_positions = true;
784
785 self.out_len = 0;
786 self.have_separate_output = false;
787
788 for pos in &mut self.pos {
789 *pos = GlyphPosition::default();
790 }
791 }
792
793 pub fn replace_glyphs(&mut self, num_in: usize, num_out: usize, glyph_data: &[u32]) {
794 if !self.make_room_for(num_in, num_out) {
795 return;
796 }
797
798 assert!(self.idx + num_in <= self.len);
799
800 self.merge_clusters(self.idx, self.idx + num_in);
801
802 let orig_info = self.info[self.idx];
803 for i in 0..num_out {
804 let ii = self.out_len + i;
805 self.set_out_info(ii, orig_info);
806 self.out_info_mut()[ii].glyph_id = glyph_data[i];
807 }
808
809 self.idx += num_in;
810 self.out_len += num_out;
811 }
812
813 pub fn replace_glyph(&mut self, glyph_index: u32) {
814 if self.have_separate_output || self.out_len != self.idx {
815 if !self.make_room_for(1, 1) {
816 return;
817 }
818
819 self.set_out_info(self.out_len, self.info[self.idx]);
820 }
821
822 let out_len = self.out_len;
823 self.out_info_mut()[out_len].glyph_id = glyph_index;
824
825 self.idx += 1;
826 self.out_len += 1;
827 }
828
829 pub fn output_glyph(&mut self, glyph_index: u32) {
830 if !self.make_room_for(0, 1) {
831 return;
832 }
833
834 if self.idx == self.len && self.out_len == 0 {
835 return;
836 }
837
838 let out_len = self.out_len;
839 if self.idx < self.len {
840 self.set_out_info(out_len, self.info[self.idx]);
841 } else {
842 let info = self.out_info()[out_len - 1];
843 self.set_out_info(out_len, info);
844 }
845
846 self.out_info_mut()[out_len].glyph_id = glyph_index;
847
848 self.out_len += 1;
849 }
850
851 pub fn output_info(&mut self, glyph_info: GlyphInfo) {
852 if !self.make_room_for(0, 1) {
853 return;
854 }
855
856 self.set_out_info(self.out_len, glyph_info);
857 self.out_len += 1;
858 }
859
860 pub fn output_char(&mut self, unichar: u32, glyph: u32) {
861 self.cur_mut(0).set_glyph_index(glyph);
862 self.output_glyph(unichar);
864 let mut flags = self.scratch_flags;
865 self.prev_mut().init_unicode_props(&mut flags);
866 self.scratch_flags = flags;
867 }
868
869 pub fn copy_glyph(&mut self) {
871 if !self.make_room_for(0, 1) {
872 return;
873 }
874
875 self.set_out_info(self.out_len, self.info[self.idx]);
876 self.out_len += 1;
877 }
878
879 pub fn next_glyph(&mut self) {
883 if self.have_output {
884 if self.have_separate_output || self.out_len != self.idx {
885 if !self.make_room_for(1, 1) {
886 return;
887 }
888
889 self.set_out_info(self.out_len, self.info[self.idx]);
890 }
891
892 self.out_len += 1;
893 }
894
895 self.idx += 1;
896 }
897
898 pub fn next_glyphs(&mut self, n: usize) {
902 if self.have_output {
903 if self.have_separate_output || self.out_len != self.idx {
904 if !self.make_room_for(n, n) {
905 return;
906 }
907
908 for i in 0..n {
909 self.set_out_info(self.out_len + i, self.info[self.idx + i]);
910 }
911 }
912
913 self.out_len += n;
914 }
915
916 self.idx += n;
917 }
918
919 pub fn next_char(&mut self, glyph: u32) {
920 self.cur_mut(0).set_glyph_index(glyph);
921 self.next_glyph();
922 }
923
924 pub fn skip_glyph(&mut self) {
926 self.idx += 1;
927 }
928
929 pub fn reset_masks(&mut self, mask: Mask) {
930 for info in &mut self.info[..self.len] {
931 info.mask = mask;
932 }
933 }
934
935 pub fn set_masks(
936 &mut self,
937 mut value: Mask,
938 mask: Mask,
939 cluster_start: u32,
940 cluster_end: u32,
941 ) {
942 let not_mask = !mask;
943 value &= mask;
944
945 if mask == 0 {
946 return;
947 }
948
949 if cluster_start == 0 && cluster_end == core::u32::MAX {
950 for info in &mut self.info[..self.len] {
951 info.mask = (info.mask & not_mask) | value;
952 }
953
954 return;
955 }
956
957 for info in &mut self.info[..self.len] {
958 if cluster_start <= info.cluster && info.cluster < cluster_end {
959 info.mask = (info.mask & not_mask) | value;
960 }
961 }
962 }
963
964 pub fn merge_clusters(&mut self, start: usize, end: usize) {
965 if end - start < 2 {
966 return;
967 }
968
969 self.merge_clusters_impl(start, end)
970 }
971
972 fn merge_clusters_impl(&mut self, mut start: usize, mut end: usize) {
973 if self.cluster_level == BufferClusterLevel::Characters {
974 self.unsafe_to_break(start, end);
975 return;
976 }
977
978 let mut cluster = self.info[start].cluster;
979
980 for i in start+1..end {
981 cluster = core::cmp::min(cluster, self.info[i].cluster);
982 }
983
984 while end < self.len && self.info[end - 1].cluster == self.info[end].cluster {
986 end += 1;
987 }
988
989 while end < start && self.info[start - 1].cluster == self.info[start].cluster {
991 start -= 1;
992 }
993
994 if self.idx == start {
996 let mut i = self.out_len;
997 while i != 0 && self.out_info()[i - 1].cluster == self.info[start].cluster {
998 Self::set_cluster(&mut self.out_info_mut()[i - 1], cluster, 0);
999 i -= 1;
1000 }
1001 }
1002
1003 for i in start..end {
1004 Self::set_cluster(&mut self.info[i], cluster, 0);
1005 }
1006 }
1007
1008 pub fn merge_out_clusters(&mut self, mut start: usize, mut end: usize) {
1009 if self.cluster_level == BufferClusterLevel::Characters {
1010 return;
1011 }
1012
1013 if end - start < 2 {
1014 return;
1015 }
1016
1017 let mut cluster = self.out_info()[start].cluster;
1018
1019 for i in start+1..end {
1020 cluster = core::cmp::min(cluster, self.out_info()[i].cluster);
1021 }
1022
1023 while start != 0 && self.out_info()[start - 1].cluster == self.out_info()[start].cluster {
1025 start -= 1;
1026 }
1027
1028 while end < self.out_len && self.out_info()[end - 1].cluster == self.out_info()[end].cluster {
1030 end += 1;
1031 }
1032
1033 if end == self.out_len {
1035 let mut i = self.idx;
1036 while i < self.len && self.info[i].cluster == self.out_info()[end - 1].cluster {
1037 Self::set_cluster(&mut self.info[i], cluster, 0);
1038 i += 1;
1039 }
1040 }
1041
1042 for i in start..end {
1043 Self::set_cluster(&mut self.out_info_mut()[i], cluster, 0);
1044 }
1045 }
1046
1047 pub fn delete_glyph(&mut self) {
1049 let cluster = self.info[self.idx].cluster;
1050
1051 if self.idx + 1 < self.len && cluster == self.info[self.idx + 1].cluster {
1052 self.skip_glyph();
1054 return;
1055 }
1056
1057 if self.out_len != 0 {
1058 if cluster < self.out_info()[self.out_len - 1].cluster {
1060 let mask = self.info[self.idx].mask;
1061 let old_cluster = self.out_info()[self.out_len - 1].cluster;
1062
1063 let mut i = self.out_len;
1064 while i != 0 && self.out_info()[i - 1].cluster == old_cluster {
1065 Self::set_cluster(&mut self.out_info_mut()[i - 1], cluster, mask);
1066 i -= 1;
1067 }
1068 }
1069
1070 self.skip_glyph();
1071 return;
1072 }
1073
1074 if self.idx + 1 < self.len {
1075 self.merge_clusters(self.idx, self.idx + 2);
1077 }
1078
1079 self.skip_glyph();
1080 }
1081
1082 pub fn delete_glyphs_inplace(&mut self, filter: impl Fn(&GlyphInfo) -> bool) {
1083 let mut j = 0;
1086
1087 for i in 0..self.len {
1088 if filter(&self.info[i]) {
1089 let cluster = self.info[i].cluster;
1093 if i + 1 < self.len && cluster == self.info[i + 1].cluster {
1094 continue;
1096 }
1097
1098 if j != 0 {
1099 if cluster < self.info[j - 1].cluster {
1101 let mask = self.info[i].mask;
1102 let old_cluster = self.info[j - 1].cluster;
1103
1104 let mut k = j;
1105 while k > 0 && self.info[k - 1].cluster == old_cluster {
1106 Self::set_cluster(&mut self.info[k - 1], cluster, mask);
1107 k -= 1;
1108 }
1109 }
1110 continue;
1111 }
1112
1113 if i + 1 < self.len {
1114 self.merge_clusters(i, i + 2);
1116 }
1117
1118 continue;
1119 }
1120
1121 if j != i {
1122 self.info[j] = self.info[i];
1123 self.pos[j] = self.pos[i];
1124 }
1125
1126 j += 1;
1127 }
1128
1129 self.len = j;
1130 }
1131
1132 pub fn unsafe_to_break(&mut self, start: usize, end: usize) {
1133 if end - start < 2 {
1134 return;
1135 }
1136
1137 self.unsafe_to_break_impl(start, end);
1138 }
1139
1140 fn unsafe_to_break_impl(&mut self, start: usize, end: usize) {
1141 let mut cluster = core::u32::MAX;
1142 cluster = Self::_unsafe_to_break_find_min_cluster(&self.info, start, end, cluster);
1143 let unsafe_to_break = Self::_unsafe_to_break_set_mask(&mut self.info, start, end, cluster);
1144 if unsafe_to_break {
1145 self.scratch_flags |= BufferScratchFlags::HAS_UNSAFE_TO_BREAK;
1146 }
1147 }
1148
1149 pub fn unsafe_to_break_from_outbuffer(&mut self, start: usize, end: usize) {
1150 if !self.have_output {
1151 self.unsafe_to_break_impl(start, end);
1152 return;
1153 }
1154
1155 assert!(start <= self.out_len);
1156 assert!(self.idx <= end);
1157
1158 let mut cluster = core::u32::MAX;
1159 cluster = Self::_unsafe_to_break_find_min_cluster(self.out_info(), start, self.out_len, cluster);
1160 cluster = Self::_unsafe_to_break_find_min_cluster(&self.info, self.idx, end, cluster);
1161 let idx = self.idx;
1162 let out_len = self.out_len;
1163 let unsafe_to_break1 = Self::_unsafe_to_break_set_mask(self.out_info_mut(), start, out_len, cluster);
1164 let unsafe_to_break2 = Self::_unsafe_to_break_set_mask(&mut self.info, idx, end, cluster);
1165
1166 if unsafe_to_break1 || unsafe_to_break2 {
1167 self.scratch_flags |= BufferScratchFlags::HAS_UNSAFE_TO_BREAK;
1168 }
1169 }
1170
1171 pub fn move_to(&mut self, i: usize) -> bool {
1172 if !self.have_output {
1173 assert!(i <= self.len);
1174 self.idx = i;
1175 return true;
1176 }
1177
1178 if !self.successful {
1179 return false;
1180 }
1181
1182 assert!(i <= self.out_len + (self.len - self.idx));
1183
1184 if self.out_len < i {
1185 let count = i - self.out_len;
1186 if !self.make_room_for(count, count) {
1187 return false;
1188 }
1189
1190 for j in 0..count {
1191 self.set_out_info(self.out_len + j, self.info[self.idx + j]);
1192 }
1193
1194 self.idx += count;
1195 self.out_len += count;
1196 } else if self.out_len > i {
1197 let count = self.out_len - i;
1199
1200 if self.idx < count {
1209 self.shift_forward(count);
1210 }
1211
1212 assert!(self.idx >= count);
1213
1214 self.idx -= count;
1215 self.out_len -= count;
1216
1217 for j in 0..count {
1218 self.info[self.idx + j] = self.out_info()[self.out_len + j];
1219 }
1220 }
1221
1222 true
1223 }
1224
1225 pub fn ensure(&mut self, size: usize) -> bool {
1226 if size < self.len {
1227 return true;
1228 }
1229
1230 if size > self.max_len {
1231 self.successful = false;
1232 return false;
1233 }
1234
1235 self.info.resize(size, GlyphInfo::default());
1236 self.pos.resize(size, GlyphPosition::default());
1237 true
1238 }
1239
1240 pub fn set_len(&mut self, len: usize) {
1241 self.ensure(len);
1242 self.len = len;
1243 }
1244
1245 fn make_room_for(&mut self, num_in: usize, num_out: usize) -> bool {
1246 if !self.ensure(self.out_len + num_out) {
1247 return false;
1248 }
1249
1250 if !self.have_separate_output && self.out_len + num_out > self.idx + num_in {
1251 assert!(self.have_output);
1252
1253 self.have_separate_output = true;
1254 for i in 0..self.out_len {
1255 self.set_out_info(i, self.info[i]);
1256 }
1257 }
1258
1259 true
1260 }
1261
1262 fn shift_forward(&mut self, count: usize) {
1263 assert!(self.have_output);
1264 self.ensure(self.len + count);
1265
1266 for i in 0..(self.len - self.idx) {
1267 self.info[self.idx + count + i] = self.info[self.idx + i];
1268 }
1269
1270 if self.idx + count > self.len {
1271 for info in &mut self.info[self.len..self.idx+count] {
1272 *info = GlyphInfo::default();
1273 }
1274 }
1275
1276 self.len += count;
1277 self.idx += count;
1278 }
1279
1280 pub fn sort(&mut self, start: usize, end: usize, cmp: impl Fn(&GlyphInfo, &GlyphInfo) -> bool) {
1281 assert!(!self.have_positions);
1282
1283 for i in start+1..end {
1284 let mut j = i;
1285 while j > start && cmp(&self.info[j - 1], &self.info[i]) {
1286 j -= 1;
1287 }
1288
1289 if i == j {
1290 continue;
1291 }
1292
1293 self.merge_clusters(j, i + 1);
1295
1296 {
1297 let t = self.info[i];
1298 for idx in (0..i-j).rev() {
1299 self.info[idx + j + 1] = self.info[idx + j];
1300 }
1301
1302 self.info[j] = t;
1303 }
1304 }
1305 }
1306
1307 pub fn set_cluster(info: &mut GlyphInfo, cluster: u32, mask: Mask) {
1308 if info.cluster != cluster {
1309 if mask & glyph_flag::UNSAFE_TO_BREAK != 0 {
1310 info.mask |= glyph_flag::UNSAFE_TO_BREAK;
1311 } else {
1312 info.mask &= !glyph_flag::UNSAFE_TO_BREAK;
1313 }
1314 }
1315
1316 info.cluster = cluster;
1317 }
1318
1319 fn _unsafe_to_break_find_min_cluster(info: &[GlyphInfo], start: usize, end: usize, mut cluster: u32) -> u32 {
1320 for glyph_info in &info[start..end] {
1321 cluster = core::cmp::min(cluster, glyph_info.cluster);
1322 }
1323
1324 cluster
1325 }
1326
1327 fn _unsafe_to_break_set_mask(info: &mut [GlyphInfo], start: usize, end: usize, cluster: u32) -> bool {
1328 let mut unsafe_to_break = false;
1329 for glyph_info in &mut info[start..end] {
1330 if glyph_info.cluster != cluster {
1331 unsafe_to_break = true;
1332 glyph_info.mask |= glyph_flag::UNSAFE_TO_BREAK;
1333 }
1334 }
1335
1336 unsafe_to_break
1337 }
1338
1339 pub fn is_empty(&self) -> bool {
1341 self.len == 0
1342 }
1343
1344 fn push_str(&mut self, text: &str) {
1345 self.ensure(self.len + text.chars().count());
1346
1347 for (i, c) in text.char_indices() {
1348 self.add(c as u32, i as u32);
1349 }
1350 }
1351
1352 pub fn next_cluster(&self, mut start: usize) -> usize {
1353 if start >= self.len {
1354 return start;
1355 }
1356
1357 let cluster = self.info[start].cluster;
1358 start += 1;
1359 while start < self.len && cluster == self.info[start].cluster {
1360 start += 1;
1361 }
1362
1363 start
1364 }
1365
1366 pub fn next_syllable(&self, mut start: usize) -> usize {
1367 if start >= self.len {
1368 return start;
1369 }
1370
1371 let syllable = self.info[start].syllable();
1372 start += 1;
1373 while start < self.len && syllable == self.info[start].syllable() {
1374 start += 1;
1375 }
1376
1377 start
1378 }
1379
1380 pub fn next_grapheme(&self, mut start: usize) -> usize {
1381 if start >= self.len {
1382 return start;
1383 }
1384
1385 start += 1;
1386 while start < self.len && self.info[start].is_continuation() {
1387 start += 1;
1388 }
1389
1390 start
1391 }
1392
1393 #[inline]
1394 pub fn allocate_lig_id(&mut self) -> u8 {
1395 let mut lig_id = self.next_serial() & 0x07;
1396 if lig_id == 0 {
1397 lig_id = self.next_serial() & 0x07;
1399 }
1400 lig_id as u8
1401 }
1402}
1403
1404macro_rules! foreach_cluster {
1407 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {{
1408 let mut $start = 0;
1409 let mut $end = $buffer.next_cluster(0);
1410 while $start < $buffer.len {
1411 $($body)*;
1412 $start = $end;
1413 $end = $buffer.next_cluster($start);
1414 }
1415 }};
1416}
1417
1418macro_rules! foreach_syllable {
1419 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {{
1420 let mut $start = 0;
1421 let mut $end = $buffer.next_syllable(0);
1422 while $start < $buffer.len {
1423 $($body)*;
1424 $start = $end;
1425 $end = $buffer.next_syllable($start);
1426 }
1427 }};
1428}
1429
1430macro_rules! foreach_grapheme {
1431 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {{
1432 let mut $start = 0;
1433 let mut $end = $buffer.next_grapheme(0);
1434 while $start < $buffer.len {
1435 $($body)*;
1436 $start = $end;
1437 $end = $buffer.next_grapheme($start);
1438 }
1439 }};
1440}
1441
1442
1443bitflags::bitflags! {
1444 #[derive(Default)]
1445 pub struct UnicodeProps: u16 {
1446 const GENERAL_CATEGORY = 0x001F;
1447 const IGNORABLE = 0x0020;
1448 const HIDDEN = 0x0040;
1450 const CONTINUATION = 0x0080;
1451
1452 const CF_ZWJ = 0x0100;
1454 const CF_ZWNJ = 0x0200;
1455 }
1456}
1457
1458
1459bitflags::bitflags! {
1460 #[derive(Default)]
1461 pub struct GlyphPropsFlags: u16 {
1462 const BASE_GLYPH = 0x02;
1464 const LIGATURE = 0x04;
1465 const MARK = 0x08;
1466 const CLASS_MASK = Self::BASE_GLYPH.bits | Self::LIGATURE.bits | Self::MARK.bits;
1467
1468 const SUBSTITUTED = 0x10;
1470 const LIGATED = 0x20;
1471 const MULTIPLIED = 0x40;
1472
1473 const PRESERVE = Self::SUBSTITUTED.bits | Self::LIGATED.bits | Self::MULTIPLIED.bits;
1474 }
1475}
1476
1477
1478bitflags::bitflags! {
1479 #[derive(Default)]
1480 pub struct BufferFlags: u32 {
1481 const BEGINNING_OF_TEXT = 1 << 1;
1482 const END_OF_TEXT = 1 << 2;
1483 const PRESERVE_DEFAULT_IGNORABLES = 1 << 3;
1484 const REMOVE_DEFAULT_IGNORABLES = 1 << 4;
1485 const DO_NOT_INSERT_DOTTED_CIRCLE = 1 << 5;
1486 }
1487}
1488
1489
1490bitflags::bitflags! {
1491 #[derive(Default)]
1492 pub struct BufferScratchFlags: u32 {
1493 const HAS_NON_ASCII = 0x00000001;
1494 const HAS_DEFAULT_IGNORABLES = 0x00000002;
1495 const HAS_SPACE_FALLBACK = 0x00000004;
1496 const HAS_GPOS_ATTACHMENT = 0x00000008;
1497 const HAS_UNSAFE_TO_BREAK = 0x00000010;
1498 const HAS_CGJ = 0x00000020;
1499
1500 const COMPLEX0 = 0x01000000;
1502 const COMPLEX1 = 0x02000000;
1503 const COMPLEX2 = 0x04000000;
1504 const COMPLEX3 = 0x08000000;
1505 }
1506}
1507
1508
1509bitflags::bitflags! {
1510 #[derive(Default)]
1512 pub struct SerializeFlags: u8 {
1513 const NO_CLUSTERS = 0b00000001;
1515 const NO_POSITIONS = 0b00000010;
1517 const NO_GLYPH_NAMES = 0b00000100;
1519 const GLYPH_EXTENTS = 0b00001000;
1521 const GLYPH_FLAGS = 0b00010000;
1523 const NO_ADVANCES = 0b00100000;
1526 }
1527}
1528
1529
1530pub struct UnicodeBuffer(pub(crate) Buffer);
1532
1533impl UnicodeBuffer {
1534 #[inline]
1536 pub fn new() -> UnicodeBuffer {
1537 UnicodeBuffer(Buffer::new())
1538 }
1539
1540 #[inline]
1545 pub fn len(&self) -> usize {
1546 self.0.len
1547 }
1548
1549 #[inline]
1551 pub fn is_empty(&self) -> bool {
1552 self.0.is_empty()
1553 }
1554
1555 #[inline]
1557 pub fn push_str(&mut self, str: &str) {
1558 self.0.push_str(str);
1559 }
1560
1561 #[inline]
1563 pub fn add(&mut self, codepoint: char, cluster: u32) {
1564 self.0.add(codepoint as u32, cluster);
1565 self.0.context_len[1] = 0;
1566 }
1567
1568 #[inline]
1570 pub fn set_direction(&mut self, direction: Direction) {
1571 self.0.direction = direction;
1572 }
1573
1574 #[inline]
1576 pub fn direction(&self) -> Direction {
1577 self.0.direction
1578 }
1579
1580 #[inline]
1582 pub fn set_script(&mut self, script: Script) {
1583 self.0.script = Some(script);
1584 }
1585
1586 pub fn script(&self) -> Script {
1588 self.0.script.unwrap_or(script::UNKNOWN)
1589 }
1590
1591 #[inline]
1593 pub fn set_language(&mut self, lang: Language) {
1594 self.0.language = Some(lang);
1595 }
1596
1597 #[inline]
1599 pub fn language(&self) -> Option<Language> {
1600 self.0.language.clone()
1601 }
1602
1603 #[inline]
1606 pub fn guess_segment_properties(&mut self) {
1607 self.0.guess_segment_properties()
1608 }
1609
1610 #[inline]
1612 pub fn set_cluster_level(&mut self, cluster_level: BufferClusterLevel) {
1613 self.0.cluster_level = cluster_level
1614 }
1615
1616 #[inline]
1618 pub fn cluster_level(&self) -> BufferClusterLevel {
1619 self.0.cluster_level
1620 }
1621
1622 #[inline]
1624 pub fn reset_clusters(&mut self) {
1625 self.0.reset_clusters();
1626 }
1627
1628 #[inline]
1630 pub fn clear(&mut self) {
1631 self.0.clear()
1632 }
1633}
1634
1635impl core::fmt::Debug for UnicodeBuffer {
1636 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1637 fmt.debug_struct("UnicodeBuffer")
1638 .field("direction", &self.direction())
1639 .field("language", &self.language())
1640 .field("script", &self.script())
1641 .field("cluster_level", &self.cluster_level())
1642 .finish()
1643 }
1644}
1645
1646impl Default for UnicodeBuffer {
1647 fn default() -> UnicodeBuffer {
1648 UnicodeBuffer::new()
1649 }
1650}
1651
1652
1653pub struct GlyphBuffer(pub(crate) Buffer);
1655
1656impl GlyphBuffer {
1657 #[inline]
1663 pub fn len(&self) -> usize {
1664 self.0.len
1665 }
1666
1667 #[inline]
1669 pub fn is_empty(&self) -> bool {
1670 self.0.is_empty()
1671 }
1672
1673 #[inline]
1675 pub fn glyph_infos(&self) -> &[GlyphInfo] {
1676 &self.0.info[0..self.0.len]
1677 }
1678
1679 #[inline]
1681 pub fn glyph_positions(&self) -> &[GlyphPosition] {
1682 &self.0.pos[0..self.0.len]
1683 }
1684
1685 #[inline]
1688 pub fn clear(mut self) -> UnicodeBuffer {
1689 self.0.clear();
1690 UnicodeBuffer(self.0)
1691 }
1692
1693 pub fn serialize(&self, face: &Face, flags: SerializeFlags) -> String {
1695 self.serialize_impl(face, flags).unwrap_or_default()
1696 }
1697
1698 fn serialize_impl(&self, face: &Face, flags: SerializeFlags) -> Result<String, core::fmt::Error> {
1699 use core::fmt::Write;
1700
1701 let mut s = String::with_capacity(64);
1702
1703 let info = self.glyph_infos();
1704 let pos = self.glyph_positions();
1705 let mut x = 0;
1706 let mut y = 0;
1707 for (info, pos) in info.iter().zip(pos) {
1708 if !flags.contains(SerializeFlags::NO_GLYPH_NAMES) {
1709 match face.glyph_name(info.as_glyph()) {
1710 Some(name) => s.push_str(name),
1711 None => write!(&mut s, "gid{}", info.glyph_id)?,
1712 }
1713 } else {
1714 write!(&mut s, "{}", info.glyph_id)?;
1715 }
1716
1717 if !flags.contains(SerializeFlags::NO_CLUSTERS) {
1718 write!(&mut s, "={}", info.cluster)?;
1719 }
1720
1721 if !flags.contains(SerializeFlags::NO_POSITIONS) {
1722 if x + pos.x_offset != 0 || y + pos.y_offset != 0 {
1723 write!(&mut s, "@{},{}", x + pos.x_offset, y + pos.y_offset)?;
1724 }
1725
1726 if !flags.contains(SerializeFlags::NO_ADVANCES) {
1727 write!(&mut s, "+{}", pos.x_advance)?;
1728 if pos.y_advance != 0 {
1729 write!(&mut s, ",{}", pos.y_advance)?;
1730 }
1731 }
1732 }
1733
1734 if flags.contains(SerializeFlags::GLYPH_FLAGS) {
1735 if info.mask & glyph_flag::DEFINED != 0 {
1736 write!(&mut s, "#{:X}", info.mask & glyph_flag::DEFINED)?;
1737 }
1738 }
1739
1740 if flags.contains(SerializeFlags::GLYPH_EXTENTS) {
1741 let extents = face.glyph_extents(info.as_glyph()).unwrap_or_default();
1742 write!(&mut s, "<{},{},{},{}>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)?;
1743 }
1744
1745 if flags.contains(SerializeFlags::NO_ADVANCES) {
1746 x += pos.x_advance;
1747 y += pos.y_advance;
1748 }
1749
1750 s.push('|');
1751 }
1752
1753 if !s.is_empty() {
1755 s.pop();
1756 }
1757
1758 Ok(s)
1759 }
1760}
1761
1762impl core::fmt::Debug for GlyphBuffer {
1763 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1764 fmt.debug_struct("GlyphBuffer")
1765 .field("glyph_positions", &self.glyph_positions())
1766 .field("glyph_infos", &self.glyph_infos())
1767 .finish()
1768 }
1769}