1use crate::U32Set;
2use alloc::{string::String, vec::Vec};
3use core::cmp::min;
4use core::convert::TryFrom;
5use read_fonts::types::{GlyphId, GlyphId16};
6
7use super::buffer::glyph_flag::{SAFE_TO_INSERT_TATWEEL, UNSAFE_TO_BREAK, UNSAFE_TO_CONCAT};
8use super::face::hb_glyph_extents_t;
9use super::unicode::CharExt;
10use super::{hb_font_t, hb_mask_t};
11use crate::hb::set_digest::hb_set_digest_t;
12use crate::hb::unicode::Codepoint;
13use crate::{script, BufferClusterLevel, BufferFlags, Direction, Language, Script, SerializeFlags};
14
15const CONTEXT_LENGTH: usize = 5;
16
17pub mod glyph_flag {
18 pub const UNSAFE_TO_BREAK: u32 = 0x0000_0001;
34 pub const UNSAFE_TO_CONCAT: u32 = 0x0000_0002;
95
96 pub const SAFE_TO_INSERT_TATWEEL: u32 = 0x0000_0004;
101
102 pub const DEFINED: u32 = 0x0000_0007; }
105
106#[repr(C)]
110#[derive(Clone, Copy, Default, Debug, bytemuck::Pod, bytemuck::Zeroable)]
111pub struct GlyphPosition {
112 pub x_advance: i32,
115 pub y_advance: i32,
118 pub x_offset: i32,
121 pub y_offset: i32,
124 pub(crate) var: u32,
125}
126
127impl GlyphPosition {
128 #[inline]
129 pub(crate) fn attach_chain(&self) -> i16 {
130 let v: &[i16; 2] = bytemuck::cast_ref(&self.var);
133 v[0]
134 }
135
136 #[inline]
137 pub(crate) fn set_attach_chain(&mut self, n: i16) {
138 let v: &mut [i16; 2] = bytemuck::cast_mut(&mut self.var);
139 v[0] = n;
140 }
141
142 #[inline]
143 pub(crate) fn attach_type(&self) -> u8 {
144 let v: &[u8; 4] = bytemuck::cast_ref(&self.var);
147 v[2]
148 }
149
150 #[inline]
151 pub(crate) fn set_attach_type(&mut self, n: u8) {
152 let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var);
153 v[2] = n;
154 }
155}
156
157#[repr(C)]
165#[derive(Clone, Copy, Default, Debug, bytemuck::Pod, bytemuck::Zeroable)]
166pub struct GlyphInfo {
167 pub glyph_id: u32,
174 pub(crate) mask: hb_mask_t,
175 pub cluster: u32,
179 pub(crate) vars: [u32; 2],
180}
181
182#[allow(dead_code)]
183pub(crate) struct buffer_var_shape {
184 pub(crate) width: u8,
185 pub(crate) var_index: u8,
186 pub(crate) index: u8,
187}
188
189impl buffer_var_shape {
190 #[inline]
191 pub fn start(&self) -> u8 {
192 (self.var_index - 1) * 4 + self.index * self.width
193 }
194
195 #[inline]
196 pub fn count(&self) -> u8 {
197 self.width
198 }
199
200 #[inline]
201 pub fn bits(&self) -> u8 {
202 let start = self.start();
203 let end = start + self.count();
204 debug_assert!(end <= 8);
205 ((1u16 << end) - (1u16 << start)) as u8
206 }
207}
208
209macro_rules! declare_buffer_var {
210 ($ty:ty, $var_index:expr, $index:expr, $var_name:ident, $getter:ident, $setter:ident) => {
211 #[allow(dead_code)]
212 pub(crate) const $var_name: buffer_var_shape = buffer_var_shape {
213 width: core::mem::size_of::<$ty>() as u8,
214 var_index: $var_index,
215 index: $index,
216 };
217
218 #[inline]
219 #[allow(dead_code)]
220 pub(crate) fn $getter(&self) -> $ty {
221 const LEN: usize = core::mem::size_of::<u32>() / core::mem::size_of::<$ty>();
222 let v: &[$ty; LEN] = bytemuck::cast_ref(&self.vars[$var_index - 1usize]);
223 v[$index]
224 }
225
226 #[inline]
227 #[allow(dead_code)]
228 pub(crate) fn $setter(&mut self, value: $ty) {
229 const LEN: usize = core::mem::size_of::<u32>() / core::mem::size_of::<$ty>();
230 let v: &mut [$ty; LEN] = bytemuck::cast_mut(&mut self.vars[$var_index - 1usize]);
231 v[$index] = value;
232 }
233 };
234}
235
236macro_rules! declare_buffer_var_alias {
237 ($alias_var:ident, $ty:ty, $var_name:ident, $getter:ident, $setter:ident) => {
238 #[allow(dead_code)]
239 pub(crate) const $var_name: buffer_var_shape = GlyphInfo::$alias_var;
240
241 #[inline]
242 pub(crate) fn $getter(&self) -> $ty {
243 const { assert!(GlyphInfo::$alias_var.width == core::mem::size_of::<$ty>() as u8) };
244 const LEN: usize = core::mem::size_of::<u32>() / core::mem::size_of::<$ty>();
245 let v: &[$ty; LEN] =
246 bytemuck::cast_ref(&self.vars[GlyphInfo::$alias_var.var_index as usize - 1usize]);
247 v[GlyphInfo::$alias_var.index as usize]
248 }
249
250 #[inline]
251 pub(crate) fn $setter(&mut self, value: $ty) {
252 const { assert!(GlyphInfo::$alias_var.width == core::mem::size_of::<$ty>() as u8) };
253 const LEN: usize = core::mem::size_of::<u32>() / core::mem::size_of::<$ty>();
254 let v: &mut [$ty; LEN] = bytemuck::cast_mut(
255 &mut self.vars[GlyphInfo::$alias_var.var_index as usize - 1usize],
256 );
257 v[GlyphInfo::$alias_var.index as usize] = value;
258 }
259 };
260}
261
262impl GlyphInfo {
263 pub fn unsafe_to_break(&self) -> bool {
274 self.mask & UNSAFE_TO_BREAK != 0
275 }
276
277 pub fn unsafe_to_concat(&self) -> bool {
309 self.mask & UNSAFE_TO_CONCAT != 0
310 }
311
312 pub fn safe_to_insert_tatweel(&self) -> bool {
317 self.mask & SAFE_TO_INSERT_TATWEEL != 0
318 }
319
320 #[inline]
321 pub(crate) fn as_codepoint(&self) -> Codepoint {
322 self.glyph_id
323 }
324
325 #[inline]
326 pub(crate) fn as_glyph(&self) -> GlyphId {
327 GlyphId::new(self.glyph_id)
328 }
329
330 #[inline]
331 pub(crate) fn as_gid16(&self) -> Option<GlyphId16> {
332 let gid: u16 = self.glyph_id.try_into().ok()?;
333 Some(gid.into())
334 }
335
336 pub(crate) fn init_unicode_props(&mut self, scratch_flags: &mut hb_buffer_scratch_flags_t) {
337 let u = self.as_codepoint();
338 let gc = u.general_category();
339 let mut props = gc.0 as u16;
340
341 if u >= 0x80 {
342 if u.is_default_ignorable() {
343 props |= UnicodeProps::IGNORABLE.bits();
344 *scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
345
346 match u {
347 0x200C => props |= UnicodeProps::CF_ZWNJ.bits(),
348 0x200D => props |= UnicodeProps::CF_ZWJ.bits(),
349
350 0x180B..=0x180D | 0x180F => props |= UnicodeProps::HIDDEN.bits(),
358
359 0xE0020..=0xE007F => props |= UnicodeProps::HIDDEN.bits(),
362
363 0x034F => {
366 props |= UnicodeProps::HIDDEN.bits();
367 *scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CGJ;
368 }
369
370 _ => {}
371 }
372 }
373
374 if gc.is_mark() {
375 *scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS;
376 props |= UnicodeProps::CONTINUATION.bits();
377 props |= (u.modified_combining_class() as u16) << 8;
378 }
379 }
380
381 self.set_unicode_props(props);
382 }
383
384 #[inline]
385 pub(crate) fn unhide(&mut self) {
386 let mut n = self.unicode_props();
387 n &= !UnicodeProps::HIDDEN.bits();
388 self.set_unicode_props(n);
389 }
390}
391
392pub type hb_buffer_cluster_level_t = u32;
393pub const HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES: u32 = 0;
394pub const HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS: u32 = 1;
395pub const HB_BUFFER_CLUSTER_LEVEL_CHARACTERS: u32 = 2;
396pub const HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES: u32 = 3;
397pub const HB_BUFFER_CLUSTER_LEVEL_DEFAULT: u32 = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES;
398
399pub struct hb_buffer_t {
400 pub flags: BufferFlags,
402 pub cluster_level: hb_buffer_cluster_level_t,
403 pub invisible: Option<GlyphId>,
404 pub not_found_variation_selector: Option<u32>,
405
406 pub direction: Direction,
408 pub script: Option<Script>,
409 pub language: Option<Language>,
410
411 pub successful: bool,
413 pub(crate) have_output: bool,
415 pub have_separate_output: bool,
416 pub have_positions: bool,
418
419 pub idx: usize,
420 pub len: usize,
421 pub out_len: usize,
422
423 pub info: Vec<GlyphInfo>,
424 pub pos: Vec<GlyphPosition>,
425
426 pub context: [[Codepoint; CONTEXT_LENGTH]; 2],
430 pub context_len: [usize; 2],
431
432 pub(crate) digest: hb_set_digest_t,
433 pub(crate) glyph_set: U32Set,
434
435 pub allocated_var_bits: u8,
437 pub serial: u8,
438 pub scratch_flags: hb_buffer_scratch_flags_t,
439 pub max_len: usize,
441 pub max_ops: i32,
443}
444
445impl hb_buffer_t {
446 pub const MAX_LEN_FACTOR: usize = 256;
447 pub const MAX_LEN_MIN: usize = 65536;
448 pub const MAX_LEN_DEFAULT: usize = 0x3FFF_FFFF;
450
451 pub const MAX_OPS_FACTOR: i32 = 4096;
452 pub const MAX_OPS_MIN: i32 = 65536;
453 pub const MAX_OPS_DEFAULT: i32 = 0x1FFF_FFFF;
455
456 pub fn new() -> Self {
458 hb_buffer_t {
459 flags: BufferFlags::empty(),
460 cluster_level: HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
461 invisible: None,
462 scratch_flags: HB_BUFFER_SCRATCH_FLAG_DEFAULT,
463 not_found_variation_selector: None,
464 max_len: Self::MAX_LEN_DEFAULT,
465 max_ops: Self::MAX_OPS_DEFAULT,
466 direction: Direction::Invalid,
467 script: None,
468 language: None,
469 successful: true,
470 have_output: false,
471 have_positions: false,
472 idx: 0,
473 len: 0,
474 out_len: 0,
475 info: Vec::new(),
476 pos: Vec::new(),
477 have_separate_output: false,
478 allocated_var_bits: 0,
479 serial: 0,
480 context: Default::default(),
481 context_len: [0, 0],
482 digest: hb_set_digest_t::new(),
483 glyph_set: U32Set::default(),
484 }
485 }
486
487 #[inline]
488 pub fn allocate_var(&mut self, shape: buffer_var_shape) {
489 let bits = shape.bits();
490 debug_assert_eq!(
491 self.allocated_var_bits & bits,
492 0,
493 "Variable already allocated"
494 );
495 self.allocated_var_bits |= bits;
496 }
497
498 #[inline]
499 pub fn try_allocate_var(&mut self, shape: buffer_var_shape) -> bool {
500 let bits = shape.bits();
501 if self.allocated_var_bits & bits != 0 {
502 return false;
503 }
504 self.allocated_var_bits |= bits;
505 true
506 }
507
508 #[inline]
509 pub fn deallocate_var(&mut self, shape: buffer_var_shape) {
510 let bits = shape.bits();
511 debug_assert_eq!(
512 self.allocated_var_bits & bits,
513 bits,
514 "Deallocating unallocated var"
515 );
516 self.allocated_var_bits &= !bits;
517 }
518
519 #[inline]
520 pub fn assert_var(&self, shape: buffer_var_shape) {
521 let bits = shape.bits();
522 debug_assert_eq!(
523 self.allocated_var_bits & bits,
524 bits,
525 "Variable not allocated"
526 );
527 }
528
529 #[inline]
530 pub fn info_slice_mut(&mut self) -> &mut [GlyphInfo] {
531 &mut self.info[..self.len]
532 }
533
534 #[inline]
535 pub fn out_info(&self) -> &[GlyphInfo] {
536 if self.have_separate_output {
537 bytemuck::cast_slice(self.pos.as_slice())
538 } else {
539 &self.info
540 }
541 }
542
543 #[inline]
544 pub fn out_info_mut(&mut self) -> &mut [GlyphInfo] {
545 if self.have_separate_output {
546 bytemuck::cast_slice_mut(self.pos.as_mut_slice())
547 } else {
548 &mut self.info
549 }
550 }
551
552 #[inline]
553 fn set_out_info(&mut self, i: usize, info: GlyphInfo) {
554 self.out_info_mut()[i] = info;
555 }
556
557 #[inline]
558 pub fn cur(&self, i: usize) -> &GlyphInfo {
559 &self.info[self.idx + i]
560 }
561
562 #[inline]
563 pub fn cur_mut(&mut self, i: usize) -> &mut GlyphInfo {
564 let idx = self.idx + i;
565 &mut self.info[idx]
566 }
567
568 #[inline]
569 pub fn cur_pos_mut(&mut self) -> &mut GlyphPosition {
570 let i = self.idx;
571 &mut self.pos[i]
572 }
573
574 #[inline]
575 pub fn prev(&self) -> &GlyphInfo {
576 let idx = self.out_len.saturating_sub(1);
577 &self.out_info()[idx]
578 }
579
580 #[inline]
581 pub fn prev_mut(&mut self) -> &mut GlyphInfo {
582 let idx = self.out_len.saturating_sub(1);
583 &mut self.out_info_mut()[idx]
584 }
585
586 pub fn update_digest(&mut self) {
587 self.digest = hb_set_digest_t::new();
588 self.digest.add_array(self.info.iter().map(|i| i.glyph_id));
589 }
590 pub fn update_glyph_set(&mut self) {
591 self.glyph_set.clear();
592 self.glyph_set
593 .extend_unsorted(self.info.iter().map(|i| i.glyph_id));
594 }
595
596 fn clear(&mut self) {
597 self.direction = Direction::Invalid;
598 self.script = None;
599 self.language = None;
600
601 self.successful = true;
602 self.have_output = false;
603 self.have_positions = false;
604
605 self.idx = 0;
606 self.info.clear();
607 self.pos.clear();
608 self.len = 0;
609 self.out_len = 0;
610 self.have_separate_output = false;
611
612 self.context = Default::default();
613 self.context_len = [0, 0];
614
615 self.serial = 0;
616 self.scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
617 self.cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT;
618 self.not_found_variation_selector = None;
619 }
620
621 #[inline]
622 pub fn backtrack_len(&self) -> usize {
623 if self.have_output {
624 self.out_len
625 } else {
626 self.idx
627 }
628 }
629
630 #[inline]
631 pub fn lookahead_len(&self) -> usize {
632 self.len - self.idx
633 }
634
635 #[inline]
636 fn next_serial(&mut self) -> u8 {
637 self.serial = self.serial.wrapping_add(1);
639
640 if self.serial == 0 {
641 self.serial += 1;
642 }
643
644 self.serial
645 }
646
647 fn add(&mut self, codepoint: u32, cluster: u32) {
648 if !self.ensure(self.len + 1) {
649 return;
650 }
651 self.info[self.len] = GlyphInfo {
652 glyph_id: codepoint,
653 cluster,
654 ..GlyphInfo::default()
655 };
656 self.len += 1;
657 }
658
659 #[inline]
660 pub fn reverse(&mut self) {
661 if self.is_empty() {
662 return;
663 }
664
665 self.reverse_range(0, self.len);
666 }
667
668 pub fn reverse_range(&mut self, start: usize, end: usize) {
669 if end - start < 2 {
670 return;
671 }
672
673 self.info[start..end].reverse();
674 if self.have_positions {
675 self.pos[start..end].reverse();
676 }
677 }
678
679 pub fn reverse_groups<F>(&mut self, group: F, merge_clusters: bool)
680 where
681 F: Fn(&GlyphInfo, &GlyphInfo) -> bool,
682 {
683 if self.is_empty() {
684 return;
685 }
686
687 let mut start = 0;
688 let mut i = 1;
689
690 while i < self.len {
691 if !group(&self.info[i - 1], &self.info[i]) {
692 if merge_clusters {
693 self.merge_clusters(start, i);
694 }
695
696 self.reverse_range(start, i);
697 start = i;
698 }
699
700 i += 1;
701 }
702
703 if merge_clusters {
704 self.merge_clusters(start, i);
705 }
706
707 self.reverse_range(start, i);
708
709 self.reverse();
710 }
711
712 pub fn group_end<F>(&self, mut start: usize, group: F) -> usize
713 where
714 F: Fn(&GlyphInfo, &GlyphInfo) -> bool,
715 {
716 start += 1;
717
718 while start < self.len && group(&self.info[start - 1], &self.info[start]) {
719 start += 1;
720 }
721
722 start
723 }
724
725 #[inline]
726 fn reset_clusters(&mut self) {
727 for (i, info) in self.info.iter_mut().enumerate() {
728 info.cluster = i as u32;
729 }
730 }
731
732 pub fn guess_segment_properties(&mut self) {
733 if self.script.is_none() {
734 for info in &self.info {
735 match info.as_codepoint().script() {
736 script::COMMON | script::INHERITED | script::UNKNOWN => {}
737 s => {
738 self.script = Some(s);
739 break;
740 }
741 }
742 }
743 }
744
745 if self.direction == Direction::Invalid {
746 if let Some(script) = self.script {
747 self.direction = Direction::from_script(script).unwrap_or_default();
748 }
749
750 if self.direction == Direction::Invalid {
751 self.direction = Direction::LeftToRight;
752 }
753 }
754
755 }
757
758 pub fn sync(&mut self) -> bool {
759 debug_assert!(self.have_output);
760 debug_assert!(self.idx <= self.len);
761
762 if !self.successful {
763 self.have_output = false;
764 self.out_len = 0;
765 self.idx = 0;
766 return false;
767 }
768
769 self.next_glyphs(self.len - self.idx);
770
771 if self.have_separate_output {
772 let info: Vec<GlyphPosition> = bytemuck::cast_vec(core::mem::take(&mut self.info));
774 let pos: Vec<GlyphInfo> = bytemuck::cast_vec(core::mem::take(&mut self.pos));
775 self.pos = info;
776 self.info = pos;
777 self.have_separate_output = false;
778 }
779
780 self.len = self.out_len;
781
782 self.have_output = false;
783 self.out_len = 0;
784 self.idx = 0;
785 true
786 }
787
788 pub fn clear_output(&mut self) {
789 self.have_output = true;
790 self.have_positions = false;
791
792 self.idx = 0;
793 self.out_len = 0;
794 self.have_separate_output = false;
795 }
796
797 pub fn clear_positions(&mut self) {
798 self.have_output = false;
799 self.have_positions = true;
800
801 self.out_len = 0;
802 self.have_separate_output = false;
803
804 for pos in &mut self.pos {
805 *pos = GlyphPosition::default();
806 }
807 }
808
809 pub fn replace_glyphs(&mut self, num_in: usize, num_out: usize, glyph_data: &[u32]) {
810 if !self.make_room_for(num_in, num_out) {
811 return;
812 }
813
814 debug_assert!(self.idx + num_in <= self.len);
815
816 self.merge_clusters(self.idx, self.idx + num_in);
817
818 let orig_info = self.info[self.idx];
819 for i in 0..num_out {
820 let ii = self.out_len + i;
821 self.set_out_info(ii, orig_info);
822 self.out_info_mut()[ii].glyph_id = glyph_data[i];
823 }
824
825 self.idx += num_in;
826 self.out_len += num_out;
827 }
828
829 pub fn replace_glyph(&mut self, glyph_index: u32) {
830 if self.have_separate_output || self.out_len != self.idx {
831 if !self.make_room_for(1, 1) {
832 return;
833 }
834
835 self.set_out_info(self.out_len, self.info[self.idx]);
836 }
837
838 let out_len = self.out_len;
839 self.out_info_mut()[out_len].glyph_id = glyph_index;
840
841 self.idx += 1;
842 self.out_len += 1;
843 }
844
845 pub fn output_glyph(&mut self, glyph_index: u32) {
846 if !self.make_room_for(0, 1) {
847 return;
848 }
849
850 if self.idx == self.len && self.out_len == 0 {
851 return;
852 }
853
854 let out_len = self.out_len;
855 if self.idx < self.len {
856 self.set_out_info(out_len, self.info[self.idx]);
857 } else {
858 let info = self.out_info()[out_len - 1];
859 self.set_out_info(out_len, info);
860 }
861
862 self.out_info_mut()[out_len].glyph_id = glyph_index;
863
864 self.out_len += 1;
865 }
866
867 pub fn output_info(&mut self, glyph_info: GlyphInfo) {
868 if !self.make_room_for(0, 1) {
869 return;
870 }
871
872 self.set_out_info(self.out_len, glyph_info);
873 self.out_len += 1;
874 }
875
876 pub fn copy_glyph(&mut self) {
878 if !self.make_room_for(0, 1) {
879 return;
880 }
881
882 self.set_out_info(self.out_len, self.info[self.idx]);
883 self.out_len += 1;
884 }
885
886 #[inline(always)]
890 pub fn next_glyph(&mut self) {
891 if self.have_output {
892 if self.have_separate_output || self.out_len != self.idx {
893 if !self.ensure(self.out_len + 1) {
894 return;
895 }
896
897 let i = self.out_len;
898 self.out_info_mut()[i] = self.info[self.idx];
899 }
900
901 self.out_len += 1;
902 }
903
904 self.idx += 1;
905 }
906
907 pub fn next_glyphs(&mut self, n: usize) {
911 if self.have_output {
912 if self.have_separate_output || self.out_len != self.idx {
913 if !self.ensure(self.out_len + n) {
914 return;
915 }
916
917 for i in 0..n {
918 self.set_out_info(self.out_len + i, self.info[self.idx + i]);
919 }
920 }
921
922 self.out_len += n;
923 }
924
925 self.idx += n;
926 }
927
928 pub fn skip_glyph(&mut self) {
930 self.idx += 1;
931 }
932
933 pub fn reset_masks(&mut self, mask: hb_mask_t) {
934 for info in &mut self.info[..self.len] {
935 info.mask = mask;
936 }
937 }
938
939 pub fn set_masks(
940 &mut self,
941 mut value: hb_mask_t,
942 mask: hb_mask_t,
943 cluster_start: u32,
944 cluster_end: u32,
945 ) {
946 if mask == 0 {
947 return;
948 }
949
950 let not_mask = !mask;
951 value &= mask;
952
953 self.max_ops -= self.len as i32;
954 if self.max_ops < 0 {
955 self.successful = false;
956 }
957
958 if cluster_start == 0 && cluster_end == u32::MAX {
959 for info in &mut self.info[..self.len] {
960 info.mask = (info.mask & not_mask) | value;
961 }
962
963 return;
964 }
965
966 for info in &mut self.info[..self.len] {
967 if cluster_start <= info.cluster && info.cluster < cluster_end {
968 info.mask = (info.mask & not_mask) | value;
969 }
970 }
971 }
972
973 #[inline(always)]
974 pub fn merge_clusters(&mut self, start: usize, end: usize) {
975 if end - start < 2 {
976 return;
977 }
978
979 self.merge_clusters_impl(start, end);
980 }
981
982 fn merge_clusters_impl(&mut self, mut start: usize, mut end: usize) {
983 if !BufferClusterLevel::new(self.cluster_level).is_monotone() {
984 self.unsafe_to_break(Some(start), Some(end));
985 return;
986 }
987
988 self.max_ops -= (end - start) as i32;
989 if self.max_ops < 0 {
990 self.successful = false;
991 }
992
993 let cluster = self.info[start..end]
994 .iter()
995 .map(|info| info.cluster)
996 .min()
997 .unwrap();
998
999 if cluster != self.info[end - 1].cluster {
1001 while end < self.len && self.info[end - 1].cluster == self.info[end].cluster {
1002 end += 1;
1003 }
1004 }
1005
1006 if cluster != self.info[start].cluster {
1008 while end < start && self.info[start - 1].cluster == self.info[start].cluster {
1009 start -= 1;
1010 }
1011 }
1012
1013 if self.idx == start && self.info[start].cluster != cluster {
1015 let mut i = self.out_len;
1016 while i != 0 && self.out_info()[i - 1].cluster == self.info[start].cluster {
1017 Self::set_cluster(&mut self.out_info_mut()[i - 1], cluster, 0);
1018 i -= 1;
1019 }
1020 }
1021
1022 for info in &mut self.info[start..end] {
1023 Self::set_cluster(info, cluster, 0);
1024 }
1025 }
1026
1027 pub fn merge_out_clusters(&mut self, mut start: usize, mut end: usize) {
1028 if !BufferClusterLevel::new(self.cluster_level).is_monotone() {
1029 return;
1030 }
1031
1032 if end - start < 2 {
1033 return;
1034 }
1035
1036 self.max_ops -= (end - start) as i32;
1037 if self.max_ops < 0 {
1038 self.successful = false;
1039 }
1040
1041 let cluster = self.out_info()[start..end]
1042 .iter()
1043 .map(|info| info.cluster)
1044 .min()
1045 .unwrap();
1046
1047 while start != 0 && self.out_info()[start - 1].cluster == self.out_info()[start].cluster {
1049 start -= 1;
1050 }
1051
1052 while end < self.out_len && self.out_info()[end - 1].cluster == self.out_info()[end].cluster
1054 {
1055 end += 1;
1056 }
1057
1058 if end == self.out_len {
1060 let mut i = self.idx;
1061 while i < self.len && self.info[i].cluster == self.out_info()[end - 1].cluster {
1062 Self::set_cluster(&mut self.info[i], cluster, 0);
1063 i += 1;
1064 }
1065 }
1066
1067 for info in &mut self.out_info_mut()[start..end] {
1068 Self::set_cluster(info, cluster, 0);
1069 }
1070 }
1071
1072 pub fn delete_glyph(&mut self) {
1074 let cluster = self.info[self.idx].cluster;
1075
1076 if (self.idx + 1 < self.len && cluster == self.info[self.idx + 1].cluster)
1077 || (self.out_len != 0 && cluster == self.out_info()[self.out_len - 1].cluster)
1078 {
1079 self.skip_glyph();
1081 return;
1082 }
1083
1084 if self.out_len != 0 {
1085 if cluster < self.out_info()[self.out_len - 1].cluster {
1087 let mask = self.info[self.idx].mask;
1088 let old_cluster = self.out_info()[self.out_len - 1].cluster;
1089
1090 let mut i = self.out_len;
1091 while i != 0 && self.out_info()[i - 1].cluster == old_cluster {
1092 Self::set_cluster(&mut self.out_info_mut()[i - 1], cluster, mask);
1093 i -= 1;
1094 }
1095 }
1096
1097 self.skip_glyph();
1098 return;
1099 }
1100
1101 if self.idx + 1 < self.len {
1102 self.merge_clusters(self.idx, self.idx + 2);
1104 }
1105
1106 self.skip_glyph();
1107 }
1108
1109 pub fn delete_glyphs_inplace(&mut self, filter: impl Fn(&GlyphInfo) -> bool) {
1110 let mut j = 0;
1113
1114 for i in 0..self.len {
1115 if filter(&self.info[i]) {
1116 let cluster = self.info[i].cluster;
1120 if i + 1 < self.len && cluster == self.info[i + 1].cluster {
1121 continue;
1123 }
1124
1125 if j != 0 {
1126 if cluster < self.info[j - 1].cluster {
1128 let mask = self.info[i].mask;
1129 let old_cluster = self.info[j - 1].cluster;
1130
1131 let mut k = j;
1132 while k > 0 && self.info[k - 1].cluster == old_cluster {
1133 Self::set_cluster(&mut self.info[k - 1], cluster, mask);
1134 k -= 1;
1135 }
1136 }
1137 continue;
1138 }
1139
1140 if i + 1 < self.len {
1141 self.merge_clusters(i, i + 2);
1143 }
1144
1145 continue;
1146 }
1147
1148 if j != i {
1149 self.info[j] = self.info[i];
1150 self.pos[j] = self.pos[i];
1151 }
1152
1153 j += 1;
1154 }
1155
1156 self.len = j;
1157 }
1158
1159 pub fn unsafe_to_break(&mut self, start: Option<usize>, end: Option<usize>) {
1160 self._set_glyph_flags(
1161 UNSAFE_TO_BREAK | UNSAFE_TO_CONCAT,
1162 start,
1163 end,
1164 Some(true),
1165 None,
1166 );
1167 }
1168
1169 pub fn safe_to_insert_tatweel(&mut self, start: Option<usize>, end: Option<usize>) {
1170 if !self
1171 .flags
1172 .contains(BufferFlags::PRODUCE_SAFE_TO_INSERT_TATWEEL)
1173 {
1174 self.unsafe_to_break(start, end);
1175 return;
1176 }
1177
1178 self._set_glyph_flags(SAFE_TO_INSERT_TATWEEL, start, end, Some(true), None);
1179 }
1180
1181 fn _set_glyph_flags_impl(
1182 &mut self,
1183 mask: hb_mask_t,
1184 start: usize,
1185 end: usize,
1186 interior: bool,
1187 from_out_buffer: bool,
1188 ) {
1189 if !from_out_buffer || !self.have_output {
1190 if !interior {
1191 for info in &mut self.info[start..end] {
1192 info.mask |= mask;
1193 }
1194 } else {
1195 let cluster = self._infos_find_min_cluster(&self.info, start, end, None);
1196 self._infos_set_glyph_flags(false, start, end, cluster, mask);
1197 }
1198 } else {
1199 debug_assert!(start <= self.out_len);
1200 debug_assert!(self.idx <= end);
1201
1202 if !interior {
1203 let range_end = self.out_len;
1204 for info in &mut self.out_info_mut()[start..range_end] {
1205 info.mask |= mask;
1206 }
1207
1208 for info in &mut self.info[self.idx..end] {
1209 info.mask |= mask;
1210 }
1211 } else {
1212 let mut cluster = self._infos_find_min_cluster(&self.info, self.idx, end, None);
1213 cluster = self._infos_find_min_cluster(
1214 self.out_info(),
1215 start,
1216 self.out_len,
1217 Some(cluster),
1218 );
1219
1220 let out_len = self.out_len;
1221 self._infos_set_glyph_flags(true, start, out_len, cluster, mask);
1222 self._infos_set_glyph_flags(false, self.idx, end, cluster, mask);
1223 }
1224 }
1225 }
1226
1227 fn _set_glyph_flags(
1231 &mut self,
1232 mask: hb_mask_t,
1233 start: Option<usize>,
1234 end: Option<usize>,
1235 interior: Option<bool>,
1236 from_out_buffer: Option<bool>,
1237 ) {
1238 if let (Some(start), Some(end)) = (start, end) {
1241 if end.wrapping_sub(start) > 255 {
1242 return;
1243 }
1244 }
1245
1246 let start = start.unwrap_or(0);
1247 let end = min(end.unwrap_or(self.len), self.len);
1248 let interior = interior.unwrap_or(false);
1249 let from_out_buffer = from_out_buffer.unwrap_or(false);
1250
1251 if interior && !from_out_buffer && end - start < 2 {
1252 return;
1253 }
1254
1255 self._set_glyph_flags_impl(mask, start, end, interior, from_out_buffer);
1256 }
1257
1258 pub fn unsafe_to_concat(&mut self, start: Option<usize>, end: Option<usize>) {
1259 if !self.flags.contains(BufferFlags::PRODUCE_UNSAFE_TO_CONCAT) {
1260 return;
1261 }
1262
1263 self._set_glyph_flags(UNSAFE_TO_CONCAT, start, end, Some(false), None);
1264 }
1265
1266 pub fn unsafe_to_break_from_outbuffer(&mut self, start: Option<usize>, end: Option<usize>) {
1267 self._set_glyph_flags(
1268 UNSAFE_TO_BREAK | UNSAFE_TO_CONCAT,
1269 start,
1270 end,
1271 Some(true),
1272 Some(true),
1273 );
1274 }
1275
1276 pub fn unsafe_to_concat_from_outbuffer(&mut self, start: Option<usize>, end: Option<usize>) {
1277 if !self.flags.contains(BufferFlags::PRODUCE_UNSAFE_TO_CONCAT) {
1278 return;
1279 }
1280
1281 self._set_glyph_flags(UNSAFE_TO_CONCAT, start, end, Some(false), Some(true));
1282 }
1283
1284 pub fn move_to(&mut self, i: usize) -> bool {
1285 if !self.have_output {
1286 debug_assert!(i <= self.len);
1287 self.idx = i;
1288 return true;
1289 }
1290
1291 if !self.successful {
1292 return false;
1293 }
1294
1295 debug_assert!(i <= self.out_len + (self.len - self.idx));
1296
1297 if self.out_len < i {
1298 let count = i - self.out_len;
1299 if !self.make_room_for(count, count) {
1300 return false;
1301 }
1302
1303 for j in 0..count {
1304 self.set_out_info(self.out_len + j, self.info[self.idx + j]);
1305 }
1306
1307 self.idx += count;
1308 self.out_len += count;
1309 } else if self.out_len > i {
1310 let count = self.out_len - i;
1312
1313 if self.idx < count && !self.shift_forward(count - self.idx) {
1321 return false;
1322 }
1323
1324 debug_assert!(self.idx >= count);
1325
1326 self.idx -= count;
1327 self.out_len -= count;
1328
1329 for j in 0..count {
1330 self.info[self.idx + j] = self.out_info()[self.out_len + j];
1331 }
1332 }
1333
1334 true
1335 }
1336
1337 #[must_use]
1338 #[inline(always)]
1339 pub fn ensure(&mut self, size: usize) -> bool {
1340 if size <= self.info.len() {
1341 true
1342 } else {
1343 self.enlarge(size)
1344 }
1345 }
1346
1347 #[must_use]
1348 fn enlarge(&mut self, size: usize) -> bool {
1349 if size > self.max_len {
1350 self.successful = false;
1351 return false;
1352 }
1353
1354 self.info.resize(size, GlyphInfo::default());
1355 self.pos.resize(size, GlyphPosition::default());
1356 true
1357 }
1358
1359 #[must_use]
1360 fn make_room_for(&mut self, num_in: usize, num_out: usize) -> bool {
1361 if !self.ensure(self.out_len + num_out) {
1362 return false;
1363 }
1364
1365 if !self.have_separate_output && self.out_len + num_out > self.idx + num_in {
1366 debug_assert!(self.have_output);
1367
1368 self.have_separate_output = true;
1369 for i in 0..self.out_len {
1370 self.set_out_info(i, self.info[i]);
1371 }
1372 }
1373
1374 true
1375 }
1376
1377 fn shift_forward(&mut self, count: usize) -> bool {
1378 debug_assert!(self.have_output);
1379 if !self.ensure(self.len + count) {
1380 return false;
1381 }
1382
1383 self.max_ops -= (self.len - self.idx) as i32;
1384 if self.max_ops < 0 {
1385 self.successful = false;
1386 return false;
1387 }
1388
1389 for i in (0..(self.len - self.idx)).rev() {
1390 self.info[self.idx + count + i] = self.info[self.idx + i];
1391 }
1392
1393 if self.idx + count > self.len {
1394 for info in &mut self.info[self.len..self.idx + count] {
1395 *info = GlyphInfo::default();
1396 }
1397 }
1398
1399 self.len += count;
1400 self.idx += count;
1401
1402 true
1403 }
1404
1405 fn clear_context(&mut self, side: usize) {
1406 self.context_len[side] = 0;
1407 }
1408
1409 pub fn sort(&mut self, start: usize, end: usize, cmp: impl Fn(&GlyphInfo, &GlyphInfo) -> bool) {
1410 debug_assert!(!self.have_positions);
1411
1412 for i in start + 1..end {
1413 let mut j = i;
1414 while j > start && cmp(&self.info[j - 1], &self.info[i]) {
1415 j -= 1;
1416 }
1417
1418 if i == j {
1419 continue;
1420 }
1421
1422 self.merge_clusters(j, i + 1);
1424
1425 {
1426 let t = self.info[i];
1427 for idx in (0..i - j).rev() {
1428 self.info[idx + j + 1] = self.info[idx + j];
1429 }
1430
1431 self.info[j] = t;
1432 }
1433 }
1434 }
1435
1436 pub fn set_cluster(info: &mut GlyphInfo, cluster: u32, mask: hb_mask_t) {
1437 if info.cluster != cluster {
1438 info.mask = (info.mask & !glyph_flag::DEFINED) | (mask & glyph_flag::DEFINED);
1439 }
1440
1441 info.cluster = cluster;
1442 }
1443
1444 pub(crate) fn enter(&mut self) {
1446 self.serial = 0;
1447 self.scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
1448
1449 if let Some(len) = self.len.checked_mul(hb_buffer_t::MAX_LEN_FACTOR) {
1450 self.max_len = len.max(hb_buffer_t::MAX_LEN_MIN);
1451 }
1452
1453 if let Ok(len) = i32::try_from(self.len) {
1454 if let Some(ops) = len.checked_mul(hb_buffer_t::MAX_OPS_FACTOR) {
1455 self.max_ops = ops.max(hb_buffer_t::MAX_OPS_MIN);
1456 }
1457 }
1458 }
1459
1460 pub(crate) fn leave(&mut self) {
1462 self.max_len = hb_buffer_t::MAX_LEN_DEFAULT;
1463 self.max_ops = hb_buffer_t::MAX_OPS_DEFAULT;
1464 self.serial = 0;
1465 }
1466
1467 fn _infos_find_min_cluster(
1468 &self,
1469 info: &[GlyphInfo],
1470 start: usize,
1471 end: usize,
1472 cluster: Option<u32>,
1473 ) -> u32 {
1474 let mut cluster = cluster.unwrap_or(u32::MAX);
1475
1476 if start == end {
1477 return cluster;
1478 }
1479
1480 if self.cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS {
1481 for glyph_info in &info[start..end] {
1482 cluster = min(cluster, glyph_info.cluster);
1483 }
1484 }
1485
1486 cluster.min(info[start].cluster.min(info[end - 1].cluster))
1487 }
1488
1489 #[inline(always)]
1490 fn _infos_set_glyph_flags(
1491 &mut self,
1492 out_info: bool,
1493 start: usize,
1494 end: usize,
1495 cluster: u32,
1496 mask: hb_mask_t,
1497 ) {
1498 if start == end {
1499 return;
1500 }
1501
1502 let cluster_level = self.cluster_level;
1503
1504 let infos = if out_info {
1505 self.out_info_mut()
1506 } else {
1507 self.info.as_mut_slice()
1508 };
1509
1510 let cluster_first = infos[start].cluster;
1511 let cluster_last = infos[end - 1].cluster;
1512
1513 if cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS
1514 || (cluster != cluster_first && cluster != cluster_last)
1515 {
1516 for info in &mut infos[start..end] {
1517 if info.cluster != cluster {
1518 info.mask |= mask;
1519 }
1520 }
1521
1522 return;
1523 }
1524
1525 if cluster == cluster_first {
1527 let mut i = end;
1528 while start < i && infos[i - 1].cluster != cluster_first {
1529 if cluster != infos[i - 1].cluster {
1530 infos[i - 1].mask |= mask;
1531 }
1532
1533 i -= 1;
1534 }
1535 } else {
1536 let mut i = start;
1537 while i < end && infos[i].cluster != cluster_last {
1538 if cluster != infos[i].cluster {
1539 infos[i].mask |= mask;
1540 }
1541
1542 i += 1;
1543 }
1544 }
1545 }
1546
1547 pub fn is_empty(&self) -> bool {
1549 self.len == 0
1550 }
1551
1552 fn push_str(&mut self, text: &str) {
1553 if !self.ensure(self.len + text.chars().count()) {
1554 return;
1555 }
1556
1557 for (i, c) in text.char_indices() {
1558 self.info[self.len] = GlyphInfo {
1559 glyph_id: c as u32,
1560 cluster: i as u32,
1561 ..GlyphInfo::default()
1562 };
1563 self.len += 1;
1564 }
1565 }
1566
1567 fn set_pre_context(&mut self, text: &str) {
1568 self.clear_context(0);
1569 for (i, c) in text.chars().rev().enumerate().take(CONTEXT_LENGTH) {
1570 self.context[0][i] = c as Codepoint;
1571 self.context_len[0] += 1;
1572 }
1573 }
1574
1575 fn set_post_context(&mut self, text: &str) {
1576 self.clear_context(1);
1577 for (i, c) in text.chars().enumerate().take(CONTEXT_LENGTH) {
1578 self.context[1][i] = c as Codepoint;
1579 self.context_len[1] += 1;
1580 }
1581 }
1582
1583 pub fn next_syllable(&self, mut start: usize) -> usize {
1584 if start >= self.len {
1585 return start;
1586 }
1587
1588 let syllable = self.info[start].syllable();
1589 start += 1;
1590 while start < self.len && syllable == self.info[start].syllable() {
1591 start += 1;
1592 }
1593
1594 start
1595 }
1596
1597 #[inline]
1598 pub fn allocate_lig_id(&mut self) -> u8 {
1599 let mut lig_id = self.next_serial() & 0x07;
1600
1601 if lig_id == 0 {
1602 lig_id = self.allocate_lig_id();
1603 }
1604
1605 lig_id
1606 }
1607}
1608
1609pub(crate) fn _cluster_group_func(a: &GlyphInfo, b: &GlyphInfo) -> bool {
1610 a.cluster == b.cluster
1611}
1612
1613macro_rules! foreach_cluster {
1616 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {
1617 foreach_group!($buffer, $start, $end, $crate::hb::buffer::_cluster_group_func, $($body)*)
1618 };
1619}
1620
1621macro_rules! foreach_group {
1622 ($buffer:expr, $start:ident, $end:ident, $group_func:expr, $($body:tt)*) => {{
1623 let count = $buffer.len;
1624 let mut $start = 0;
1625 let mut $end = if count > 0 { $buffer.group_end(0, $group_func) } else { 0 };
1626
1627 while $start < count {
1628 $($body)*;
1629 $start = $end;
1630 $end = $buffer.group_end($start, $group_func);
1631 }
1632 }};
1633}
1634
1635macro_rules! foreach_syllable {
1636 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {{
1637 let mut $start = 0;
1638 let mut $end = $buffer.next_syllable(0);
1639 while $start < $buffer.len {
1640 $($body)*;
1641 $start = $end;
1642 $end = $buffer.next_syllable($start);
1643 }
1644 }};
1645}
1646
1647macro_rules! foreach_grapheme {
1648 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {
1649 foreach_group!($buffer, $start, $end, $crate::hb::ot_layout::_hb_grapheme_group_func, $($body)*)
1650 };
1651}
1652
1653bitflags::bitflags! {
1654 #[derive(Default, Debug, Clone, Copy)]
1655 pub struct UnicodeProps: u16 {
1656 const GENERAL_CATEGORY = 0x001F;
1657 const IGNORABLE = 0x0020;
1658 const HIDDEN = 0x0040;
1660 const CONTINUATION = 0x0080;
1661
1662 const CF_ZWJ = 0x0100;
1664 const CF_ZWNJ = 0x0200;
1665 const CF_VS = 0x0400;
1666 const CF_AAT_DELETED = 0x0800;
1667 }
1668}
1669
1670bitflags::bitflags! {
1671 #[derive(Default, Debug, Clone, Copy)]
1672 pub struct GlyphPropsFlags: u16 {
1673 const BASE_GLYPH = 0x02;
1675 const LIGATURE = 0x04;
1676 const MARK = 0x08;
1677 const CLASS_MASK = Self::BASE_GLYPH.bits() | Self::LIGATURE.bits() | Self::MARK.bits();
1678
1679 const MATCHES = 0x10;
1681 const SUBSTITUTED = 0x20;
1682 const LIGATED = 0x40;
1683 const MULTIPLIED = 0x80;
1684
1685 const PRESERVE = Self::SUBSTITUTED.bits() | Self::LIGATED.bits() | Self::MULTIPLIED.bits();
1686 }
1687}
1688
1689pub type hb_buffer_scratch_flags_t = u32;
1690pub const HB_BUFFER_SCRATCH_FLAG_DEFAULT: u32 = 0x0000_0000;
1691pub const HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH: u32 = 0x0000_0001;
1692pub const HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES: u32 = 0x0000_0002;
1693pub const HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK: u32 = 0x0000_0004;
1694pub const HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT: u32 = 0x0000_0008;
1695pub const HB_BUFFER_SCRATCH_FLAG_HAS_CGJ: u32 = 0x0000_0010;
1696pub const HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE: u32 = 0x0000_0020;
1697pub const HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK: u32 = 0x0000_0040;
1698pub const HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS: u32 = 0x0000_0080;
1699
1700pub const HB_BUFFER_SCRATCH_FLAG_SHAPER0: u32 = 0x0100_0000;
1702pub struct UnicodeBuffer(pub(crate) hb_buffer_t);
1708
1709impl UnicodeBuffer {
1710 #[inline]
1712 pub fn new() -> UnicodeBuffer {
1713 UnicodeBuffer(hb_buffer_t::new())
1714 }
1715
1716 #[inline]
1721 pub fn len(&self) -> usize {
1722 self.0.len
1723 }
1724
1725 pub fn reserve(&mut self, size: usize) -> bool {
1727 self.0.ensure(size)
1728 }
1729
1730 #[inline]
1732 pub fn is_empty(&self) -> bool {
1733 self.0.is_empty()
1734 }
1735
1736 #[inline]
1738 pub fn push_str(&mut self, str: &str) {
1739 self.0.push_str(str);
1740 }
1741
1742 #[inline]
1744 pub fn set_pre_context(&mut self, str: &str) {
1745 self.0.set_pre_context(str);
1746 }
1747
1748 #[inline]
1750 pub fn set_post_context(&mut self, str: &str) {
1751 self.0.set_post_context(str);
1752 }
1753
1754 #[inline]
1756 pub fn add(&mut self, codepoint: char, cluster: u32) {
1757 self.0.add(codepoint as u32, cluster);
1758 self.0.context_len[1] = 0;
1759 }
1760
1761 #[inline]
1763 pub fn set_direction(&mut self, direction: Direction) {
1764 self.0.direction = direction;
1765 }
1766
1767 #[inline]
1769 pub fn direction(&self) -> Direction {
1770 self.0.direction
1771 }
1772
1773 #[inline]
1775 pub fn set_script(&mut self, script: Script) {
1776 self.0.script = Some(script);
1777 }
1778
1779 pub fn script(&self) -> Script {
1781 self.0.script.unwrap_or(script::UNKNOWN)
1782 }
1783
1784 #[inline]
1786 pub fn set_language(&mut self, lang: Language) {
1787 self.0.language = Some(lang);
1788 }
1789
1790 #[inline]
1792 pub fn set_not_found_variation_selector_glyph(&mut self, glyph: u32) {
1793 self.0.not_found_variation_selector = Some(glyph);
1794 }
1795
1796 #[inline]
1798 pub fn language(&self) -> Option<Language> {
1799 self.0.language.clone()
1800 }
1801
1802 #[inline]
1805 pub fn guess_segment_properties(&mut self) {
1806 self.0.guess_segment_properties();
1807 }
1808
1809 #[inline]
1811 pub fn set_flags(&mut self, flags: BufferFlags) {
1812 self.0.flags = flags;
1813 }
1814
1815 #[inline]
1817 pub fn flags(&self) -> BufferFlags {
1818 self.0.flags
1819 }
1820
1821 #[inline]
1823 pub fn set_cluster_level(&mut self, cluster_level: BufferClusterLevel) {
1824 self.0.cluster_level = match cluster_level {
1825 BufferClusterLevel::MonotoneGraphemes => HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES,
1826 BufferClusterLevel::MonotoneCharacters => HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS,
1827 BufferClusterLevel::Characters => HB_BUFFER_CLUSTER_LEVEL_CHARACTERS,
1828 BufferClusterLevel::Graphemes => HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES,
1829 }
1830 }
1831
1832 #[inline]
1834 pub fn cluster_level(&self) -> BufferClusterLevel {
1835 match self.0.cluster_level {
1836 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES => BufferClusterLevel::MonotoneGraphemes,
1837 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS => BufferClusterLevel::MonotoneCharacters,
1838 HB_BUFFER_CLUSTER_LEVEL_CHARACTERS => BufferClusterLevel::Characters,
1839 HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES => BufferClusterLevel::Graphemes,
1840 _ => BufferClusterLevel::MonotoneGraphemes,
1841 }
1842 }
1843
1844 #[inline]
1846 pub fn reset_clusters(&mut self) {
1847 self.0.reset_clusters();
1848 }
1849
1850 #[inline]
1852 pub fn clear(&mut self) {
1853 self.0.clear();
1854 }
1855}
1856
1857impl core::fmt::Debug for UnicodeBuffer {
1858 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1859 fmt.debug_struct("UnicodeBuffer")
1860 .field("direction", &self.direction())
1861 .field("language", &self.language())
1862 .field("script", &self.script())
1863 .field("cluster_level", &self.cluster_level())
1864 .finish()
1865 }
1866}
1867
1868impl Default for UnicodeBuffer {
1869 fn default() -> UnicodeBuffer {
1870 UnicodeBuffer::new()
1871 }
1872}
1873
1874pub struct GlyphBuffer(pub(crate) hb_buffer_t);
1876
1877impl GlyphBuffer {
1878 #[inline]
1884 pub fn len(&self) -> usize {
1885 self.0.len
1886 }
1887
1888 #[inline]
1890 pub fn is_empty(&self) -> bool {
1891 self.0.is_empty()
1892 }
1893
1894 #[inline]
1896 pub fn glyph_infos(&self) -> &[GlyphInfo] {
1897 &self.0.info[0..self.0.len]
1898 }
1899
1900 #[inline]
1902 pub fn glyph_positions(&self) -> &[GlyphPosition] {
1903 &self.0.pos[0..self.0.len]
1904 }
1905
1906 #[inline]
1909 pub fn clear(mut self) -> UnicodeBuffer {
1910 self.0.clear();
1911 UnicodeBuffer(self.0)
1912 }
1913
1914 pub fn serialize(&self, face: &crate::Shaper, flags: SerializeFlags) -> String {
1916 self.serialize_impl(face, flags).unwrap_or_default()
1917 }
1918
1919 fn serialize_impl(
1920 &self,
1921 face: &hb_font_t,
1922 flags: SerializeFlags,
1923 ) -> Result<String, core::fmt::Error> {
1924 use core::fmt::Write;
1925
1926 let mut s = String::with_capacity(64);
1927
1928 let info = self.glyph_infos();
1929 let pos = self.glyph_positions();
1930 let mut x = 0;
1931 let mut y = 0;
1932 let names = face.glyph_names();
1933 for (info, pos) in info.iter().zip(pos) {
1934 s.push(if s.is_empty() { '[' } else { '|' });
1935
1936 if !flags.contains(SerializeFlags::NO_GLYPH_NAMES) {
1937 match names.get(info.as_glyph().to_u32()) {
1938 Some(name) => s.push_str(name),
1939 None => write!(&mut s, "gid{}", info.glyph_id)?,
1940 }
1941 } else {
1942 write!(&mut s, "{}", info.glyph_id)?;
1943 }
1944
1945 if !flags.contains(SerializeFlags::NO_CLUSTERS) {
1946 write!(&mut s, "={}", info.cluster)?;
1947 }
1948
1949 if !flags.contains(SerializeFlags::NO_POSITIONS) {
1950 if x + pos.x_offset != 0 || y + pos.y_offset != 0 {
1951 write!(&mut s, "@{},{}", x + pos.x_offset, y + pos.y_offset)?;
1952 }
1953
1954 if !flags.contains(SerializeFlags::NO_ADVANCES) {
1955 write!(&mut s, "+{}", pos.x_advance)?;
1956 if pos.y_advance != 0 {
1957 write!(&mut s, ",{}", pos.y_advance)?;
1958 }
1959 }
1960 }
1961
1962 if flags.contains(SerializeFlags::GLYPH_FLAGS) {
1963 if info.mask & glyph_flag::DEFINED != 0 {
1964 write!(&mut s, "#{:X}", info.mask & glyph_flag::DEFINED)?;
1965 }
1966 }
1967
1968 if flags.contains(SerializeFlags::GLYPH_EXTENTS) {
1969 let mut extents = hb_glyph_extents_t::default();
1970 face.glyph_extents(info.as_glyph(), &mut extents);
1971 write!(
1972 &mut s,
1973 "<{},{},{},{}>",
1974 extents.x_bearing, extents.y_bearing, extents.width, extents.height
1975 )?;
1976 }
1977
1978 if flags.contains(SerializeFlags::NO_ADVANCES) {
1979 x += pos.x_advance;
1980 y += pos.y_advance;
1981 }
1982 }
1983
1984 if !s.is_empty() {
1985 s.push(']');
1986 }
1987
1988 Ok(s)
1989 }
1990}
1991
1992impl core::fmt::Debug for GlyphBuffer {
1993 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1994 fmt.debug_struct("GlyphBuffer")
1995 .field("glyph_positions", &self.glyph_positions())
1996 .field("glyph_infos", &self.glyph_infos())
1997 .finish()
1998 }
1999}