1use alloc::{string::String, vec::Vec};
2use core::convert::TryFrom;
3use core::cmp::min;
4
5use ttf_parser::GlyphId;
6
7use super::buffer::glyph_flag::{UNSAFE_TO_BREAK, UNSAFE_TO_CONCAT};
8use super::face::GlyphExtents;
9use super::unicode::{CharExt, GeneralCategoryExt};
10use super::{hb_font_t, hb_mask_t};
11use crate::{script, BufferClusterLevel, BufferFlags, Direction, Language, Script, SerializeFlags};
12
13const CONTEXT_LENGTH: usize = 5;
14
15pub mod glyph_flag {
16 pub const UNSAFE_TO_BREAK: u32 = 0x00000001;
32 pub const UNSAFE_TO_CONCAT: u32 = 0x00000002;
93
94 pub const DEFINED: u32 = 0x00000003; }
97
98#[repr(C)]
102#[derive(Clone, Copy, Default, Debug)]
103pub struct GlyphPosition {
104 pub x_advance: i32,
107 pub y_advance: i32,
110 pub x_offset: i32,
113 pub y_offset: i32,
116 var: u32,
117}
118
119unsafe impl bytemuck::Zeroable for GlyphPosition {}
120unsafe impl bytemuck::Pod for GlyphPosition {}
121
122impl GlyphPosition {
123 #[inline]
124 pub(crate) fn attach_chain(&self) -> i16 {
125 let v: &[i16; 2] = bytemuck::cast_ref(&self.var);
128 v[0]
129 }
130
131 #[inline]
132 pub(crate) fn set_attach_chain(&mut self, n: i16) {
133 let v: &mut [i16; 2] = bytemuck::cast_mut(&mut self.var);
134 v[0] = n;
135 }
136
137 #[inline]
138 pub(crate) fn attach_type(&self) -> u8 {
139 let v: &[u8; 4] = bytemuck::cast_ref(&self.var);
142 v[2]
143 }
144
145 #[inline]
146 pub(crate) fn set_attach_type(&mut self, n: u8) {
147 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var);
148 v[2] = n;
149 }
150}
151
152#[repr(C)]
154#[derive(Clone, Copy, Default, Debug)]
155pub struct hb_glyph_info_t {
156 pub glyph_id: u32,
163 pub(crate) mask: hb_mask_t,
164 pub cluster: u32,
168 pub(crate) var1: u32,
169 pub(crate) var2: u32,
170}
171
172unsafe impl bytemuck::Zeroable for hb_glyph_info_t {}
173unsafe impl bytemuck::Pod for hb_glyph_info_t {}
174
175impl hb_glyph_info_t {
176 pub fn unsafe_to_break(&self) -> bool {
187 self.mask & glyph_flag::UNSAFE_TO_BREAK != 0
188 }
189
190 #[inline]
191 pub(crate) fn as_char(&self) -> char {
192 char::try_from(self.glyph_id).unwrap()
193 }
194
195 #[inline]
196 pub(crate) fn as_glyph(&self) -> GlyphId {
197 debug_assert!(self.glyph_id <= u32::from(u16::MAX));
198 GlyphId(self.glyph_id as u16)
199 }
200
201 #[inline]
205 pub(crate) fn unicode_props(&self) -> u16 {
206 let v: &[u16; 2] = bytemuck::cast_ref(&self.var2);
207 v[0]
208 }
209
210 #[inline]
211 pub(crate) fn set_unicode_props(&mut self, n: u16) {
212 let v: &mut [u16; 2] = bytemuck::cast_mut(&mut self.var2);
213 v[0] = n;
214 }
215
216 pub(crate) fn init_unicode_props(&mut self, scratch_flags: &mut hb_buffer_scratch_flags_t) {
217 let u = self.as_char();
218 let gc = u.general_category();
219 let mut props = gc.to_rb() as u16;
220
221 if u as u32 >= 0x80 {
222 *scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII;
223
224 if u.is_default_ignorable() {
225 props |= UnicodeProps::IGNORABLE.bits();
226 *scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
227
228 match u as u32 {
229 0x200C => props |= UnicodeProps::CF_ZWNJ.bits(),
230 0x200D => props |= UnicodeProps::CF_ZWJ.bits(),
231
232 0x180B..=0x180D | 0x180F => props |= UnicodeProps::HIDDEN.bits(),
240
241 0xE0020..=0xE007F => props |= UnicodeProps::HIDDEN.bits(),
244
245 0x034F => {
248 props |= UnicodeProps::HIDDEN.bits();
249 *scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CGJ;
250 }
251
252 _ => {}
253 }
254 }
255
256 if gc.is_mark() {
257 props |= UnicodeProps::CONTINUATION.bits();
258 props |= (u.modified_combining_class() as u16) << 8;
259 }
260 }
261
262 self.set_unicode_props(props);
263 }
264
265 #[inline]
266 pub(crate) fn is_hidden(&self) -> bool {
267 self.unicode_props() & UnicodeProps::HIDDEN.bits() != 0
268 }
269
270 #[inline]
271 pub(crate) fn unhide(&mut self) {
272 let mut n = self.unicode_props();
273 n &= !UnicodeProps::HIDDEN.bits();
274 self.set_unicode_props(n);
275 }
276
277 #[inline]
278 pub(crate) fn lig_props(&self) -> u8 {
279 let v: &[u8; 4] = bytemuck::cast_ref(&self.var1);
280 v[2]
281 }
282
283 #[inline]
284 pub(crate) fn set_lig_props(&mut self, n: u8) {
285 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var1);
286 v[2] = n;
287 }
288
289 #[inline]
290 pub(crate) fn glyph_props(&self) -> u16 {
291 let v: &[u16; 2] = bytemuck::cast_ref(&self.var1);
292 v[0]
293 }
294
295 #[inline]
296 pub(crate) fn set_glyph_props(&mut self, n: u16) {
297 let v: &mut [u16; 2] = bytemuck::cast_mut(&mut self.var1);
298 v[0] = n;
299 }
300
301 #[inline]
302 pub(crate) fn syllable(&self) -> u8 {
303 let v: &[u8; 4] = bytemuck::cast_ref(&self.var1);
304 v[3]
305 }
306
307 #[inline]
308 pub(crate) fn set_syllable(&mut self, n: u8) {
309 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var1);
310 v[3] = n;
311 }
312
313 #[inline]
317 pub(crate) fn glyph_index(&mut self) -> u32 {
318 self.var1
319 }
320
321 #[inline]
322 pub(crate) fn set_glyph_index(&mut self, n: u32) {
323 self.var1 = n;
324 }
325}
326
327pub type hb_buffer_cluster_level_t = u32;
328pub const HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES: u32 = 0;
329pub const HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS: u32 = 1;
330pub const HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: u32 = 2;
331pub const HB_BUFFER_CLUSTER_LEVEL_DEFAULT: u32 = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES;
332
333pub struct hb_buffer_t {
334 pub flags: BufferFlags,
336 pub cluster_level: hb_buffer_cluster_level_t,
337 pub invisible: Option<GlyphId>,
338
339 pub direction: Direction,
341 pub script: Option<Script>,
342 pub language: Option<Language>,
343
344 pub successful: bool,
346 pub(crate) have_output: bool,
348 pub have_separate_output: bool,
349 pub have_positions: bool,
351
352 pub idx: usize,
353 pub len: usize,
354 pub out_len: usize,
355
356 pub info: Vec<hb_glyph_info_t>,
357 pub pos: Vec<GlyphPosition>,
358
359 pub context: [[char; CONTEXT_LENGTH]; 2],
363 pub context_len: [usize; 2],
364
365 pub serial: u8,
367 pub scratch_flags: hb_buffer_scratch_flags_t,
368 pub max_len: usize,
370 pub max_ops: i32,
372}
373
374impl hb_buffer_t {
375 pub const MAX_LEN_FACTOR: usize = 64;
376 pub const MAX_LEN_MIN: usize = 16384;
377 pub const MAX_LEN_DEFAULT: usize = 0x3FFFFFFF;
379
380 pub const MAX_OPS_FACTOR: i32 = 1024;
381 pub const MAX_OPS_MIN: i32 = 16384;
382 pub const MAX_OPS_DEFAULT: i32 = 0x1FFFFFFF;
384
385 pub fn new() -> Self {
387 hb_buffer_t {
388 flags: BufferFlags::empty(),
389 cluster_level: HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
390 invisible: None,
391 scratch_flags: HB_BUFFER_SCRATCH_FLAG_DEFAULT,
392 max_len: Self::MAX_LEN_DEFAULT,
393 max_ops: Self::MAX_OPS_DEFAULT,
394 direction: Direction::Invalid,
395 script: None,
396 language: None,
397 successful: true,
398 have_output: false,
399 have_positions: false,
400 idx: 0,
401 len: 0,
402 out_len: 0,
403 info: Vec::new(),
404 pos: Vec::new(),
405 have_separate_output: false,
406 serial: 0,
407 context: [
408 ['\0', '\0', '\0', '\0', '\0'],
409 ['\0', '\0', '\0', '\0', '\0'],
410 ],
411 context_len: [0, 0],
412 }
413 }
414
415 #[inline]
416 pub fn info_slice(&self) -> &[hb_glyph_info_t] {
417 &self.info[..self.len]
418 }
419
420 #[inline]
421 pub fn info_slice_mut(&mut self) -> &mut [hb_glyph_info_t] {
422 &mut self.info[..self.len]
423 }
424
425 #[inline]
426 pub fn out_info(&self) -> &[hb_glyph_info_t] {
427 if self.have_separate_output {
428 bytemuck::cast_slice(self.pos.as_slice())
429 } else {
430 &self.info
431 }
432 }
433
434 #[inline]
435 pub fn out_info_mut(&mut self) -> &mut [hb_glyph_info_t] {
436 if self.have_separate_output {
437 bytemuck::cast_slice_mut(self.pos.as_mut_slice())
438 } else {
439 &mut self.info
440 }
441 }
442
443 #[inline]
444 fn set_out_info(&mut self, i: usize, info: hb_glyph_info_t) {
445 self.out_info_mut()[i] = info;
446 }
447
448 #[inline]
449 pub fn cur(&self, i: usize) -> &hb_glyph_info_t {
450 &self.info[self.idx + i]
451 }
452
453 #[inline]
454 pub fn cur_mut(&mut self, i: usize) -> &mut hb_glyph_info_t {
455 let idx = self.idx + i;
456 &mut self.info[idx]
457 }
458
459 #[inline]
460 pub fn cur_pos_mut(&mut self) -> &mut GlyphPosition {
461 let i = self.idx;
462 &mut self.pos[i]
463 }
464
465 #[inline]
466 pub fn prev(&self) -> &hb_glyph_info_t {
467 let idx = self.out_len.saturating_sub(1);
468 &self.out_info()[idx]
469 }
470
471 #[inline]
472 pub fn prev_mut(&mut self) -> &mut hb_glyph_info_t {
473 let idx = self.out_len.saturating_sub(1);
474 &mut self.out_info_mut()[idx]
475 }
476
477 fn clear(&mut self) {
478 self.direction = Direction::Invalid;
479 self.script = None;
480 self.language = None;
481
482 self.successful = true;
483 self.have_output = false;
484 self.have_positions = false;
485
486 self.idx = 0;
487 self.info.clear();
488 self.pos.clear();
489 self.len = 0;
490 self.out_len = 0;
491 self.have_separate_output = false;
492
493 self.context = [
494 ['\0', '\0', '\0', '\0', '\0'],
495 ['\0', '\0', '\0', '\0', '\0'],
496 ];
497 self.context_len = [0, 0];
498
499 self.serial = 0;
500 self.scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
501 self.cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT;
502 }
503
504 #[inline]
505 pub fn backtrack_len(&self) -> usize {
506 if self.have_output {
507 self.out_len
508 } else {
509 self.idx
510 }
511 }
512
513 #[inline]
514 pub fn lookahead_len(&self) -> usize {
515 self.len - self.idx
516 }
517
518 #[inline]
519 fn next_serial(&mut self) -> u8 {
520 self.serial += 1;
521
522 if self.serial == 0 {
523 self.serial += 1;
524 }
525
526 self.serial
527 }
528
529 fn add(&mut self, codepoint: u32, cluster: u32) {
530 self.ensure(self.len + 1);
531
532 let i = self.len;
533 self.info[i] = hb_glyph_info_t {
534 glyph_id: codepoint,
535 mask: 0,
536 cluster,
537 var1: 0,
538 var2: 0,
539 };
540
541 self.len += 1;
542 }
543
544 #[inline]
545 pub fn reverse(&mut self) {
546 if self.is_empty() {
547 return;
548 }
549
550 self.reverse_range(0, self.len);
551 }
552
553 pub fn reverse_range(&mut self, start: usize, end: usize) {
554 if end - start < 2 {
555 return;
556 }
557
558 self.info[start..end].reverse();
559 if self.have_positions {
560 self.pos[start..end].reverse();
561 }
562 }
563
564 pub fn reverse_groups<F>(&mut self, group: F, merge_clusters: bool)
565 where
566 F: Fn(&hb_glyph_info_t, &hb_glyph_info_t) -> bool,
567 {
568 if self.is_empty() {
569 return;
570 }
571
572 let mut start = 0;
573
574 for i in 1..self.len {
575 if !group(&self.info[i - 1], &self.info[i]) {
576 if merge_clusters {
577 self.merge_clusters(start, i);
578 }
579
580 self.reverse_range(start, i);
581 start = i;
582 }
583
584 if merge_clusters {
585 self.merge_clusters(start, i);
586 }
587
588 self.reverse_range(start, i);
589
590 self.reverse();
591 }
592 }
593
594 pub fn group_end<F>(&self, mut start: usize, group: F) -> usize
595 where
596 F: Fn(&hb_glyph_info_t, &hb_glyph_info_t) -> bool,
597 {
598 start += 1;
599
600 while start < self.len && group(&self.info[start - 1], &self.info[start]) {
601 start += 1;
602 }
603
604 start
605 }
606
607 #[inline]
608 fn reset_clusters(&mut self) {
609 for (i, info) in self.info.iter_mut().enumerate() {
610 info.cluster = i as u32;
611 }
612 }
613
614 pub fn guess_segment_properties(&mut self) {
615 if self.script.is_none() {
616 for info in &self.info {
617 match info.as_char().script() {
618 crate::script::COMMON | crate::script::INHERITED | crate::script::UNKNOWN => {}
619 s => {
620 self.script = Some(s);
621 break;
622 }
623 }
624 }
625 }
626
627 if self.direction == Direction::Invalid {
628 if let Some(script) = self.script {
629 self.direction = Direction::from_script(script).unwrap_or_default();
630 }
631
632 if self.direction == Direction::Invalid {
633 self.direction = Direction::LeftToRight;
634 }
635 }
636
637 }
639
640 pub fn sync(&mut self) {
641 assert!(self.have_output);
642
643 assert!(self.idx <= self.len);
644 if !self.successful {
645 self.have_output = false;
646 self.out_len = 0;
647 self.idx = 0;
648 return;
649 }
650
651 self.next_glyphs(self.len - self.idx);
652
653 if self.have_separate_output {
654 let info: Vec<GlyphPosition> = bytemuck::cast_vec(core::mem::take(&mut self.info));
656 let pos: Vec<hb_glyph_info_t> = bytemuck::cast_vec(core::mem::take(&mut self.pos));
657 self.pos = info;
658 self.info = pos;
659 }
660
661 self.len = self.out_len;
662
663 self.have_output = false;
664 self.out_len = 0;
665 self.idx = 0;
666 }
667
668 pub fn clear_output(&mut self) {
669 self.have_output = true;
670 self.have_positions = false;
671
672 self.idx = 0;
673 self.out_len = 0;
674 self.have_separate_output = false;
675 }
676
677 pub fn clear_positions(&mut self) {
678 self.have_output = false;
679 self.have_positions = true;
680
681 self.out_len = 0;
682 self.have_separate_output = false;
683
684 for pos in &mut self.pos {
685 *pos = GlyphPosition::default();
686 }
687 }
688
689 pub fn replace_glyphs(&mut self, num_in: usize, num_out: usize, glyph_data: &[u32]) {
690 if !self.make_room_for(num_in, num_out) {
691 return;
692 }
693
694 assert!(self.idx + num_in <= self.len);
695
696 self.merge_clusters(self.idx, self.idx + num_in);
697
698 let orig_info = self.info[self.idx];
699 for i in 0..num_out {
700 let ii = self.out_len + i;
701 self.set_out_info(ii, orig_info);
702 self.out_info_mut()[ii].glyph_id = glyph_data[i];
703 }
704
705 self.idx += num_in;
706 self.out_len += num_out;
707 }
708
709 pub fn replace_glyph(&mut self, glyph_index: u32) {
710 if self.have_separate_output || self.out_len != self.idx {
711 if !self.make_room_for(1, 1) {
712 return;
713 }
714
715 self.set_out_info(self.out_len, self.info[self.idx]);
716 }
717
718 let out_len = self.out_len;
719 self.out_info_mut()[out_len].glyph_id = glyph_index;
720
721 self.idx += 1;
722 self.out_len += 1;
723 }
724
725 pub fn output_glyph(&mut self, glyph_index: u32) {
726 if !self.make_room_for(0, 1) {
727 return;
728 }
729
730 if self.idx == self.len && self.out_len == 0 {
731 return;
732 }
733
734 let out_len = self.out_len;
735 if self.idx < self.len {
736 self.set_out_info(out_len, self.info[self.idx]);
737 } else {
738 let info = self.out_info()[out_len - 1];
739 self.set_out_info(out_len, info);
740 }
741
742 self.out_info_mut()[out_len].glyph_id = glyph_index;
743
744 self.out_len += 1;
745 }
746
747 pub fn output_info(&mut self, glyph_info: hb_glyph_info_t) {
748 if !self.make_room_for(0, 1) {
749 return;
750 }
751
752 self.set_out_info(self.out_len, glyph_info);
753 self.out_len += 1;
754 }
755
756 pub fn copy_glyph(&mut self) {
758 if !self.make_room_for(0, 1) {
759 return;
760 }
761
762 self.set_out_info(self.out_len, self.info[self.idx]);
763 self.out_len += 1;
764 }
765
766 pub fn next_glyph(&mut self) {
770 if self.have_output {
771 if self.have_separate_output || self.out_len != self.idx {
772 if !self.make_room_for(1, 1) {
773 return;
774 }
775
776 self.set_out_info(self.out_len, self.info[self.idx]);
777 }
778
779 self.out_len += 1;
780 }
781
782 self.idx += 1;
783 }
784
785 pub fn next_glyphs(&mut self, n: usize) {
789 if self.have_output {
790 if self.have_separate_output || self.out_len != self.idx {
791 if !self.make_room_for(n, n) {
792 return;
793 }
794
795 for i in 0..n {
796 self.set_out_info(self.out_len + i, self.info[self.idx + i]);
797 }
798 }
799
800 self.out_len += n;
801 }
802
803 self.idx += n;
804 }
805
806 pub fn skip_glyph(&mut self) {
808 self.idx += 1;
809 }
810
811 pub fn reset_masks(&mut self, mask: hb_mask_t) {
812 for info in &mut self.info[..self.len] {
813 info.mask = mask;
814 }
815 }
816
817 pub fn set_masks(
818 &mut self,
819 mut value: hb_mask_t,
820 mask: hb_mask_t,
821 cluster_start: u32,
822 cluster_end: u32,
823 ) {
824 let not_mask = !mask;
825 value &= mask;
826
827 if mask == 0 {
828 return;
829 }
830
831 if cluster_start == 0 && cluster_end == core::u32::MAX {
832 for info in &mut self.info[..self.len] {
833 info.mask = (info.mask & not_mask) | value;
834 }
835
836 return;
837 }
838
839 for info in &mut self.info[..self.len] {
840 if cluster_start <= info.cluster && info.cluster < cluster_end {
841 info.mask = (info.mask & not_mask) | value;
842 }
843 }
844 }
845
846 pub fn merge_clusters(&mut self, start: usize, end: usize) {
847 if end - start < 2 {
848 return;
849 }
850
851 self.merge_clusters_impl(start, end)
852 }
853
854 fn merge_clusters_impl(&mut self, mut start: usize, mut end: usize) {
855 if self.cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS {
856 self.unsafe_to_break(Some(start), Some(end));
857 return;
858 }
859
860 let mut cluster = self.info[start].cluster;
861
862 for i in start + 1..end {
863 cluster = core::cmp::min(cluster, self.info[i].cluster);
864 }
865
866 while end < self.len && self.info[end - 1].cluster == self.info[end].cluster {
868 end += 1;
869 }
870
871 while end < start && self.info[start - 1].cluster == self.info[start].cluster {
873 start -= 1;
874 }
875
876 if self.idx == start {
878 let mut i = self.out_len;
879 while i != 0 && self.out_info()[i - 1].cluster == self.info[start].cluster {
880 Self::set_cluster(&mut self.out_info_mut()[i - 1], cluster, 0);
881 i -= 1;
882 }
883 }
884
885 for i in start..end {
886 Self::set_cluster(&mut self.info[i], cluster, 0);
887 }
888 }
889
890 pub fn merge_out_clusters(&mut self, mut start: usize, mut end: usize) {
891 if self.cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS {
892 return;
893 }
894
895 if end - start < 2 {
896 return;
897 }
898
899 let mut cluster = self.out_info()[start].cluster;
900
901 for i in start + 1..end {
902 cluster = core::cmp::min(cluster, self.out_info()[i].cluster);
903 }
904
905 while start != 0 && self.out_info()[start - 1].cluster == self.out_info()[start].cluster {
907 start -= 1;
908 }
909
910 while end < self.out_len && self.out_info()[end - 1].cluster == self.out_info()[end].cluster
912 {
913 end += 1;
914 }
915
916 if end == self.out_len {
918 let mut i = self.idx;
919 while i < self.len && self.info[i].cluster == self.out_info()[end - 1].cluster {
920 Self::set_cluster(&mut self.info[i], cluster, 0);
921 i += 1;
922 }
923 }
924
925 for i in start..end {
926 Self::set_cluster(&mut self.out_info_mut()[i], cluster, 0);
927 }
928 }
929
930 pub fn delete_glyph(&mut self) {
932 let cluster = self.info[self.idx].cluster;
933
934 if self.idx + 1 < self.len && cluster == self.info[self.idx + 1].cluster {
935 self.skip_glyph();
937 return;
938 }
939
940 if self.out_len != 0 {
941 if cluster < self.out_info()[self.out_len - 1].cluster {
943 let mask = self.info[self.idx].mask;
944 let old_cluster = self.out_info()[self.out_len - 1].cluster;
945
946 let mut i = self.out_len;
947 while i != 0 && self.out_info()[i - 1].cluster == old_cluster {
948 Self::set_cluster(&mut self.out_info_mut()[i - 1], cluster, mask);
949 i -= 1;
950 }
951 }
952
953 self.skip_glyph();
954 return;
955 }
956
957 if self.idx + 1 < self.len {
958 self.merge_clusters(self.idx, self.idx + 2);
960 }
961
962 self.skip_glyph();
963 }
964
965 pub fn delete_glyphs_inplace(&mut self, filter: impl Fn(&hb_glyph_info_t) -> bool) {
966 let mut j = 0;
969
970 for i in 0..self.len {
971 if filter(&self.info[i]) {
972 let cluster = self.info[i].cluster;
976 if i + 1 < self.len && cluster == self.info[i + 1].cluster {
977 continue;
979 }
980
981 if j != 0 {
982 if cluster < self.info[j - 1].cluster {
984 let mask = self.info[i].mask;
985 let old_cluster = self.info[j - 1].cluster;
986
987 let mut k = j;
988 while k > 0 && self.info[k - 1].cluster == old_cluster {
989 Self::set_cluster(&mut self.info[k - 1], cluster, mask);
990 k -= 1;
991 }
992 }
993 continue;
994 }
995
996 if i + 1 < self.len {
997 self.merge_clusters(i, i + 2);
999 }
1000
1001 continue;
1002 }
1003
1004 if j != i {
1005 self.info[j] = self.info[i];
1006 self.pos[j] = self.pos[i];
1007 }
1008
1009 j += 1;
1010 }
1011
1012 self.len = j;
1013 }
1014
1015 pub fn unsafe_to_break(&mut self, start: Option<usize>, end: Option<usize>) {
1016 self._set_glyph_flags(
1017 UNSAFE_TO_BREAK | UNSAFE_TO_CONCAT,
1018 start,
1019 end,
1020 Some(true),
1021 None,
1022 );
1023 }
1024
1025 fn _set_glyph_flags(
1029 &mut self,
1030 mask: hb_mask_t,
1031 start: Option<usize>,
1032 end: Option<usize>,
1033 interior: Option<bool>,
1034 from_out_buffer: Option<bool>,
1035 ) {
1036 let start = start.unwrap_or(0);
1037 let end = min(end.unwrap_or(self.len), self.len);
1038 let interior = interior.unwrap_or(false);
1039 let from_out_buffer = from_out_buffer.unwrap_or(false);
1040
1041 if interior && !from_out_buffer && end - start < 2 {
1042 return;
1043 }
1044
1045 self.scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
1046
1047 if !from_out_buffer || !self.have_output {
1048 if !interior {
1049 for i in start..end {
1050 self.info[i].mask |= mask;
1051 }
1052 } else {
1053 let cluster = Self::_infos_find_min_cluster(&self.info, start, end, None);
1054 if Self::_infos_set_glyph_flags(&mut self.info, start, end, cluster, mask) {
1055 self.scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
1056 }
1057 }
1058 } else {
1059 assert!(start <= self.out_len);
1060 assert!(self.idx <= end);
1061
1062 if !interior {
1063 for i in start..self.out_len {
1064 self.out_info_mut()[i].mask |= mask;
1065 }
1066
1067 for i in self.idx..end {
1068 self.info[i].mask |= mask;
1069 }
1070 } else {
1071 let mut cluster = Self::_infos_find_min_cluster(&self.info, self.idx, end, None);
1072 cluster = Self::_infos_find_min_cluster(
1073 &self.out_info(),
1074 start,
1075 self.out_len,
1076 Some(cluster),
1077 );
1078
1079 let out_len = self.out_len;
1080 let first = Self::_infos_set_glyph_flags(
1081 &mut self.out_info_mut(),
1082 start,
1083 out_len,
1084 cluster,
1085 mask,
1086 );
1087 let second =
1088 Self::_infos_set_glyph_flags(&mut self.info, self.idx, end, cluster, mask);
1089
1090 if first || second {
1091 self.scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
1092 }
1093 }
1094 }
1095 }
1096
1097 pub fn unsafe_to_concat(&mut self, start: Option<usize>, end: Option<usize>) {
1098 if !self.flags.contains(BufferFlags::PRODUCE_UNSAFE_TO_CONCAT) {
1099 return;
1100 }
1101
1102 self._set_glyph_flags(UNSAFE_TO_CONCAT, start, end, Some(true), None);
1103 }
1104
1105 pub fn unsafe_to_break_from_outbuffer(&mut self, start: Option<usize>, end: Option<usize>) {
1106 if !self.flags.contains(BufferFlags::PRODUCE_UNSAFE_TO_CONCAT) {
1107 return;
1108 }
1109
1110 self._set_glyph_flags(
1111 UNSAFE_TO_BREAK | UNSAFE_TO_CONCAT,
1112 start,
1113 end,
1114 Some(true),
1115 Some(true),
1116 );
1117 }
1118
1119 pub fn unsafe_to_concat_from_outbuffer(&mut self, start: Option<usize>, end: Option<usize>) {
1120 self._set_glyph_flags(UNSAFE_TO_CONCAT, start, end, Some(false), Some(true));
1121 }
1122
1123 pub fn move_to(&mut self, i: usize) -> bool {
1124 if !self.have_output {
1125 assert!(i <= self.len);
1126 self.idx = i;
1127 return true;
1128 }
1129
1130 if !self.successful {
1131 return false;
1132 }
1133
1134 assert!(i <= self.out_len + (self.len - self.idx));
1135
1136 if self.out_len < i {
1137 let count = i - self.out_len;
1138 if !self.make_room_for(count, count) {
1139 return false;
1140 }
1141
1142 for j in 0..count {
1143 self.set_out_info(self.out_len + j, self.info[self.idx + j]);
1144 }
1145
1146 self.idx += count;
1147 self.out_len += count;
1148 } else if self.out_len > i {
1149 let count = self.out_len - i;
1151
1152 if self.idx < count {
1160 self.shift_forward(count - self.idx);
1161 }
1162
1163 assert!(self.idx >= count);
1164
1165 self.idx -= count;
1166 self.out_len -= count;
1167
1168 for j in 0..count {
1169 self.info[self.idx + j] = self.out_info()[self.out_len + j];
1170 }
1171 }
1172
1173 true
1174 }
1175
1176 pub fn ensure(&mut self, size: usize) -> bool {
1177 if size < self.len {
1178 return true;
1179 }
1180
1181 if size > self.max_len {
1182 self.successful = false;
1183 return false;
1184 }
1185
1186 self.info.resize(size, hb_glyph_info_t::default());
1187 self.pos.resize(size, GlyphPosition::default());
1188 true
1189 }
1190
1191 pub fn set_len(&mut self, len: usize) {
1192 self.ensure(len);
1193 self.len = len;
1194 }
1195
1196 fn make_room_for(&mut self, num_in: usize, num_out: usize) -> bool {
1197 if !self.ensure(self.out_len + num_out) {
1198 return false;
1199 }
1200
1201 if !self.have_separate_output && self.out_len + num_out > self.idx + num_in {
1202 assert!(self.have_output);
1203
1204 self.have_separate_output = true;
1205 for i in 0..self.out_len {
1206 self.set_out_info(i, self.info[i]);
1207 }
1208 }
1209
1210 true
1211 }
1212
1213 fn shift_forward(&mut self, count: usize) {
1214 assert!(self.have_output);
1215 self.ensure(self.len + count);
1216
1217 for i in (0..(self.len - self.idx)).rev() {
1218 self.info[self.idx + count + i] = self.info[self.idx + i];
1219 }
1220
1221 if self.idx + count > self.len {
1222 for info in &mut self.info[self.len..self.idx + count] {
1223 *info = hb_glyph_info_t::default();
1224 }
1225 }
1226
1227 self.len += count;
1228 self.idx += count;
1229 }
1230
1231 fn clear_context(&mut self, side: usize) {
1232 self.context_len[side] = 0;
1233 }
1234
1235 pub fn sort(
1236 &mut self,
1237 start: usize,
1238 end: usize,
1239 cmp: impl Fn(&hb_glyph_info_t, &hb_glyph_info_t) -> bool,
1240 ) {
1241 assert!(!self.have_positions);
1242
1243 for i in start + 1..end {
1244 let mut j = i;
1245 while j > start && cmp(&self.info[j - 1], &self.info[i]) {
1246 j -= 1;
1247 }
1248
1249 if i == j {
1250 continue;
1251 }
1252
1253 self.merge_clusters(j, i + 1);
1255
1256 {
1257 let t = self.info[i];
1258 for idx in (0..i - j).rev() {
1259 self.info[idx + j + 1] = self.info[idx + j];
1260 }
1261
1262 self.info[j] = t;
1263 }
1264 }
1265 }
1266
1267 pub fn set_cluster(info: &mut hb_glyph_info_t, cluster: u32, mask: hb_mask_t) {
1268 if info.cluster != cluster {
1269 info.mask = (info.mask & !glyph_flag::DEFINED) | (mask & glyph_flag::DEFINED);
1270 }
1271
1272 info.cluster = cluster;
1273 }
1274
1275 pub(crate) fn enter(&mut self) {
1277 self.serial = 0;
1278 self.scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
1279
1280 if let Some(len) = self.len.checked_mul(hb_buffer_t::MAX_LEN_FACTOR) {
1281 self.max_len = len.max(hb_buffer_t::MAX_LEN_MIN);
1282 }
1283
1284 if let Ok(len) = i32::try_from(self.len) {
1285 if let Some(ops) = len.checked_mul(hb_buffer_t::MAX_OPS_FACTOR) {
1286 self.max_ops = ops.max(hb_buffer_t::MAX_OPS_MIN);
1287 }
1288 }
1289 }
1290
1291 pub(crate) fn leave(&mut self) {
1293 self.max_len = hb_buffer_t::MAX_LEN_DEFAULT;
1294 self.max_ops = hb_buffer_t::MAX_OPS_DEFAULT;
1295 self.serial = 0;
1296 }
1297
1298 fn _infos_find_min_cluster(
1299 info: &[hb_glyph_info_t],
1300 start: usize,
1301 end: usize,
1302 cluster: Option<u32>,
1303 ) -> u32 {
1304 let mut cluster = cluster.unwrap_or(core::u32::MAX);
1305
1306 for glyph_info in &info[start..end] {
1307 cluster = core::cmp::min(cluster, glyph_info.cluster);
1308 }
1309
1310 cluster
1311 }
1312
1313 #[must_use]
1314 fn _infos_set_glyph_flags(
1315 info: &mut [hb_glyph_info_t],
1316 start: usize,
1317 end: usize,
1318 cluster: u32,
1319 mask: hb_mask_t,
1320 ) -> bool {
1321 let mut unsafe_to_break = false;
1326 for glyph_info in &mut info[start..end] {
1327 if glyph_info.cluster != cluster {
1328 glyph_info.mask |= mask;
1329 unsafe_to_break = true;
1330 }
1331 }
1332
1333 unsafe_to_break
1334 }
1335
1336 pub fn is_empty(&self) -> bool {
1338 self.len == 0
1339 }
1340
1341 fn push_str(&mut self, text: &str) {
1342 self.ensure(self.len + text.chars().count());
1343
1344 for (i, c) in text.char_indices() {
1345 self.add(c as u32, i as u32);
1346 }
1347 }
1348
1349 fn set_pre_context(&mut self, text: &str) {
1350 self.clear_context(0);
1351 for (i, c) in text.chars().rev().enumerate().take(CONTEXT_LENGTH) {
1352 self.context[0][i] = c;
1353 self.context_len[0] += 1;
1354 }
1355 }
1356
1357 fn set_post_context(&mut self, text: &str) {
1358 self.clear_context(1);
1359 for (i, c) in text.chars().enumerate().take(CONTEXT_LENGTH) {
1360 self.context[1][i] = c;
1361 self.context_len[1] += 1;
1362 }
1363 }
1364
1365 pub fn next_syllable(&self, mut start: usize) -> usize {
1366 if start >= self.len {
1367 return start;
1368 }
1369
1370 let syllable = self.info[start].syllable();
1371 start += 1;
1372 while start < self.len && syllable == self.info[start].syllable() {
1373 start += 1;
1374 }
1375
1376 start
1377 }
1378
1379 #[inline]
1380 pub fn allocate_lig_id(&mut self) -> u8 {
1381 let mut lig_id = self.next_serial() & 0x07;
1382
1383 if lig_id == 0 {
1384 lig_id = self.allocate_lig_id();
1385 }
1386
1387 lig_id
1388 }
1389}
1390
1391pub(crate) fn _cluster_group_func(a: &hb_glyph_info_t, b: &hb_glyph_info_t) -> bool {
1392 a.cluster == b.cluster
1393}
1394
1395macro_rules! foreach_cluster {
1398 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {
1399 foreach_group!($buffer, $start, $end, crate::hb::buffer::_cluster_group_func, $($body)*)
1400 };
1401}
1402
1403macro_rules! foreach_group {
1404 ($buffer:expr, $start:ident, $end:ident, $group_func:expr, $($body:tt)*) => {{
1405 let count = $buffer.len;
1406 let mut $start = 0;
1407 let mut $end = if count > 0 { $buffer.group_end(0, $group_func) } else { 0 };
1408
1409 while $start < count {
1410 $($body)*;
1411 $start = $end;
1412 $end = $buffer.group_end($start, $group_func);
1413 }
1414 }};
1415}
1416
1417macro_rules! foreach_syllable {
1418 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {{
1419 let mut $start = 0;
1420 let mut $end = $buffer.next_syllable(0);
1421 while $start < $buffer.len {
1422 $($body)*;
1423 $start = $end;
1424 $end = $buffer.next_syllable($start);
1425 }
1426 }};
1427}
1428
1429macro_rules! foreach_grapheme {
1430 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {
1431 foreach_group!($buffer, $start, $end, crate::hb::ot_layout::_hb_grapheme_group_func, $($body)*)
1432 };
1433}
1434
1435bitflags::bitflags! {
1436 #[derive(Default, Debug, Clone, Copy)]
1437 pub struct UnicodeProps: u16 {
1438 const GENERAL_CATEGORY = 0x001F;
1439 const IGNORABLE = 0x0020;
1440 const HIDDEN = 0x0040;
1442 const CONTINUATION = 0x0080;
1443
1444 const CF_ZWJ = 0x0100;
1446 const CF_ZWNJ = 0x0200;
1447 }
1448}
1449
1450bitflags::bitflags! {
1451 #[derive(Default, Debug, Clone, Copy)]
1452 pub struct GlyphPropsFlags: u16 {
1453 const BASE_GLYPH = 0x02;
1455 const LIGATURE = 0x04;
1456 const MARK = 0x08;
1457 const CLASS_MASK = Self::BASE_GLYPH.bits() | Self::LIGATURE.bits() | Self::MARK.bits();
1458
1459 const SUBSTITUTED = 0x10;
1461 const LIGATED = 0x20;
1462 const MULTIPLIED = 0x40;
1463
1464 const PRESERVE = Self::SUBSTITUTED.bits() | Self::LIGATED.bits() | Self::MULTIPLIED.bits();
1465 }
1466}
1467
1468pub type hb_buffer_scratch_flags_t = u32;
1469pub const HB_BUFFER_SCRATCH_FLAG_DEFAULT: u32 = 0x00000000;
1470pub const HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII: u32 = 0x00000001;
1471pub const HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES: u32 = 0x00000002;
1472pub const HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK: u32 = 0x00000004;
1473pub const HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT: u32 = 0x00000008;
1474pub const HB_BUFFER_SCRATCH_FLAG_HAS_CGJ: u32 = 0x00000010;
1475pub const HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS: u32 = 0x00000020;
1476
1477pub const HB_BUFFER_SCRATCH_FLAG_COMPLEX0: u32 = 0x01000000;
1479pub struct UnicodeBuffer(pub(crate) hb_buffer_t);
1485
1486impl UnicodeBuffer {
1487 #[inline]
1489 pub fn new() -> UnicodeBuffer {
1490 UnicodeBuffer(hb_buffer_t::new())
1491 }
1492
1493 #[inline]
1498 pub fn len(&self) -> usize {
1499 self.0.len
1500 }
1501
1502 #[inline]
1504 pub fn is_empty(&self) -> bool {
1505 self.0.is_empty()
1506 }
1507
1508 #[inline]
1510 pub fn push_str(&mut self, str: &str) {
1511 self.0.push_str(str);
1512 }
1513
1514 #[inline]
1516 pub fn set_pre_context(&mut self, str: &str) {
1517 self.0.set_pre_context(str)
1518 }
1519
1520 #[inline]
1522 pub fn set_post_context(&mut self, str: &str) {
1523 self.0.set_post_context(str)
1524 }
1525
1526 #[inline]
1528 pub fn add(&mut self, codepoint: char, cluster: u32) {
1529 self.0.add(codepoint as u32, cluster);
1530 self.0.context_len[1] = 0;
1531 }
1532
1533 #[inline]
1535 pub fn set_direction(&mut self, direction: Direction) {
1536 self.0.direction = direction;
1537 }
1538
1539 #[inline]
1541 pub fn direction(&self) -> Direction {
1542 self.0.direction
1543 }
1544
1545 #[inline]
1547 pub fn set_script(&mut self, script: Script) {
1548 self.0.script = Some(script);
1549 }
1550
1551 pub fn script(&self) -> Script {
1553 self.0.script.unwrap_or(script::UNKNOWN)
1554 }
1555
1556 #[inline]
1558 pub fn set_language(&mut self, lang: Language) {
1559 self.0.language = Some(lang);
1560 }
1561
1562 #[inline]
1564 pub fn language(&self) -> Option<Language> {
1565 self.0.language.clone()
1566 }
1567
1568 #[inline]
1571 pub fn guess_segment_properties(&mut self) {
1572 self.0.guess_segment_properties()
1573 }
1574
1575 #[inline]
1577 pub fn set_flags(&mut self, flags: BufferFlags) {
1578 self.0.flags = flags;
1579 }
1580
1581 #[inline]
1583 pub fn flags(&self) -> BufferFlags {
1584 self.0.flags
1585 }
1586
1587 #[inline]
1589 pub fn set_cluster_level(&mut self, cluster_level: BufferClusterLevel) {
1590 self.0.cluster_level = match cluster_level {
1591 BufferClusterLevel::MonotoneGraphemes => HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES,
1592 BufferClusterLevel::MonotoneCharacters => HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS,
1593 BufferClusterLevel::Characters => HB_BUFFER_CLUSTER_LEVEL_CHARACTERS,
1594 }
1595 }
1596
1597 #[inline]
1599 pub fn cluster_level(&self) -> BufferClusterLevel {
1600 match self.0.cluster_level {
1601 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES => BufferClusterLevel::MonotoneGraphemes,
1602 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS => BufferClusterLevel::MonotoneCharacters,
1603 HB_BUFFER_CLUSTER_LEVEL_CHARACTERS => BufferClusterLevel::Characters,
1604 _ => BufferClusterLevel::MonotoneGraphemes,
1605 }
1606 }
1607
1608 #[inline]
1610 pub fn reset_clusters(&mut self) {
1611 self.0.reset_clusters();
1612 }
1613
1614 #[inline]
1616 pub fn clear(&mut self) {
1617 self.0.clear()
1618 }
1619}
1620
1621impl core::fmt::Debug for UnicodeBuffer {
1622 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1623 fmt.debug_struct("UnicodeBuffer")
1624 .field("direction", &self.direction())
1625 .field("language", &self.language())
1626 .field("script", &self.script())
1627 .field("cluster_level", &self.cluster_level())
1628 .finish()
1629 }
1630}
1631
1632impl Default for UnicodeBuffer {
1633 fn default() -> UnicodeBuffer {
1634 UnicodeBuffer::new()
1635 }
1636}
1637
1638pub struct GlyphBuffer(pub(crate) hb_buffer_t);
1640
1641impl GlyphBuffer {
1642 #[inline]
1648 pub fn len(&self) -> usize {
1649 self.0.len
1650 }
1651
1652 #[inline]
1654 pub fn is_empty(&self) -> bool {
1655 self.0.is_empty()
1656 }
1657
1658 #[inline]
1660 pub fn glyph_infos(&self) -> &[hb_glyph_info_t] {
1661 &self.0.info[0..self.0.len]
1662 }
1663
1664 #[inline]
1666 pub fn glyph_positions(&self) -> &[GlyphPosition] {
1667 &self.0.pos[0..self.0.len]
1668 }
1669
1670 #[inline]
1673 pub fn clear(mut self) -> UnicodeBuffer {
1674 self.0.clear();
1675 UnicodeBuffer(self.0)
1676 }
1677
1678 pub fn serialize(&self, face: &hb_font_t, flags: SerializeFlags) -> String {
1680 self.serialize_impl(face, flags).unwrap_or_default()
1681 }
1682
1683 fn serialize_impl(
1684 &self,
1685 face: &hb_font_t,
1686 flags: SerializeFlags,
1687 ) -> Result<String, core::fmt::Error> {
1688 use core::fmt::Write;
1689
1690 let mut s = String::with_capacity(64);
1691
1692 let info = self.glyph_infos();
1693 let pos = self.glyph_positions();
1694 let mut x = 0;
1695 let mut y = 0;
1696 for (info, pos) in info.iter().zip(pos) {
1697 if !flags.contains(SerializeFlags::NO_GLYPH_NAMES) {
1698 match face.glyph_name(info.as_glyph()) {
1699 Some(name) => s.push_str(name),
1700 None => write!(&mut s, "gid{}", info.glyph_id)?,
1701 }
1702 } else {
1703 write!(&mut s, "{}", info.glyph_id)?;
1704 }
1705
1706 if !flags.contains(SerializeFlags::NO_CLUSTERS) {
1707 write!(&mut s, "={}", info.cluster)?;
1708 }
1709
1710 if !flags.contains(SerializeFlags::NO_POSITIONS) {
1711 if x + pos.x_offset != 0 || y + pos.y_offset != 0 {
1712 write!(&mut s, "@{},{}", x + pos.x_offset, y + pos.y_offset)?;
1713 }
1714
1715 if !flags.contains(SerializeFlags::NO_ADVANCES) {
1716 write!(&mut s, "+{}", pos.x_advance)?;
1717 if pos.y_advance != 0 {
1718 write!(&mut s, ",{}", pos.y_advance)?;
1719 }
1720 }
1721 }
1722
1723 if flags.contains(SerializeFlags::GLYPH_FLAGS) {
1724 if info.mask & glyph_flag::DEFINED != 0 {
1725 write!(&mut s, "#{:X}", info.mask & glyph_flag::DEFINED)?;
1726 }
1727 }
1728
1729 if flags.contains(SerializeFlags::GLYPH_EXTENTS) {
1730 let mut extents = GlyphExtents::default();
1731 face.glyph_extents(info.as_glyph(), &mut extents);
1732 write!(
1733 &mut s,
1734 "<{},{},{},{}>",
1735 extents.x_bearing, extents.y_bearing, extents.width, extents.height
1736 )?;
1737 }
1738
1739 if flags.contains(SerializeFlags::NO_ADVANCES) {
1740 x += pos.x_advance;
1741 y += pos.y_advance;
1742 }
1743
1744 s.push('|');
1745 }
1746
1747 if !s.is_empty() {
1749 s.pop();
1750 }
1751
1752 Ok(s)
1753 }
1754}
1755
1756impl core::fmt::Debug for GlyphBuffer {
1757 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1758 fmt.debug_struct("GlyphBuffer")
1759 .field("glyph_positions", &self.glyph_positions())
1760 .field("glyph_infos", &self.glyph_infos())
1761 .finish()
1762 }
1763}