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 if !BufferClusterLevel::new(self.cluster_level).is_monotone() {
980 self.unsafe_to_break(Some(start), Some(end));
981 return;
982 }
983
984 self.merge_clusters_impl(start, end);
985 }
986
987 fn merge_clusters_impl(&mut self, mut start: usize, mut end: usize) {
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 self.idx < 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_grapheme_clusters(&mut self, start: usize, end: usize) {
1028 if end - start < 2 {
1029 return;
1030 }
1031
1032 if !BufferClusterLevel::new(self.cluster_level).is_graphemes() {
1033 self.unsafe_to_break(Some(start), Some(end));
1034 return;
1035 }
1036
1037 self.merge_clusters_impl(start, end);
1038 }
1039
1040 pub fn merge_out_clusters(&mut self, start: usize, end: usize) {
1041 if end - start < 2 {
1042 return;
1043 }
1044
1045 if !BufferClusterLevel::new(self.cluster_level).is_monotone() {
1046 return;
1047 }
1048
1049 self.merge_out_clusters_impl(start, end);
1050 }
1051
1052 pub fn merge_out_grapheme_clusters(&mut self, start: usize, end: usize) {
1053 if end - start < 2 {
1054 return;
1055 }
1056
1057 if !BufferClusterLevel::new(self.cluster_level).is_graphemes() {
1058 return;
1059 }
1060
1061 self.merge_out_clusters_impl(start, end);
1062 }
1063
1064 fn merge_out_clusters_impl(&mut self, mut start: usize, mut end: usize) {
1065 self.max_ops -= (end - start) as i32;
1066 if self.max_ops < 0 {
1067 self.successful = false;
1068 }
1069
1070 let cluster = self.out_info()[start..end]
1071 .iter()
1072 .map(|info| info.cluster)
1073 .min()
1074 .unwrap();
1075
1076 while start != 0 && self.out_info()[start - 1].cluster == self.out_info()[start].cluster {
1078 start -= 1;
1079 }
1080
1081 while end < self.out_len && self.out_info()[end - 1].cluster == self.out_info()[end].cluster
1083 {
1084 end += 1;
1085 }
1086
1087 if end == self.out_len {
1089 let mut i = self.idx;
1090 while i < self.len && self.info[i].cluster == self.out_info()[end - 1].cluster {
1091 Self::set_cluster(&mut self.info[i], cluster, 0);
1092 i += 1;
1093 }
1094 }
1095
1096 for info in &mut self.out_info_mut()[start..end] {
1097 Self::set_cluster(info, cluster, 0);
1098 }
1099 }
1100
1101 pub fn delete_glyph(&mut self) {
1103 let cluster = self.info[self.idx].cluster;
1104
1105 if (self.idx + 1 < self.len && cluster == self.info[self.idx + 1].cluster)
1106 || (self.out_len != 0 && cluster == self.out_info()[self.out_len - 1].cluster)
1107 {
1108 self.skip_glyph();
1110 return;
1111 }
1112
1113 if self.out_len != 0 {
1114 if cluster < self.out_info()[self.out_len - 1].cluster {
1116 let mask = self.info[self.idx].mask;
1117 let old_cluster = self.out_info()[self.out_len - 1].cluster;
1118
1119 let mut i = self.out_len;
1120 while i != 0 && self.out_info()[i - 1].cluster == old_cluster {
1121 Self::set_cluster(&mut self.out_info_mut()[i - 1], cluster, mask);
1122 i -= 1;
1123 }
1124 }
1125
1126 self.skip_glyph();
1127 return;
1128 }
1129
1130 if self.idx + 1 < self.len {
1131 self.merge_clusters(self.idx, self.idx + 2);
1133 }
1134
1135 self.skip_glyph();
1136 }
1137
1138 pub fn delete_glyphs_inplace(&mut self, filter: impl Fn(&GlyphInfo) -> bool) {
1139 let mut j = 0;
1142
1143 for i in 0..self.len {
1144 if filter(&self.info[i]) {
1145 let cluster = self.info[i].cluster;
1149 if i + 1 < self.len && cluster == self.info[i + 1].cluster {
1150 continue;
1152 }
1153
1154 if j != 0 {
1155 if cluster < self.info[j - 1].cluster {
1157 let mask = self.info[i].mask;
1158 let old_cluster = self.info[j - 1].cluster;
1159
1160 let mut k = j;
1161 while k > 0 && self.info[k - 1].cluster == old_cluster {
1162 Self::set_cluster(&mut self.info[k - 1], cluster, mask);
1163 k -= 1;
1164 }
1165 }
1166 continue;
1167 }
1168
1169 if i + 1 < self.len {
1170 self.merge_clusters(i, i + 2);
1172 }
1173
1174 continue;
1175 }
1176
1177 if j != i {
1178 self.info[j] = self.info[i];
1179 self.pos[j] = self.pos[i];
1180 }
1181
1182 j += 1;
1183 }
1184
1185 self.len = j;
1186 }
1187
1188 pub fn unsafe_to_break(&mut self, start: Option<usize>, end: Option<usize>) {
1189 self._set_glyph_flags(
1190 UNSAFE_TO_BREAK | UNSAFE_TO_CONCAT,
1191 start,
1192 end,
1193 Some(true),
1194 None,
1195 );
1196 }
1197
1198 pub fn safe_to_insert_tatweel(&mut self, start: Option<usize>, end: Option<usize>) {
1199 if !self
1200 .flags
1201 .contains(BufferFlags::PRODUCE_SAFE_TO_INSERT_TATWEEL)
1202 {
1203 self.unsafe_to_break(start, end);
1204 return;
1205 }
1206
1207 self._set_glyph_flags(SAFE_TO_INSERT_TATWEEL, start, end, Some(true), None);
1208 }
1209
1210 fn _set_glyph_flags_impl(
1211 &mut self,
1212 mask: hb_mask_t,
1213 start: usize,
1214 end: usize,
1215 interior: bool,
1216 from_out_buffer: bool,
1217 ) {
1218 if !from_out_buffer || !self.have_output {
1219 if !interior {
1220 for info in &mut self.info[start..end] {
1221 info.mask |= mask;
1222 }
1223 } else {
1224 let cluster = self._infos_find_min_cluster(&self.info, start, end, None);
1225 self._infos_set_glyph_flags(false, start, end, cluster, mask);
1226 }
1227 } else {
1228 debug_assert!(start <= self.out_len);
1229 debug_assert!(self.idx <= end);
1230
1231 if !interior {
1232 let range_end = self.out_len;
1233 for info in &mut self.out_info_mut()[start..range_end] {
1234 info.mask |= mask;
1235 }
1236
1237 for info in &mut self.info[self.idx..end] {
1238 info.mask |= mask;
1239 }
1240 } else {
1241 let mut cluster = self._infos_find_min_cluster(&self.info, self.idx, end, None);
1242 cluster = self._infos_find_min_cluster(
1243 self.out_info(),
1244 start,
1245 self.out_len,
1246 Some(cluster),
1247 );
1248
1249 let out_len = self.out_len;
1250 self._infos_set_glyph_flags(true, start, out_len, cluster, mask);
1251 self._infos_set_glyph_flags(false, self.idx, end, cluster, mask);
1252 }
1253 }
1254 }
1255
1256 fn _set_glyph_flags(
1260 &mut self,
1261 mask: hb_mask_t,
1262 start: Option<usize>,
1263 end: Option<usize>,
1264 interior: Option<bool>,
1265 from_out_buffer: Option<bool>,
1266 ) {
1267 if let (Some(start), Some(end)) = (start, end) {
1270 if end.wrapping_sub(start) > 255 {
1271 return;
1272 }
1273 }
1274
1275 let start = start.unwrap_or(0);
1276 let end = min(end.unwrap_or(self.len), self.len);
1277 let interior = interior.unwrap_or(false);
1278 let from_out_buffer = from_out_buffer.unwrap_or(false);
1279
1280 if interior && !from_out_buffer && end - start < 2 {
1281 return;
1282 }
1283
1284 self._set_glyph_flags_impl(mask, start, end, interior, from_out_buffer);
1285 }
1286
1287 pub fn unsafe_to_concat(&mut self, start: Option<usize>, end: Option<usize>) {
1288 if !self.flags.contains(BufferFlags::PRODUCE_UNSAFE_TO_CONCAT) {
1289 return;
1290 }
1291
1292 self._set_glyph_flags(UNSAFE_TO_CONCAT, start, end, Some(false), None);
1293 }
1294
1295 pub fn unsafe_to_break_from_outbuffer(&mut self, start: Option<usize>, end: Option<usize>) {
1296 self._set_glyph_flags(
1297 UNSAFE_TO_BREAK | UNSAFE_TO_CONCAT,
1298 start,
1299 end,
1300 Some(true),
1301 Some(true),
1302 );
1303 }
1304
1305 pub fn unsafe_to_concat_from_outbuffer(&mut self, start: Option<usize>, end: Option<usize>) {
1306 if !self.flags.contains(BufferFlags::PRODUCE_UNSAFE_TO_CONCAT) {
1307 return;
1308 }
1309
1310 self._set_glyph_flags(UNSAFE_TO_CONCAT, start, end, Some(false), Some(true));
1311 }
1312
1313 pub fn move_to(&mut self, i: usize) -> bool {
1314 if !self.have_output {
1315 debug_assert!(i <= self.len);
1316 self.idx = i;
1317 return true;
1318 }
1319
1320 if !self.successful {
1321 return false;
1322 }
1323
1324 debug_assert!(i <= self.out_len + (self.len - self.idx));
1325
1326 if self.out_len < i {
1327 let count = i - self.out_len;
1328 if !self.make_room_for(count, count) {
1329 return false;
1330 }
1331
1332 for j in 0..count {
1333 self.set_out_info(self.out_len + j, self.info[self.idx + j]);
1334 }
1335
1336 self.idx += count;
1337 self.out_len += count;
1338 } else if self.out_len > i {
1339 let count = self.out_len - i;
1341
1342 if self.idx < count && !self.shift_forward(count - self.idx) {
1350 return false;
1351 }
1352
1353 debug_assert!(self.idx >= count);
1354
1355 self.idx -= count;
1356 self.out_len -= count;
1357
1358 for j in 0..count {
1359 self.info[self.idx + j] = self.out_info()[self.out_len + j];
1360 }
1361 }
1362
1363 true
1364 }
1365
1366 #[must_use]
1367 #[inline(always)]
1368 pub fn ensure(&mut self, size: usize) -> bool {
1369 if size <= self.info.len() {
1370 true
1371 } else {
1372 self.enlarge(size)
1373 }
1374 }
1375
1376 #[must_use]
1377 fn enlarge(&mut self, size: usize) -> bool {
1378 if size > self.max_len {
1379 self.successful = false;
1380 return false;
1381 }
1382
1383 self.info.resize(size, GlyphInfo::default());
1384 self.pos.resize(size, GlyphPosition::default());
1385 true
1386 }
1387
1388 #[must_use]
1389 fn make_room_for(&mut self, num_in: usize, num_out: usize) -> bool {
1390 if !self.ensure(self.out_len + num_out) {
1391 return false;
1392 }
1393
1394 if !self.have_separate_output && self.out_len + num_out > self.idx + num_in {
1395 debug_assert!(self.have_output);
1396
1397 self.have_separate_output = true;
1398 for i in 0..self.out_len {
1399 self.set_out_info(i, self.info[i]);
1400 }
1401 }
1402
1403 true
1404 }
1405
1406 fn shift_forward(&mut self, count: usize) -> bool {
1407 debug_assert!(self.have_output);
1408 if !self.ensure(self.len + count) {
1409 return false;
1410 }
1411
1412 self.max_ops -= (self.len - self.idx) as i32;
1413 if self.max_ops < 0 {
1414 self.successful = false;
1415 return false;
1416 }
1417
1418 for i in (0..(self.len - self.idx)).rev() {
1419 self.info[self.idx + count + i] = self.info[self.idx + i];
1420 }
1421
1422 if self.idx + count > self.len {
1423 for info in &mut self.info[self.len..self.idx + count] {
1424 *info = GlyphInfo::default();
1425 }
1426 }
1427
1428 self.len += count;
1429 self.idx += count;
1430
1431 true
1432 }
1433
1434 fn clear_context(&mut self, side: usize) {
1435 self.context_len[side] = 0;
1436 }
1437
1438 pub fn sort(&mut self, start: usize, end: usize, cmp: impl Fn(&GlyphInfo, &GlyphInfo) -> bool) {
1439 debug_assert!(!self.have_positions);
1440
1441 for i in start + 1..end {
1442 let mut j = i;
1443 while j > start && cmp(&self.info[j - 1], &self.info[i]) {
1444 j -= 1;
1445 }
1446
1447 if i == j {
1448 continue;
1449 }
1450
1451 self.merge_clusters(j, i + 1);
1453
1454 {
1455 let t = self.info[i];
1456 for idx in (0..i - j).rev() {
1457 self.info[idx + j + 1] = self.info[idx + j];
1458 }
1459
1460 self.info[j] = t;
1461 }
1462 }
1463 }
1464
1465 pub fn set_cluster(info: &mut GlyphInfo, cluster: u32, mask: hb_mask_t) {
1466 if info.cluster != cluster {
1467 info.mask = (info.mask & !glyph_flag::DEFINED) | (mask & glyph_flag::DEFINED);
1468 }
1469
1470 info.cluster = cluster;
1471 }
1472
1473 pub(crate) fn enter(&mut self) {
1475 self.serial = 0;
1476 self.scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
1477
1478 if let Some(len) = self.len.checked_mul(hb_buffer_t::MAX_LEN_FACTOR) {
1479 self.max_len = len.max(hb_buffer_t::MAX_LEN_MIN);
1480 }
1481
1482 if let Ok(len) = i32::try_from(self.len) {
1483 if let Some(ops) = len.checked_mul(hb_buffer_t::MAX_OPS_FACTOR) {
1484 self.max_ops = ops.max(hb_buffer_t::MAX_OPS_MIN);
1485 }
1486 }
1487 }
1488
1489 pub(crate) fn leave(&mut self) {
1491 self.max_len = hb_buffer_t::MAX_LEN_DEFAULT;
1492 self.max_ops = hb_buffer_t::MAX_OPS_DEFAULT;
1493 self.serial = 0;
1494 }
1495
1496 fn _infos_find_min_cluster(
1497 &self,
1498 info: &[GlyphInfo],
1499 start: usize,
1500 end: usize,
1501 cluster: Option<u32>,
1502 ) -> u32 {
1503 let mut cluster = cluster.unwrap_or(u32::MAX);
1504
1505 if start == end {
1506 return cluster;
1507 }
1508
1509 if self.cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS {
1510 for glyph_info in &info[start..end] {
1511 cluster = min(cluster, glyph_info.cluster);
1512 }
1513 }
1514
1515 cluster.min(info[start].cluster.min(info[end - 1].cluster))
1516 }
1517
1518 #[inline(always)]
1519 fn _infos_set_glyph_flags(
1520 &mut self,
1521 out_info: bool,
1522 start: usize,
1523 end: usize,
1524 cluster: u32,
1525 mask: hb_mask_t,
1526 ) {
1527 if start == end {
1528 return;
1529 }
1530
1531 let cluster_level = self.cluster_level;
1532
1533 let infos = if out_info {
1534 self.out_info_mut()
1535 } else {
1536 self.info.as_mut_slice()
1537 };
1538
1539 let cluster_first = infos[start].cluster;
1540 let cluster_last = infos[end - 1].cluster;
1541
1542 if cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS
1543 || (cluster != cluster_first && cluster != cluster_last)
1544 {
1545 for info in &mut infos[start..end] {
1546 if info.cluster != cluster {
1547 info.mask |= mask;
1548 }
1549 }
1550
1551 return;
1552 }
1553
1554 if cluster == cluster_first {
1556 let mut i = end;
1557 while start < i && infos[i - 1].cluster != cluster_first {
1558 if cluster != infos[i - 1].cluster {
1559 infos[i - 1].mask |= mask;
1560 }
1561
1562 i -= 1;
1563 }
1564 } else {
1565 let mut i = start;
1566 while i < end && infos[i].cluster != cluster_last {
1567 if cluster != infos[i].cluster {
1568 infos[i].mask |= mask;
1569 }
1570
1571 i += 1;
1572 }
1573 }
1574 }
1575
1576 pub fn is_empty(&self) -> bool {
1578 self.len == 0
1579 }
1580
1581 fn push_str(&mut self, text: &str) {
1582 if !self.ensure(self.len + text.chars().count()) {
1583 return;
1584 }
1585
1586 for (i, c) in text.char_indices() {
1587 self.info[self.len] = GlyphInfo {
1588 glyph_id: c as u32,
1589 cluster: i as u32,
1590 ..GlyphInfo::default()
1591 };
1592 self.len += 1;
1593 }
1594 }
1595
1596 fn set_pre_context(&mut self, text: &str) {
1597 self.clear_context(0);
1598 for (i, c) in text.chars().rev().enumerate().take(CONTEXT_LENGTH) {
1599 self.context[0][i] = c as Codepoint;
1600 self.context_len[0] += 1;
1601 }
1602 }
1603
1604 fn set_post_context(&mut self, text: &str) {
1605 self.clear_context(1);
1606 for (i, c) in text.chars().enumerate().take(CONTEXT_LENGTH) {
1607 self.context[1][i] = c as Codepoint;
1608 self.context_len[1] += 1;
1609 }
1610 }
1611
1612 pub fn next_syllable(&self, mut start: usize) -> usize {
1613 if start >= self.len {
1614 return start;
1615 }
1616
1617 let syllable = self.info[start].syllable();
1618 start += 1;
1619 while start < self.len && syllable == self.info[start].syllable() {
1620 start += 1;
1621 }
1622
1623 start
1624 }
1625
1626 #[inline]
1627 pub fn allocate_lig_id(&mut self) -> u8 {
1628 let mut lig_id = self.next_serial() & 0x07;
1629
1630 if lig_id == 0 {
1631 lig_id = self.allocate_lig_id();
1632 }
1633
1634 lig_id
1635 }
1636}
1637
1638pub(crate) fn _cluster_group_func(a: &GlyphInfo, b: &GlyphInfo) -> bool {
1639 a.cluster == b.cluster
1640}
1641
1642macro_rules! foreach_cluster {
1645 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {
1646 foreach_group!($buffer, $start, $end, $crate::hb::buffer::_cluster_group_func, $($body)*)
1647 };
1648}
1649
1650macro_rules! foreach_group {
1651 ($buffer:expr, $start:ident, $end:ident, $group_func:expr, $($body:tt)*) => {{
1652 let count = $buffer.len;
1653 let mut $start = 0;
1654 let mut $end = if count > 0 { $buffer.group_end(0, $group_func) } else { 0 };
1655
1656 while $start < count {
1657 $($body)*;
1658 $start = $end;
1659 $end = $buffer.group_end($start, $group_func);
1660 }
1661 }};
1662}
1663
1664macro_rules! foreach_syllable {
1665 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {{
1666 let mut $start = 0;
1667 let mut $end = $buffer.next_syllable(0);
1668 while $start < $buffer.len {
1669 $($body)*;
1670 $start = $end;
1671 $end = $buffer.next_syllable($start);
1672 }
1673 }};
1674}
1675
1676macro_rules! foreach_grapheme {
1677 ($buffer:expr, $start:ident, $end:ident, $($body:tt)*) => {
1678 foreach_group!($buffer, $start, $end, $crate::hb::ot_layout::_hb_grapheme_group_func, $($body)*)
1679 };
1680}
1681
1682bitflags::bitflags! {
1683 #[derive(Default, Debug, Clone, Copy)]
1684 pub struct UnicodeProps: u16 {
1685 const GENERAL_CATEGORY = 0x001F;
1686 const IGNORABLE = 0x0020;
1687 const HIDDEN = 0x0040;
1689 const CONTINUATION = 0x0080;
1690
1691 const CF_ZWJ = 0x0100;
1693 const CF_ZWNJ = 0x0200;
1694 const CF_VS = 0x0400;
1695 const CF_AAT_DELETED = 0x0800;
1696 }
1697}
1698
1699bitflags::bitflags! {
1700 #[derive(Default, Debug, Clone, Copy)]
1701 pub struct GlyphPropsFlags: u16 {
1702 const BASE_GLYPH = 0x02;
1704 const LIGATURE = 0x04;
1705 const MARK = 0x08;
1706 const CLASS_MASK = Self::BASE_GLYPH.bits() | Self::LIGATURE.bits() | Self::MARK.bits();
1707
1708 const SUBSTITUTED = 0x10;
1710 const LIGATED = 0x20;
1711 const MULTIPLIED = 0x40;
1712
1713 const PRESERVE = Self::SUBSTITUTED.bits() | Self::LIGATED.bits() | Self::MULTIPLIED.bits();
1714 }
1715}
1716
1717pub type hb_buffer_scratch_flags_t = u32;
1718pub const HB_BUFFER_SCRATCH_FLAG_DEFAULT: u32 = 0x0000_0000;
1719pub const HB_BUFFER_SCRATCH_FLAG_HAS_FRACTION_SLASH: u32 = 0x0000_0001;
1720pub const HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES: u32 = 0x0000_0002;
1721pub const HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK: u32 = 0x0000_0004;
1722pub const HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT: u32 = 0x0000_0008;
1723pub const HB_BUFFER_SCRATCH_FLAG_HAS_CGJ: u32 = 0x0000_0010;
1724pub const HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE: u32 = 0x0000_0020;
1725pub const HB_BUFFER_SCRATCH_FLAG_HAS_VARIATION_SELECTOR_FALLBACK: u32 = 0x0000_0040;
1726pub const HB_BUFFER_SCRATCH_FLAG_HAS_CONTINUATIONS: u32 = 0x0000_0080;
1727
1728pub const HB_BUFFER_SCRATCH_FLAG_SHAPER0: u32 = 0x0100_0000;
1730pub struct UnicodeBuffer(pub(crate) hb_buffer_t);
1736
1737impl UnicodeBuffer {
1738 #[inline]
1740 pub fn new() -> UnicodeBuffer {
1741 UnicodeBuffer(hb_buffer_t::new())
1742 }
1743
1744 #[inline]
1749 pub fn len(&self) -> usize {
1750 self.0.len
1751 }
1752
1753 pub fn reserve(&mut self, size: usize) -> bool {
1755 self.0.ensure(size)
1756 }
1757
1758 #[inline]
1760 pub fn is_empty(&self) -> bool {
1761 self.0.is_empty()
1762 }
1763
1764 #[inline]
1766 pub fn push_str(&mut self, str: &str) {
1767 self.0.push_str(str);
1768 }
1769
1770 #[inline]
1772 pub fn set_pre_context(&mut self, str: &str) {
1773 self.0.set_pre_context(str);
1774 }
1775
1776 #[inline]
1778 pub fn set_post_context(&mut self, str: &str) {
1779 self.0.set_post_context(str);
1780 }
1781
1782 #[inline]
1784 pub fn add(&mut self, codepoint: char, cluster: u32) {
1785 self.0.add(codepoint as u32, cluster);
1786 self.0.context_len[1] = 0;
1787 }
1788
1789 #[inline]
1791 pub fn set_direction(&mut self, direction: Direction) {
1792 self.0.direction = direction;
1793 }
1794
1795 #[inline]
1797 pub fn direction(&self) -> Direction {
1798 self.0.direction
1799 }
1800
1801 #[inline]
1803 pub fn set_script(&mut self, script: Script) {
1804 self.0.script = Some(script);
1805 }
1806
1807 pub fn script(&self) -> Script {
1809 self.0.script.unwrap_or(script::UNKNOWN)
1810 }
1811
1812 #[inline]
1814 pub fn set_language(&mut self, lang: Language) {
1815 self.0.language = Some(lang);
1816 }
1817
1818 #[inline]
1820 pub fn set_not_found_variation_selector_glyph(&mut self, glyph: u32) {
1821 self.0.not_found_variation_selector = Some(glyph);
1822 }
1823
1824 #[inline]
1826 pub fn language(&self) -> Option<Language> {
1827 self.0.language.clone()
1828 }
1829
1830 #[inline]
1833 pub fn guess_segment_properties(&mut self) {
1834 self.0.guess_segment_properties();
1835 }
1836
1837 #[inline]
1839 pub fn set_flags(&mut self, flags: BufferFlags) {
1840 self.0.flags = flags;
1841 }
1842
1843 #[inline]
1845 pub fn flags(&self) -> BufferFlags {
1846 self.0.flags
1847 }
1848
1849 #[inline]
1851 pub fn set_cluster_level(&mut self, cluster_level: BufferClusterLevel) {
1852 self.0.cluster_level = match cluster_level {
1853 BufferClusterLevel::MonotoneGraphemes => HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES,
1854 BufferClusterLevel::MonotoneCharacters => HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS,
1855 BufferClusterLevel::Characters => HB_BUFFER_CLUSTER_LEVEL_CHARACTERS,
1856 BufferClusterLevel::Graphemes => HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES,
1857 }
1858 }
1859
1860 #[inline]
1862 pub fn cluster_level(&self) -> BufferClusterLevel {
1863 match self.0.cluster_level {
1864 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES => BufferClusterLevel::MonotoneGraphemes,
1865 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS => BufferClusterLevel::MonotoneCharacters,
1866 HB_BUFFER_CLUSTER_LEVEL_CHARACTERS => BufferClusterLevel::Characters,
1867 HB_BUFFER_CLUSTER_LEVEL_GRAPHEMES => BufferClusterLevel::Graphemes,
1868 _ => BufferClusterLevel::MonotoneGraphemes,
1869 }
1870 }
1871
1872 #[inline]
1874 pub fn reset_clusters(&mut self) {
1875 self.0.reset_clusters();
1876 }
1877
1878 #[inline]
1880 pub fn clear(&mut self) {
1881 self.0.clear();
1882 }
1883}
1884
1885impl core::fmt::Debug for UnicodeBuffer {
1886 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1887 fmt.debug_struct("UnicodeBuffer")
1888 .field("direction", &self.direction())
1889 .field("language", &self.language())
1890 .field("script", &self.script())
1891 .field("cluster_level", &self.cluster_level())
1892 .finish()
1893 }
1894}
1895
1896impl Default for UnicodeBuffer {
1897 fn default() -> UnicodeBuffer {
1898 UnicodeBuffer::new()
1899 }
1900}
1901
1902pub struct GlyphBuffer(pub(crate) hb_buffer_t);
1904
1905impl GlyphBuffer {
1906 #[inline]
1912 pub fn len(&self) -> usize {
1913 self.0.len
1914 }
1915
1916 #[inline]
1918 pub fn is_empty(&self) -> bool {
1919 self.0.is_empty()
1920 }
1921
1922 #[inline]
1924 pub fn glyph_infos(&self) -> &[GlyphInfo] {
1925 &self.0.info[0..self.0.len]
1926 }
1927
1928 #[inline]
1930 pub fn glyph_positions(&self) -> &[GlyphPosition] {
1931 &self.0.pos[0..self.0.len]
1932 }
1933
1934 #[inline]
1937 pub fn clear(mut self) -> UnicodeBuffer {
1938 self.0.clear();
1939 UnicodeBuffer(self.0)
1940 }
1941
1942 pub fn serialize(&self, face: &crate::Shaper, flags: SerializeFlags) -> String {
1944 self.serialize_impl(face, flags).unwrap_or_default()
1945 }
1946
1947 fn serialize_impl(
1948 &self,
1949 face: &hb_font_t,
1950 flags: SerializeFlags,
1951 ) -> Result<String, core::fmt::Error> {
1952 use core::fmt::Write;
1953
1954 let mut s = String::with_capacity(64);
1955
1956 let info = self.glyph_infos();
1957 let pos = self.glyph_positions();
1958 let mut x = 0;
1959 let mut y = 0;
1960 let names = face.glyph_names();
1961 for (info, pos) in info.iter().zip(pos) {
1962 s.push(if s.is_empty() { '[' } else { '|' });
1963
1964 if !flags.contains(SerializeFlags::NO_GLYPH_NAMES) {
1965 match names.get(info.as_glyph().to_u32()) {
1966 Some(name) => s.push_str(name),
1967 None => write!(&mut s, "gid{}", info.glyph_id)?,
1968 }
1969 } else {
1970 write!(&mut s, "{}", info.glyph_id)?;
1971 }
1972
1973 if !flags.contains(SerializeFlags::NO_CLUSTERS) {
1974 write!(&mut s, "={}", info.cluster)?;
1975 }
1976
1977 if !flags.contains(SerializeFlags::NO_POSITIONS) {
1978 if x + pos.x_offset != 0 || y + pos.y_offset != 0 {
1979 write!(&mut s, "@{},{}", x + pos.x_offset, y + pos.y_offset)?;
1980 }
1981
1982 if !flags.contains(SerializeFlags::NO_ADVANCES) {
1983 write!(&mut s, "+{}", pos.x_advance)?;
1984 if pos.y_advance != 0 {
1985 write!(&mut s, ",{}", pos.y_advance)?;
1986 }
1987 }
1988 }
1989
1990 if flags.contains(SerializeFlags::GLYPH_FLAGS) {
1991 if info.mask & glyph_flag::DEFINED != 0 {
1992 write!(&mut s, "#{:X}", info.mask & glyph_flag::DEFINED)?;
1993 }
1994 }
1995
1996 if flags.contains(SerializeFlags::GLYPH_EXTENTS) {
1997 let mut extents = hb_glyph_extents_t::default();
1998 face.glyph_extents(info.as_glyph(), &mut extents);
1999 write!(
2000 &mut s,
2001 "<{},{},{},{}>",
2002 extents.x_bearing, extents.y_bearing, extents.width, extents.height
2003 )?;
2004 }
2005
2006 if flags.contains(SerializeFlags::NO_ADVANCES) {
2007 x += pos.x_advance;
2008 y += pos.y_advance;
2009 }
2010 }
2011
2012 if !s.is_empty() {
2013 s.push(']');
2014 }
2015
2016 Ok(s)
2017 }
2018}
2019
2020impl core::fmt::Debug for GlyphBuffer {
2021 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2022 fmt.debug_struct("GlyphBuffer")
2023 .field("glyph_positions", &self.glyph_positions())
2024 .field("glyph_infos", &self.glyph_infos())
2025 .finish()
2026 }
2027}