From f1ac867deec0500fed94f965b6da25f9fcd434de Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 14 Mar 2024 13:30:21 -0600 Subject: [PATCH] [buffer] Add API for random state Fixes https://github.com/harfbuzz/harfbuzz/issues/4620 New API: +hb_buffer_set_random_state() +hb_buffer_get_random_state() --- docs/harfbuzz-sections.txt | 2 ++ src/hb-buffer.cc | 44 ++++++++++++++++++++++++++++++++++++ src/hb-buffer.h | 6 +++++ src/hb-buffer.hh | 1 + src/hb-ot-layout-gsubgpos.hh | 5 ++-- 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index 4bf08ae24..bd0de9a63 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -83,6 +83,8 @@ hb_buffer_set_not_found_glyph hb_buffer_get_not_found_glyph hb_buffer_set_replacement_codepoint hb_buffer_get_replacement_codepoint +hb_buffer_set_random_state +hb_buffer_get_random_state hb_buffer_normalize_glyphs hb_buffer_reverse hb_buffer_reverse_range diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 934c6c212..f464f20a0 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -309,6 +309,7 @@ hb_buffer_t::clear () deallocate_var_all (); serial = 0; + random_state = 1; scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; } @@ -1359,6 +1360,49 @@ hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer) return buffer->not_found; } +/** + * hb_buffer_set_random_state: + * @buffer: An #hb_buffer_t + * @state: the new random state + * + * Sets the random state of the buffer. The state changes + * every time a glyph uses randomness (eg. the `rand` + * OpenType feature). This function together with + * hb_buffer_get_random_state() allow for transferring + * the current random state to a subsequent buffer, to + * get better randomness distribution. + * + * Defaults to 1 and when buffer contents are cleared. + * A value of 0 disables randomness during shaping. + * + * XSince: REPLACEME + **/ +void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state) +{ + if (unlikely (hb_object_is_immutable (buffer))) + return; + + buffer->random_state = state; +} + +/** + * hb_buffer_get_random_state: + * @buffer: An #hb_buffer_t + * + * See hb_buffer_set_random_state(). + * + * Return value: + * The @buffer random state + * + * XSince: REPLACEME + **/ +unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer) +{ + return buffer->random_state; +} /** * hb_buffer_clear_contents: diff --git a/src/hb-buffer.h b/src/hb-buffer.h index 3573127ff..f75fe96b2 100644 --- a/src/hb-buffer.h +++ b/src/hb-buffer.h @@ -487,6 +487,12 @@ hb_buffer_set_not_found_glyph (hb_buffer_t *buffer, HB_EXTERN hb_codepoint_t hb_buffer_get_not_found_glyph (const hb_buffer_t *buffer); +HB_EXTERN void +hb_buffer_set_random_state (hb_buffer_t *buffer, + unsigned state); + +HB_EXTERN unsigned +hb_buffer_get_random_state (const hb_buffer_t *buffer); /* * Content API. diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh index f04ad58f1..0a198722d 100644 --- a/src/hb-buffer.hh +++ b/src/hb-buffer.hh @@ -116,6 +116,7 @@ struct hb_buffer_t uint8_t allocated_var_bits; uint8_t serial; + uint32_t random_state; hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ int max_ops; /* Maximum allowed operations. */ diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 162179d08..c65ea32b8 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -723,7 +723,6 @@ struct hb_ot_apply_context_t : bool auto_zwj = true; bool per_syllable = false; bool random = false; - uint32_t random_state = 1; unsigned new_syllables = (unsigned) -1; signed last_base = -1; // GPOS uses @@ -788,8 +787,8 @@ struct hb_ot_apply_context_t : uint32_t random_number () { /* http://www.cplusplus.com/reference/random/minstd_rand/ */ - random_state = random_state * 48271 % 2147483647; - return random_state; + buffer->random_state = buffer->random_state * 48271 % 2147483647; + return buffer->random_state; } bool match_properties_mark (hb_codepoint_t glyph,