#define RL_BRACKET_TYPE(list) ((list)->bracket_type)
#define RL_ISOLATE_LEVEL(list) ((list)->isolate_level)
+#define LOCAL_BRACKET_SIZE 16
+
/* Pairing nodes are used for holding a pair of open/close brackets as
described in BD16. */
struct _FriBidiPairingNodeStruct {
FriBidiLevel *embedding_levels
)
{
- FriBidiLevel base_level, *base_level_per_iso_level = NULL, max_level = 0;
+ FriBidiLevel base_level_per_iso_level[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL];
+ FriBidiLevel base_level, max_level = 0;
FriBidiParType base_dir;
FriBidiRun *main_run_list = NULL, *explicits_list = NULL, *pp;
fribidi_boolean status = false;
DBG2 (" base level : %c", fribidi_char_from_level (base_level));
DBG2 (" base dir : %s", fribidi_get_bidi_type_name (base_dir));
- base_level_per_iso_level = fribidi_malloc(sizeof(base_level_per_iso_level[0]) *
- FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL);
base_level_per_iso_level[0] = base_level;
# if DEBUG
FriBidiLevel level;
int isolate;
int isolate_level;
- } *status_stack;
+ } status_stack[FRIBIDI_BIDI_MAX_RESOLVED_LEVELS];
FriBidiRun temp_link;
- FriBidiRun **run_per_isolate_level; /* Connect the isolate levels */
+ FriBidiRun *run_per_isolate_level[FRIBIDI_BIDI_MAX_RESOLVED_LEVELS];
- run_per_isolate_level = fribidi_malloc(sizeof(run_per_isolate_level[0])
- * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
memset(run_per_isolate_level, 0, sizeof(run_per_isolate_level[0])
* FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
first_interval = 0;
valid_isolate_count = 0;
isolate_overflow = 0;
- status_stack = fribidi_malloc (sizeof (status_stack[0]) *
- FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
for_run_list (pp, main_run_list)
{
override = FRIBIDI_TYPE_ON;
stack_size = 0;
over_pushed = 0;
-
- fribidi_free (status_stack);
- fribidi_free (run_per_isolate_level);
}
/* X10. The remaining rules are applied to each run of characters at the
same level. For each run, determine the start-of-level-run (sor) and
max_iso_level = 0;
DBG ("resolving weak types");
{
- int *last_strong_stack;
+ int last_strong_stack[FRIBIDI_BIDI_MAX_RESOLVED_LEVELS];
FriBidiCharType prev_type_orig;
fribidi_boolean w4;
- last_strong_stack = fribidi_malloc (sizeof (int)
- * FRIBIDI_BIDI_MAX_RESOLVED_LEVELS);
last_strong_stack[0] = base_dir;
for_run_list (pp, main_run_list)
else
prev_type_orig = PREV_TYPE_OR_SOR (pp->next);
}
-
- fribidi_free (last_strong_stack);
}
compact_neutrals (main_run_list);
/* BD16 - Build list of all pairs*/
int num_iso_levels = max_iso_level + 1;
FriBidiPairingNode *pairing_nodes = NULL;
- FriBidiRun ***bracket_stack = fribidi_malloc(sizeof(bracket_stack[0])
- * num_iso_levels);
- int *bracket_stack_size = fribidi_malloc(sizeof(bracket_stack_size[0])
- * num_iso_levels);
+ FriBidiRun *local_bracket_stack[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL][LOCAL_BRACKET_SIZE];
+ FriBidiRun **bracket_stack[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL];
+ int bracket_stack_size[FRIBIDI_BIDI_MAX_EXPLICIT_LEVEL];
int last_level = RL_LEVEL(main_run_list);
int last_iso_level = 0;
memset(bracket_stack, 0, sizeof(bracket_stack[0])*num_iso_levels);
memset(bracket_stack_size, 0, sizeof(bracket_stack_size[0])*num_iso_levels);
+ /* populate the bracket_size. The first LOCAL_BRACKET_SIZE entries
+ of the stack are one the stack. Allocate the rest of the entries.
+ */
+ {
+ int iso_level;
+ for (iso_level=0; iso_level < LOCAL_BRACKET_SIZE; iso_level++)
+ bracket_stack[iso_level] = local_bracket_stack[iso_level];
+
+ for (iso_level=LOCAL_BRACKET_SIZE; iso_level < num_iso_levels; iso_level++)
+ bracket_stack[iso_level] = fribidi_malloc (sizeof (bracket_stack[0])
+ * FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS);
+ }
+
/* Build the bd16 pair stack. */
for_run_list (pp, main_run_list)
{
if (level != last_level && last_iso_level == iso_level)
bracket_stack_size[last_iso_level] = 0;
- if (!bracket_stack[iso_level])
- bracket_stack[iso_level] = fribidi_malloc (sizeof (bracket_stack[0])
- * FRIBIDI_BIDI_MAX_NESTED_BRACKET_PAIRS);
if (brack_prop!= FRIBIDI_NO_BRACKET)
{
if (FRIBIDI_IS_BRACKET_OPEN(brack_prop))
}
free_pairing_nodes(pairing_nodes);
- {
- int i;
- for (i=0; i<num_iso_levels; i++)
- fribidi_free(bracket_stack[i]);
- }
- fribidi_free(bracket_stack);
- fribidi_free(bracket_stack_size);
+
+ if (num_iso_levels >= LOCAL_BRACKET_SIZE)
+ {
+ int i;
+ /* Only need to free the non static members */
+ for (i=LOCAL_BRACKET_SIZE; i<num_iso_levels; i++)
+ fribidi_free(bracket_stack[i]);
+ }
/* Remove the bracket property and re-compact */
{
free_run_list (main_run_list);
if UNLIKELY
(explicits_list) free_run_list (explicits_list);
- if (base_level_per_iso_level)
- fribidi_free (base_level_per_iso_level);
return status ? max_level + 1 : 0;
}
return status ? j : -1;
}
-
+/* Local array size, used for stack-based local arrays */
+#define LOCAL_LIST_SIZE 128
FRIBIDI_ENTRY FriBidiLevel
fribidi_log2vis (
fribidi_boolean private_V_to_L = false;
fribidi_boolean private_embedding_levels = false;
fribidi_boolean status = false;
+ FriBidiArabicProp local_ar_props[LOCAL_LIST_SIZE];
FriBidiArabicProp *ar_props = NULL;
+ FriBidiLevel local_embedding_levels[LOCAL_LIST_SIZE];
+ FriBidiCharType local_bidi_types[LOCAL_LIST_SIZE];
FriBidiCharType *bidi_types = NULL;
+ FriBidiBracketType local_bracket_types[LOCAL_LIST_SIZE];
FriBidiBracketType *bracket_types = NULL;
+ FriBidiStrIndex local_positions_V_to_L[LOCAL_LIST_SIZE];
if UNLIKELY
(len == 0)
fribidi_assert (str);
fribidi_assert (pbase_dir);
- bidi_types = fribidi_malloc (len * sizeof bidi_types[0]);
+ if (len < LOCAL_LIST_SIZE)
+ bidi_types = local_bidi_types;
+ else
+ bidi_types = fribidi_malloc (len * sizeof bidi_types[0]);
if (!bidi_types)
goto out;
fribidi_get_bidi_types (str, len, bidi_types);
- bracket_types = fribidi_malloc (len * sizeof bracket_types[0]);
+ if (len < LOCAL_LIST_SIZE)
+ bracket_types = local_bracket_types;
+ else
+ bracket_types = fribidi_malloc (len * sizeof bracket_types[0]);
+
if (!bracket_types)
goto out;
bracket_types);
if (!embedding_levels)
{
- embedding_levels = fribidi_malloc (len * sizeof embedding_levels[0]);
+ if (len < LOCAL_LIST_SIZE)
+ embedding_levels = local_embedding_levels;
+ else
+ embedding_levels = fribidi_malloc (len * sizeof embedding_levels[0]);
if (!embedding_levels)
goto out;
private_embedding_levels = true;
given by the caller, we have to make a private instance of it. */
if (positions_L_to_V && !positions_V_to_L)
{
- positions_V_to_L =
+ if (len < LOCAL_LIST_SIZE)
+ positions_V_to_L = local_positions_V_to_L;
+ else
+ positions_V_to_L =
(FriBidiStrIndex *) fribidi_malloc (sizeof (FriBidiStrIndex) * len);
if (!positions_V_to_L)
goto out;
memcpy (visual_str, str, len * sizeof (*visual_str));
/* Arabic joining */
- ar_props = fribidi_malloc (len * sizeof ar_props[0]);
+ if (len < LOCAL_LIST_SIZE)
+ ar_props = local_ar_props;
+ else
+ ar_props = fribidi_malloc (len * sizeof ar_props[0]);
fribidi_get_joining_types (str, len, ar_props);
fribidi_join_arabic (bidi_types, len, embedding_levels, ar_props);
out:
- if (private_V_to_L)
+ if (private_V_to_L && positions_V_to_L != local_positions_V_to_L)
fribidi_free (positions_V_to_L);
- if (private_embedding_levels)
+ if (private_embedding_levels && embedding_levels != local_embedding_levels)
fribidi_free (embedding_levels);
- if (ar_props)
+ if (ar_props && ar_props != local_ar_props)
fribidi_free (ar_props);
- if (bidi_types)
+ if (bidi_types && bidi_types != local_bidi_types)
fribidi_free (bidi_types);
- if (bracket_types)
+ if (bracket_types && bracket_types != local_bracket_types)
fribidi_free (bracket_types);
return status ? max_level + 1 : 0;