Repository: harfbuzz/rustybuzz (language: rust)

Issue:
Allow specifying `item_offset` and `item_length` as in HarfBuzz
HarfBuzz’s [`hb_buffer_add_codepoints`](https://harfbuzz.github.io/harfbuzz-hb-buffer.html#hb-buffer-add-codepoints) and friends allow specifying an offset and length from the string that was passed in. This allows HarfBuzz to have the full context of the string being shaped in order to perform proper shaping across runs. I’m not sure how feasible it would be for this crate to implement similar functionality, though.


Discussion / hints:
**Update:** I looked at the HarfBuzz code base and it stores up to 5 codepoints of context both before and after the string. The `Buffer` struct in rustybuzz has similar fields, and they’re even used in shaping Arabic text, but no method currently changes `Buffer::context_len` or `Buffer::context`.
Yes, there are a lot of missing pieces. Patches are welcome. 

Fix patch:
diff --git a/src/buffer.rs b/src/buffer.rs
index 717cb571..e9ad0feb 100644
--- a/src/buffer.rs
+++ b/src/buffer.rs
@@ -1298,6 +1298,10 @@ impl Buffer {
         self.idx += count;
     }
 
+    fn clear_context(&mut self, side: usize) {
+        self.context_len[side] = 0;
+    }
+
     pub fn sort(&mut self, start: usize, end: usize, cmp: impl Fn(&GlyphInfo, &GlyphInfo) -> bool) {
         assert!(!self.have_positions);
 
@@ -1380,6 +1384,20 @@ impl Buffer {
         }
     }
 
+    fn set_pre_context(&mut self, text: &str) {
+        self.clear_context(0);
+        for (i, c) in text.chars().rev().enumerate().take(CONTEXT_LENGTH) {
+            self.context[0][i] = c;
+        }
+    }
+
+    fn set_post_context(&mut self, text: &str) {
+        self.clear_context(1);
+        for (i, c) in text.chars().enumerate().take(CONTEXT_LENGTH) {
+            self.context[1][i] = c;
+        }
+    }
+
     pub fn next_cluster(&self, mut start: usize) -> usize {
         if start >= self.len {
             return start;
@@ -1583,6 +1601,18 @@ impl UnicodeBuffer {
         self.0.push_str(str);
     }
 
+    /// Sets the pre-context for this buffer.
+    #[inline]
+    pub fn set_pre_context(&mut self, str: &str) {
+        self.0.set_pre_context(str)
+    }
+
+    /// Sets the post-context for this buffer.
+    #[inline]
+    pub fn set_post_context(&mut self, str: &str) {
+        self.0.set_post_context(str)
+    }
+
     /// Appends a character to a buffer with the given cluster value.
     #[inline]
     pub fn add(&mut self, codepoint: char, cluster: u32) {


Test patch: