[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()
This commit is contained in:
Behdad Esfahbod 2024-03-14 13:30:21 -06:00
parent 3d455998bf
commit f1ac867dee
5 changed files with 55 additions and 3 deletions

View file

@ -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

View file

@ -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:

View file

@ -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.

View file

@ -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. */

View file

@ -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,