diff options
| author | Sam Varshavchik | 2021-03-12 07:15:38 -0500 | 
|---|---|---|
| committer | Sam Varshavchik | 2021-03-12 20:27:32 -0500 | 
| commit | cf15bdb799c6b8b395087480fe3e89fb8b53cc12 (patch) | |
| tree | bb10f5f2f04a3abdf82ccece78eee35544dd82fe /unicode/unicode_bidi.c | |
| parent | 18fc31347b80597f4100f96c86799fe130786781 (diff) | |
| download | courier-libs-cf15bdb799c6b8b395087480fe3e89fb8b53cc12.tar.bz2 | |
courier-unicode: further changes to the canonical compose/decompose.
Diffstat (limited to 'unicode/unicode_bidi.c')
| -rw-r--r-- | unicode/unicode_bidi.c | 72 | 
1 files changed, 72 insertions, 0 deletions
| diff --git a/unicode/unicode_bidi.c b/unicode/unicode_bidi.c index b4e3f2c..ac4f5bc 100644 --- a/unicode/unicode_bidi.c +++ b/unicode/unicode_bidi.c @@ -2818,3 +2818,75 @@ struct unicode_bidi_direction unicode_bidi_get_direction(const char32_t *str,  		(0, n,  		 get_enum_bidi_type_for_embedding_paragraph_level, &info);  } + +void unicode_bidi_combinings(const char32_t *str, +			     const unicode_bidi_level_t *levels, +			     size_t n, +			     void (*combinings)(unicode_bidi_level_t level, +						size_t level_start, +						size_t n_chars, +						size_t comb_start, +						size_t n_comb_chars, +						void *arg), +			       void *arg) +{ +	size_t level_start=0; + +	while (level_start < n) +	{ +		size_t level_end; +		size_t comb_start; +		size_t comb_end; + +		// Find the end of this level + +		for (level_end=level_start; ++level_end<n; ) +		{ +			if (levels && (levels[level_end] != +				       levels[level_start])) +				break; +		} + +		// Now sweep from level_start to level_end. + +		for (comb_start=level_start; comb_start < level_end; ) +		{ +			// Search for a non-0 ccc + +			if (unicode_ccc(str[comb_start]) == 0) +			{ +				++comb_start; +				continue; +			} + +			// Now, search for the next ccc of 0, stopping at +			// level_end + +			for (comb_end=comb_start; ++comb_end < level_end; ) +			{ +				if (unicode_ccc(str[comb_end]) == 0) +					break; +			} + +			// Report this +			(*combinings)((levels ? levels[level_start] +					 : 0), level_start, +				      level_end-level_start, +				      comb_start, +				      comb_end-comb_start, arg); + +			// If we're here before the level_end we must +			// have reached the next starter. So, on the next +			// iteration we want to start with the following +			// character. So, if the callback reversed the +			// combinings and the following starter the +			// next character will now be a composition, so +			// we can skip it. + +			if (comb_end < level_end) +				++comb_end; +			comb_start=comb_end; +		} +		level_start=level_end; +	} +} | 
