summaryrefslogtreecommitdiffstats
path: root/unicode/unicode_bidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'unicode/unicode_bidi.c')
-rw-r--r--unicode/unicode_bidi.c131
1 files changed, 104 insertions, 27 deletions
diff --git a/unicode/unicode_bidi.c b/unicode/unicode_bidi.c
index b23b833..772f9fe 100644
--- a/unicode/unicode_bidi.c
+++ b/unicode/unicode_bidi.c
@@ -464,7 +464,7 @@ struct directional_status_stack_entry {
typedef struct {
struct directional_status_stack_entry *head;
- unicode_bidi_level_t paragraph_embedding_level;
+ struct unicode_bidi_direction paragraph_embedding_level;
const char32_t *chars;
enum_bidi_type_t *types;
const enum_bidi_type_t *orig_types;
@@ -618,7 +618,7 @@ get_enum_bidi_type_for_paragraph_embedding_level(size_t i,
return p->p[i];
}
-static unicode_bidi_level_t
+static struct unicode_bidi_direction
compute_paragraph_embedding_level_from_types(const enum_bidi_type_t *p,
size_t i, size_t j)
{
@@ -628,7 +628,7 @@ compute_paragraph_embedding_level_from_types(const enum_bidi_type_t *p,
return compute_paragraph_embedding_level
(i, j,
get_enum_bidi_type_for_paragraph_embedding_level,
- &info).direction;
+ &info);
}
static directional_status_stack_t
@@ -642,10 +642,18 @@ directional_status_stack_init(const char32_t *chars,
stack=(directional_status_stack_t)calloc(1, sizeof(*stack));
- stack->paragraph_embedding_level=
- initial_embedding_level
- ? *initial_embedding_level & 1
- : compute_paragraph_embedding_level_from_types(types, 0, n);
+ if (initial_embedding_level)
+ {
+ stack->paragraph_embedding_level.direction=
+ *initial_embedding_level & 1;
+ stack->paragraph_embedding_level.is_explicit=1;
+ }
+ else
+ {
+ stack->paragraph_embedding_level=
+ compute_paragraph_embedding_level_from_types(types,
+ 0, n);
+ }
stack->chars=chars;
stack->orig_types=types;
@@ -666,7 +674,8 @@ directional_status_stack_init(const char32_t *chars,
stack->size=n;
directional_status_stack_push(stack,
- stack->paragraph_embedding_level,
+ stack->paragraph_embedding_level
+ .direction,
do_neutral, 0);
return stack;
@@ -736,7 +745,7 @@ void unicode_bidi_setbnl(char32_t *p,
}
}
-unicode_bidi_level_t
+struct unicode_bidi_direction
unicode_bidi_calc(const char32_t *p, size_t n, unicode_bidi_level_t *bufp,
const unicode_bidi_level_t *initial_embedding_level)
{
@@ -748,7 +757,7 @@ unicode_bidi_calc(const char32_t *p, size_t n, unicode_bidi_level_t *bufp,
unicode_bidi_calc_types(p, n, buf);
- unicode_bidi_level_t level=
+ struct unicode_bidi_direction level=
unicode_bidi_calc_levels(p,
buf,
n,
@@ -762,7 +771,7 @@ unicode_bidi_calc(const char32_t *p, size_t n, unicode_bidi_level_t *bufp,
static void unicode_bidi_cl(directional_status_stack_t stack);
-unicode_bidi_level_t
+struct unicode_bidi_direction
unicode_bidi_calc_levels(const char32_t *p,
const enum_bidi_type_t *types,
size_t n,
@@ -779,12 +788,12 @@ unicode_bidi_calc_levels(const char32_t *p,
stack=directional_status_stack_init(p, types, n, bufp,
initial_embedding_level);
- unicode_bidi_level_t paragraph_embedding_level=
+ struct unicode_bidi_direction paragraph_embedding_level=
stack->paragraph_embedding_level;
#ifdef BIDI_DEBUG
fprintf(DEBUGDUMP, "BIDI: START: Paragraph embedding level: %d\n",
- (int)stack->paragraph_embedding_level);
+ (int)paragraph_embedding_level.direction);
#endif
unicode_bidi_cl(stack);
@@ -971,7 +980,8 @@ static void unicode_bidi_cl(directional_status_stack_t stack)
}
cur_class=compute_paragraph_embedding_level_from_types
- (stack->types, i+1, j) == 1
+ (stack->types, i+1, j).direction
+ != UNICODE_BIDI_LR
? UNICODE_BIDI_TYPE_RLI
: UNICODE_BIDI_TYPE_LRI;
}
@@ -1104,7 +1114,8 @@ static void unicode_bidi_cl(directional_status_stack_t stack)
{
/* X8 */
- stack->levels[i]=stack->paragraph_embedding_level;
+ stack->levels[i]=
+ stack->paragraph_embedding_level.direction;
}
}
@@ -1203,9 +1214,9 @@ static void unicode_bidi_cl(directional_status_stack_t stack)
continue; /* Edge case */
unicode_bidi_level_t before=
- stack->paragraph_embedding_level;
+ stack->paragraph_embedding_level.direction;
unicode_bidi_level_t after=
- stack->paragraph_embedding_level;
+ stack->paragraph_embedding_level.direction;
size_t first_i=beg_iter.i;
@@ -1301,11 +1312,11 @@ static void unicode_bidi_cl(directional_status_stack_t stack)
case UNICODE_BIDI_TYPE_PDI:
if (seen_sb)
stack->levels[i]=
- stack->paragraph_embedding_level;
+ stack->paragraph_embedding_level.direction;
break;
case UNICODE_BIDI_TYPE_S:
case UNICODE_BIDI_TYPE_B:
- stack->levels[i]=stack->paragraph_embedding_level;
+ stack->levels[i]=stack->paragraph_embedding_level.direction;
seen_sb=1;
break;
default:
@@ -2052,12 +2063,14 @@ void unicode_bidi_reorder(char32_t *p,
level_run_layers_deinit(&layers);
}
-size_t unicode_bidi_cleanup(char32_t *string,
- unicode_bidi_level_t *levels,
- size_t n,
- int cleanup_options,
- void (*removed_callback)(size_t, void *),
- void *arg)
+static size_t unicode_bidi_count_or_cleanup(const char32_t *string,
+ char32_t *dest,
+ unicode_bidi_level_t *levels,
+ size_t n,
+ int cleanup_options,
+ void (*removed_callback)(size_t,
+ void *),
+ void *arg)
{
size_t i=0;
for (size_t j=0; j<n; ++j)
@@ -2079,13 +2092,34 @@ size_t unicode_bidi_cleanup(char32_t *string,
if (levels)
levels[i]=levels[j] & 1;
- string[i]=(cleanup_options & UNICODE_BIDI_CLEANUP_BNL)
- && cl == UNICODE_BIDI_TYPE_B ? '\n' : string[j];
+ if (dest)
+ dest[i]=(cleanup_options & UNICODE_BIDI_CLEANUP_BNL)
+ && cl == UNICODE_BIDI_TYPE_B ? '\n' : string[j];
++i;
}
return i;
}
+size_t unicode_bidi_cleanup(char32_t *string,
+ unicode_bidi_level_t *levels,
+ size_t n,
+ int cleanup_options,
+ void (*removed_callback)(size_t, void *),
+ void *arg)
+{
+ return unicode_bidi_count_or_cleanup(string, string, levels, n,
+ cleanup_options, removed_callback,
+ arg);
+}
+
+size_t unicode_bidi_cleaned_size(const char32_t *string,
+ size_t n,
+ int cleanup_options)
+{
+ return unicode_bidi_count_or_cleanup(string, NULL, NULL, n,
+ cleanup_options, NULL, NULL);
+}
+
void unicode_bidi_logical_order(char32_t *string,
unicode_bidi_level_t *levels,
size_t n,
@@ -2276,6 +2310,49 @@ static void emit_marker(struct bidi_embed_levelrun *p,
}
}
+int unicode_bidi_needs_embed(const char32_t *string,
+ const unicode_bidi_level_t *levels,
+ size_t n,
+ const unicode_bidi_level_t *paragraph_level)
+{
+ char32_t *string_cpy=(char32_t *)malloc(n * sizeof(char32_t));
+ unicode_bidi_level_t *levels_cpy=(unicode_bidi_level_t *)
+ malloc(n * sizeof(unicode_bidi_level_t));
+ size_t nn;
+ int ret;
+
+ if (!string_cpy || !levels_cpy)
+ abort();
+
+ memcpy(string_cpy, string, n * sizeof(char32_t));
+
+ struct unicode_bidi_direction direction=
+ unicode_bidi_calc(string_cpy, n,
+ levels_cpy, paragraph_level);
+
+ unicode_bidi_reorder(string_cpy, levels_cpy, n, NULL, NULL);
+ nn=unicode_bidi_cleanup(string_cpy, levels_cpy, n, 0,
+ NULL, NULL);
+
+ ret=0;
+ if (n == nn && (paragraph_level == NULL ||
+ direction.direction == *paragraph_level))
+ {
+ unicode_bidi_logical_order(string_cpy, levels_cpy, nn,
+ direction.direction,
+ NULL, NULL);
+ if (memcmp(string_cpy, string, n * sizeof(char32_t)) == 0 &&
+ memcmp(levels_cpy, levels, n * sizeof(unicode_bidi_level_t))
+ == 0)
+ {
+ ret=1;
+ }
+ }
+ free(string_cpy);
+ free(levels_cpy);
+ return ret;
+}
+
void unicode_bidi_embed(const char32_t *string,
const unicode_bidi_level_t *levels,
size_t n,