diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2017-11-13 15:27:37 +0200 |
---|---|---|
committer | Khaled Hosny <khaledhosny@eglug.org> | 2018-02-04 02:46:36 +0200 |
commit | 0a71013dfc3a5199f0632bb99410523949bf49d7 (patch) | |
tree | ec2873db87e16fd06c85ea3c9383ccf708ba01ee /pango/mini-fribidi/fribidi.c | |
parent | 5e8cb02bec01e4a9b0ddff173889043d9db65fbc (diff) | |
download | pango-0a71013dfc3a5199f0632bb99410523949bf49d7.tar.gz |
Drop now unused mini-fribidi
Diffstat (limited to 'pango/mini-fribidi/fribidi.c')
-rw-r--r-- | pango/mini-fribidi/fribidi.c | 967 |
1 files changed, 0 insertions, 967 deletions
diff --git a/pango/mini-fribidi/fribidi.c b/pango/mini-fribidi/fribidi.c deleted file mode 100644 index cef814ca..00000000 --- a/pango/mini-fribidi/fribidi.c +++ /dev/null @@ -1,967 +0,0 @@ -/* FriBidi - Library of BiDi algorithm - * Copyright (C) 1999,2000 Dov Grobgeld, and - * Copyright (C) 2001,2002 Behdad Esfahbod. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library, in a file named COPYING; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307, USA - * - * For licensing issues, contact <dov@imagic.weizmann.ac.il> and - * <fwpg@sharif.edu>. - */ - -#include "config.h" -#include <stdlib.h> -#include <string.h> - -#include "fribidi.h" - -/* Redefine FRIBIDI_CHUNK_SIZE in config.h to override this. */ -#ifndef FRIBIDI_CHUNK_SIZE -#ifdef MEM_OPTIMIZED -#define FRIBIDI_CHUNK_SIZE 16 -#else -#define FRIBIDI_CHUNK_SIZE 128 -#endif -#endif - -#define DBG(s) -#define DBG2(s, t) - -/*====================================================================== - * Typedef for the run-length list. - *----------------------------------------------------------------------*/ -typedef struct _TypeLink TypeLink; - -struct _TypeLink -{ - TypeLink *prev; - TypeLink *next; - - FriBidiStrIndex pos, len; - FriBidiCharType type; - FriBidiLevel level; -}; - -#define FRIBIDI_LEVEL_START -1 -#define FRIBIDI_LEVEL_END -1 -#define FRIBIDI_LEVEL_REMOVED -2 - -typedef struct -{ - FriBidiCharType override; /* only L, R and N are valid */ - FriBidiLevel level; -} -LevelInfo; - -static TypeLink * -new_type_link (void) -{ - TypeLink *link; - - link = g_slice_new0 (TypeLink); - - return link; -} - -static void -free_type_link (TypeLink *link) -{ - g_slice_free (TypeLink, link); -} - -#define FRIBIDI_ADD_TYPE_LINK(p,q) \ - do { \ - (p)->len = (q)->pos - (p)->pos; \ - (p)->next = (q); \ - (q)->prev = (p); \ - (p) = (q); \ - } while (0) - -static TypeLink * -run_length_encode_types_utf8 (const char *s, - int bytelen, - FriBidiStrIndex *len, - FriBidiCharType *pored_types, - FriBidiCharType *panded_strongs) -{ - TypeLink *list, *last, *link; - FriBidiCharType char_type; - FriBidiCharType ored_types = 0; - FriBidiCharType anded_strongs = FRIBIDI_TYPE_RLE; - FriBidiStrIndex i; - const char *p; - - /* Add the starting link */ - list = new_type_link (); - list->type = FRIBIDI_TYPE_SOT; - list->level = FRIBIDI_LEVEL_START; - last = list; - - /* Sweep over the string s */ - i = 0; - for (p = s; p < s + bytelen; p = g_utf8_next_char(p)) { - char_type = fribidi_get_type (g_utf8_get_char (p)); - ored_types |= char_type; - if (FRIBIDI_IS_STRONG (char_type)) - anded_strongs &= char_type; - if (char_type != last->type) - { - link = new_type_link (); - link->type = char_type; - link->pos = i; - FRIBIDI_ADD_TYPE_LINK (last, link); - } - i++; - } - - /* Add the ending link */ - link = new_type_link (); - link->type = FRIBIDI_TYPE_EOT; - link->level = FRIBIDI_LEVEL_END; - link->pos = i; - FRIBIDI_ADD_TYPE_LINK (last, link); - - if (len) - *len = i; - - if (pored_types) - *pored_types = ored_types; - if (panded_strongs) - *panded_strongs = anded_strongs; - - return list; -} - -/* explicits_list is a list like type_rl_list, that holds the explicit - codes that are removed from rl_list, to reinsert them later by calling - the override_list. -*/ -static void -init_list (TypeLink **start, - TypeLink **end) -{ - TypeLink *list; - TypeLink *link; - - /* Add the starting link */ - list = new_type_link (); - list->type = FRIBIDI_TYPE_SOT; - list->level = FRIBIDI_LEVEL_START; - list->len = 0; - list->pos = 0; - - /* Add the ending link */ - link = new_type_link (); - link->type = FRIBIDI_TYPE_EOT; - link->level = FRIBIDI_LEVEL_END; - link->len = 0; - link->pos = 0; - list->next = link; - link->prev = list; - - *start = list; - *end = link; -} - -/* move an element before another element in a list, the list must have a - previous element, used to update explicits_list. - assuming that p have both prev and next or none of them, also update - the list that p is currently in, if any. -*/ -static void -move_element_before (TypeLink *p, - TypeLink *list) -{ - if (p->prev) - { - p->prev->next = p->next; - p->next->prev = p->prev; - } - p->prev = list->prev; - list->prev->next = p; - p->next = list; - list->prev = p; -} - -/* override the rl_list 'base', with the elements in the list 'over', to - reinsert the previously-removed explicit codes (at X9) from - 'explicits_list' back into 'type_rl_list'. This is used at the end of I2 - to restore the explicit marks, and also to reset the character types of - characters at L1. - - it is assumed that the 'pos' of the first element in 'base' list is not - more than the 'pos' of the first element of the 'over' list, and the - 'pos' of the last element of the 'base' list is not less than the 'pos' - of the last element of the 'over' list. these two conditions are always - satisfied for the two usages mentioned above. - - TBD: use some explanatory names instead of p, q, ... -*/ -static void -override_list (TypeLink *base, - TypeLink *over) -{ - TypeLink *p = base, *q, *r, *s, *t; - FriBidiStrIndex pos = 0, pos2; - - if (!over) - return; - q = over; - while (q) - { - if (!q->len || q->pos < pos) - { - t = q; - q = q->next; - free_type_link (t); - continue; - } - pos = q->pos; - while (p->next && p->next->pos <= pos) - p = p->next; - /* now p is the element that q must be inserted 'in'. */ - pos2 = pos + q->len; - r = p; - while (r->next && r->next->pos < pos2) - r = r->next; - /* now r is the last element that q affects. */ - if (p == r) - { - /* split p into at most 3 interval, and insert q in the place of - the second interval, set r to be the third part. */ - /* third part needed? */ - if (p->next && p->next->pos == pos2) - r = r->next; - else - { - r = new_type_link (); - *r = *p; - if (r->next) - { - r->next->prev = r; - r->len = r->next->pos - pos2; - } - else - r->len -= pos - p->pos; - r->pos = pos2; - } - /* first part needed? */ - if (p->prev && p->pos == pos) - { - t = p; - p = p->prev; - free_type_link (t); - } - else - p->len = pos - p->pos; - } - else - { - /* cut the end of p. */ - p->len = pos - p->pos; - /* if all of p is cut, remove it. */ - if (!p->len && p->prev) - p = p->prev; - - /* cut the begining of r. */ - r->pos = pos2; - if (r->next) - r->len = r->next->pos - pos2; - /* if all of r is cut, remove it. */ - if (!r->len && r->next) - r = r->next; - - /* remove the elements between p and r. */ - for (s = p->next; s != r;) - { - t = s; - s = s->next; - free_type_link (t); - } - } - /* before updating the next and prev links to point to the inserted q, - we must remember the next element of q in the 'over' list. - */ - t = q; - q = q->next; - p->next = t; - t->prev = p; - t->next = r; - r->prev = t; - } -} - -/* Some convenience macros */ -#define RL_TYPE(list) ((list)->type) -#define RL_LEN(list) ((list)->len) -#define RL_POS(list) ((list)->pos) -#define RL_LEVEL(list) ((list)->level) - -static TypeLink * -merge_with_prev (TypeLink *second) -{ - TypeLink *first = second->prev; - first->next = second->next; - first->next->prev = first; - RL_LEN (first) += RL_LEN (second); - free_type_link (second); - return first; -} - -static void -compact_list (TypeLink *list) -{ - if (list->next) - for (list = list->next; list; list = list->next) - if (RL_TYPE (list->prev) == RL_TYPE (list) - && RL_LEVEL (list->prev) == RL_LEVEL (list)) - list = merge_with_prev (list); -} - -static void -compact_neutrals (TypeLink *list) -{ - if (list->next) - { - for (list = list->next; list; list = list->next) - { - if (RL_LEVEL (list->prev) == RL_LEVEL (list) - && - ((RL_TYPE - (list->prev) == RL_TYPE (list) - || (FRIBIDI_IS_NEUTRAL (RL_TYPE (list->prev)) - && FRIBIDI_IS_NEUTRAL (RL_TYPE (list)))))) - list = merge_with_prev (list); - } - } -} - -/*====================================================================== - * Frees up the rl_list, must be called after each call to - * fribidi_analyse_string(), after the list is not needed anymore. - *----------------------------------------------------------------------*/ -static void -free_rl_list (TypeLink *type_rl_list) -{ - DBG ("Entering free_rl_list()\n"); - - if (!type_rl_list) - { - DBG ("Leaving free_rl_list()\n"); - return; - } - - g_slice_free_chain (TypeLink, type_rl_list, next); - - DBG ("Leaving free_rl_list()\n"); - return; -} - -/*========================================================================= - * define macros for push and pop the status in to / out of the stack - *-------------------------------------------------------------------------*/ - -/* There's some little points in pushing and poping into the status stack: - 1. when the embedding level is not valid (more than UNI_MAX_BIDI_LEVEL=61), - you must reject it, and not to push into the stack, but when you see a - PDF, you must find the matching code, and if it was pushed in the stack, - pop it, it means you must pop if and only if you have pushed the - matching code, the over_pushed var counts the number of rejected codes yet. - 2. there's a more confusing point too, when the embedding level is exactly - UNI_MAX_BIDI_LEVEL-1=60, an LRO or LRE must be rejected because the new - level would be UNI_MAX_BIDI_LEVEL+1=62, that is invalid, but an RLO or RLE - must be accepted because the new level is UNI_MAX_BIDI_LEVEL=61, that is - valid, so the rejected codes may be not continuous in the logical order, - in fact there is at most two continuous intervals of codes, with a RLO or - RLE between them. To support this case, the first_interval var counts the - number of rejected codes in the first interval, when it is 0, means that - there is only one interval yet. -*/ - -/* a. If this new level would be valid, then this embedding code is valid. - Remember (push) the current embedding level and override status. - Reset current level to this new level, and reset the override status to - new_override. - b. If the new level would not be valid, then this code is invalid. Don't - change the current level or override status. -*/ -#define PUSH_STATUS \ - do { \ - if (new_level <= UNI_MAX_BIDI_LEVEL) \ - { \ - if (level == UNI_MAX_BIDI_LEVEL - 1) \ - first_interval = over_pushed; \ - status_stack[stack_size].level = level; \ - status_stack[stack_size].override = override; \ - stack_size++; \ - level = new_level; \ - override = new_override; \ - } else \ - over_pushed++; \ - } while (0) - -/* If there was a valid matching code, restore (pop) the last remembered - (pushed) embedding level and directional override. -*/ -#define POP_STATUS \ - do { \ - if (over_pushed || stack_size) \ - { \ - if (over_pushed > first_interval) \ - over_pushed--; \ - else \ - { \ - if (over_pushed == first_interval) \ - first_interval = 0; \ - stack_size--; \ - level = status_stack[stack_size].level; \ - override = status_stack[stack_size].override; \ - } \ - } \ - } while (0) - -/*========================================================================== - * There was no support for sor and eor in the absence of Explicit Embedding - * Levels, so define macros, to support them, with as less change as needed. - *--------------------------------------------------------------------------*/ - -/* Return the type of previous char or the sor, if already at the start of - a run level. */ -#define PREV_TYPE_OR_SOR(pp) \ - ( \ - RL_LEVEL(pp->prev) == RL_LEVEL(pp) ? \ - RL_TYPE(pp->prev) : \ - FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->prev), RL_LEVEL(pp))) \ - ) - -/* Return the type of next char or the eor, if already at the end of - a run level. */ -#define NEXT_TYPE_OR_EOR(pp) \ - ( \ - !pp->next ? \ - FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(pp)) : \ - (RL_LEVEL(pp->next) == RL_LEVEL(pp) ? \ - RL_TYPE(pp->next) : \ - FRIBIDI_LEVEL_TO_DIR(MAX(RL_LEVEL(pp->next), RL_LEVEL(pp))) \ - ) \ - ) - - -/* Return the embedding direction of a link. */ -#define FRIBIDI_EMBEDDING_DIRECTION(list) \ - FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(list)) - - -/*====================================================================== - * This function should follow the Unicode specification closely! - *----------------------------------------------------------------------*/ -static fribidi_boolean -fribidi_analyse_string_utf8 ( /* input */ - const char *str, - int bytelen, - FriBidiCharType *pbase_dir, - /* output */ - FriBidiStrIndex *len, - TypeLink **ptype_rl_list, - FriBidiLevel *pmax_level) -{ - FriBidiLevel base_level, max_level; - FriBidiCharType base_dir; - TypeLink *type_rl_list, *explicits_list, *explicits_list_end, *pp; - - DBG ("Entering fribidi_analyse_string()\n"); - - /* Determinate character types */ - DBG (" Determine character types\n"); - { - FriBidiCharType ored_types; - FriBidiCharType anded_strongs; - - /* Run length encode the character types */ - type_rl_list = run_length_encode_types_utf8 (str, bytelen, len, - &ored_types, &anded_strongs); - - /* The case that all resolved levels will be ltr. - * First, all strongs should be ltr, there should be no Arabic numbers - * (or letters for that matter), and one of the following: - * - * o *pbase_dir doesn't have an rtl taste. - * o there are letters, and *pbase_dir is weak. - * - * For details see: - * https://bugzilla.gnome.org/show_bug.cgi?id=590183 - */ - if (!FRIBIDI_IS_RTL (ored_types) && !FRIBIDI_IS_ARABIC (ored_types) && - (!FRIBIDI_IS_RTL (*pbase_dir) || - (FRIBIDI_IS_WEAK (*pbase_dir) && FRIBIDI_IS_LETTER (ored_types)) - )) - { - /* all ltr */ - free_rl_list (type_rl_list); - - *ptype_rl_list = NULL; - *pmax_level = 0; - *pbase_dir = FRIBIDI_TYPE_LTR; - - return 0; - } - /* The case that all resolved levels will be rtl is much more complex. - * First, there should be no numbers, all strongs be rtl, and one of - * the following: - * - * o *pbase_dir has an rtl taste (may be weak). - * o there are letters, and *pbase_dir is weak. - */ - else if (!FRIBIDI_IS_NUMBER (ored_types) && FRIBIDI_IS_RTL (anded_strongs) && - (FRIBIDI_IS_RTL (*pbase_dir) || - (FRIBIDI_IS_WEAK (*pbase_dir) && FRIBIDI_IS_LETTER (ored_types)) - )) - { - free_rl_list (type_rl_list); - - *ptype_rl_list = NULL; - *pmax_level = 1; - *pbase_dir = FRIBIDI_TYPE_RTL; - - return 0; - } - } - DBG (" Determine character types, Done\n"); - - init_list (&explicits_list, &explicits_list_end); - - /* Find base level */ - DBG (" Finding the base level\n"); - if (FRIBIDI_IS_STRONG (*pbase_dir)) - base_level = FRIBIDI_DIR_TO_LEVEL (*pbase_dir); - /* P2. P3. Search for first strong character and use its direction as - base direction */ - else - { - /* If no strong base_dir was found, resort to the weak direction - that was passed on input. */ - base_level = FRIBIDI_DIR_TO_LEVEL (*pbase_dir); - base_dir = FRIBIDI_TYPE_ON; - for (pp = type_rl_list; pp; pp = pp->next) - if (FRIBIDI_IS_LETTER (RL_TYPE (pp))) - { - base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp)); - base_dir = FRIBIDI_LEVEL_TO_DIR (base_level); - break; - } - } - base_dir = FRIBIDI_LEVEL_TO_DIR (base_level); - DBG2 (" Base level : %c\n", fribidi_char_from_level (base_level)); - DBG2 (" Base dir : %c\n", fribidi_char_from_type (base_dir)); - DBG (" Finding the base level, Done\n"); - - /* Explicit Levels and Directions */ - DBG ("Explicit Levels and Directions\n"); - { - /* X1. Begin by setting the current embedding level to the paragraph - embedding level. Set the directional override status to neutral. - Process each character iteratively, applying rules X2 through X9. - Only embedding levels from 0 to 61 are valid in this phase. */ - FriBidiLevel level, new_level; - FriBidiCharType override, new_override; - FriBidiStrIndex i; - int stack_size, over_pushed, first_interval; - LevelInfo *status_stack; - TypeLink temp_link; - - level = base_level; - override = FRIBIDI_TYPE_ON; - /* stack */ - stack_size = 0; - over_pushed = 0; - first_interval = 0; - status_stack = - (LevelInfo *) malloc (sizeof (LevelInfo) * (UNI_MAX_BIDI_LEVEL + 2)); - - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType this_type = RL_TYPE (pp); - if (FRIBIDI_IS_EXPLICIT_OR_BN (this_type)) - { - if (FRIBIDI_IS_STRONG (this_type)) - { /* LRE, RLE, LRO, RLO */ - /* 1. Explicit Embeddings */ - /* X2. With each RLE, compute the least greater odd embedding level. */ - /* X3. With each LRE, compute the least greater even embedding level. */ - /* 2. Explicit Overrides */ - /* X4. With each RLO, compute the least greater odd embedding level. */ - /* X5. With each LRO, compute the least greater even embedding level. */ - new_override = FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR (this_type); - for (i = 0; i < RL_LEN (pp); i++) - { - new_level = - ((level + FRIBIDI_DIR_TO_LEVEL (this_type) + 2) & ~1) - - FRIBIDI_DIR_TO_LEVEL (this_type); - PUSH_STATUS; - } - } - else if (this_type == FRIBIDI_TYPE_PDF) - { - /* 3. Terminating Embeddings and overrides */ - /* X7. With each PDF, determine the matching embedding or - override code. */ - for (i = 0; i < RL_LEN (pp); i++) - POP_STATUS; - } - /* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */ - /* Remove element and add it to explicits_list */ - temp_link.next = pp->next; - pp->level = FRIBIDI_LEVEL_REMOVED; - move_element_before (pp, explicits_list_end); - pp = &temp_link; - } - else if (this_type == FRIBIDI_TYPE_BS) - { - /* X8. All explicit directional embeddings and overrides are - completely terminated at the end of each paragraph. Paragraph - separators are not included in the embedding. */ - break; - } - else - { - /* X6. For all typed besides RLE, LRE, RLO, LRO, and PDF: - a. Set the level of the current character to the current - embedding level. - b. Whenever the directional override status is not neutral, - reset the current character type to the directional override - status. */ - RL_LEVEL (pp) = level; - if (!FRIBIDI_IS_NEUTRAL (override)) - RL_TYPE (pp) = override; - } - } - - /* Implementing X8. It has no effect on a single paragraph! */ - level = base_level; - override = FRIBIDI_TYPE_ON; - stack_size = 0; - over_pushed = 0; - - free (status_stack); - } - /* 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 - end-of-level-run (eor) type, either L or R. This depends on the - higher of the two levels on either side of the boundary (at the start - or end of the paragraph, the level of the 'other' run is the base - embedding level). If the higher level is odd, the type is R, otherwise - it is L. */ - /* Resolving Implicit Levels can be done out of X10 loop, so only change - of Resolving Weak Types and Resolving Neutral Types is needed. */ - - compact_list (type_rl_list); - - /* 4. Resolving weak types */ - DBG ("Resolving weak types\n"); - { - FriBidiCharType last_strong, prev_type_org; - fribidi_boolean w4; - - last_strong = base_dir; - - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType prev_type, this_type, next_type; - - prev_type = PREV_TYPE_OR_SOR (pp); - this_type = RL_TYPE (pp); - next_type = NEXT_TYPE_OR_EOR (pp); - - if (FRIBIDI_IS_STRONG (prev_type)) - last_strong = prev_type; - - /* W1. NSM - Examine each non-spacing mark (NSM) in the level run, and change the - type of the NSM to the type of the previous character. If the NSM - is at the start of the level run, it will get the type of sor. */ - /* Implementation note: it is important that if the previous character - is not sor, then we should merge this run with the previous, - because of rules like W5, that we assume all of a sequence of - adjacent ETs are in one TypeLink. */ - if (this_type == FRIBIDI_TYPE_NSM) - { - if (RL_LEVEL (pp->prev) == RL_LEVEL (pp)) - pp = merge_with_prev (pp); - else - RL_TYPE (pp) = prev_type; - if (prev_type == next_type && RL_LEVEL (pp) == RL_LEVEL (pp->next)) - { - pp = merge_with_prev (pp->next); - } - continue; /* As we know the next condition cannot be true. */ - } - - /* W2: European numbers. */ - if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_AL) - { - RL_TYPE (pp) = FRIBIDI_TYPE_AN; - - /* Resolving dependency of loops for rules W1 and W2, so we - can merge them in one loop. */ - if (next_type == FRIBIDI_TYPE_NSM) - RL_TYPE (pp->next) = FRIBIDI_TYPE_AN; - } - } - - - last_strong = base_dir; - /* Resolving dependency of loops for rules W4 and W5, W5 may - want to prevent W4 to take effect in the next turn, do this - through "w4". */ - w4 = FRIBIDI_TRUE; - /* Resolving dependency of loops for rules W4 and W5 with W7, - W7 may change an EN to L but it sets the prev_type_org if needed, - so W4 and W5 in next turn can still do their works. */ - prev_type_org = FRIBIDI_TYPE_ON; - - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType prev_type, this_type, next_type; - - prev_type = PREV_TYPE_OR_SOR (pp); - this_type = RL_TYPE (pp); - next_type = NEXT_TYPE_OR_EOR (pp); - - if (FRIBIDI_IS_STRONG (prev_type)) - last_strong = prev_type; - - /* W3: Change ALs to R. */ - if (this_type == FRIBIDI_TYPE_AL) - { - RL_TYPE (pp) = FRIBIDI_TYPE_RTL; - w4 = FRIBIDI_TRUE; - prev_type_org = FRIBIDI_TYPE_ON; - continue; - } - - /* W4. A single european separator changes to a european number. - A single common separator between two numbers of the same type - changes to that type. */ - if (w4 - && RL_LEN (pp) == 1 && FRIBIDI_IS_ES_OR_CS (this_type) - && FRIBIDI_IS_NUMBER (prev_type_org) && prev_type_org == next_type - && (prev_type_org == FRIBIDI_TYPE_EN - || this_type == FRIBIDI_TYPE_CS)) - { - RL_TYPE (pp) = prev_type; - this_type = RL_TYPE (pp); - } - w4 = FRIBIDI_TRUE; - - /* W5. A sequence of European terminators adjacent to European - numbers changes to All European numbers. */ - if (this_type == FRIBIDI_TYPE_ET - && (prev_type_org == FRIBIDI_TYPE_EN - || next_type == FRIBIDI_TYPE_EN)) - { - RL_TYPE (pp) = FRIBIDI_TYPE_EN; - w4 = FRIBIDI_FALSE; - this_type = RL_TYPE (pp); - } - - /* W6. Otherwise change separators and terminators to other neutral. */ - if (FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR (this_type)) - RL_TYPE (pp) = FRIBIDI_TYPE_ON; - - /* W7. Change european numbers to L. */ - if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_LTR) - { - RL_TYPE (pp) = FRIBIDI_TYPE_LTR; - prev_type_org = (RL_LEVEL (pp) == RL_LEVEL (pp->next) ? - FRIBIDI_TYPE_EN : FRIBIDI_TYPE_ON); - } - else - prev_type_org = PREV_TYPE_OR_SOR (pp->next); - } - } - - compact_neutrals (type_rl_list); - - /* 5. Resolving Neutral Types */ - DBG ("Resolving neutral types\n"); - { - /* N1. and N2. - For each neutral, resolve it. */ - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType prev_type, this_type, next_type; - - /* "European and arabic numbers are treated as though they were R" - FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */ - this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE (pp)); - prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (PREV_TYPE_OR_SOR (pp)); - next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (NEXT_TYPE_OR_EOR (pp)); - - if (FRIBIDI_IS_NEUTRAL (this_type)) - RL_TYPE (pp) = (prev_type == next_type) ? - /* N1. */ prev_type : - /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp); - } - } - - compact_list (type_rl_list); - - /* 6. Resolving implicit levels */ - DBG ("Resolving implicit levels\n"); - { - max_level = base_level; - - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiCharType this_type; - int level; - - this_type = RL_TYPE (pp); - level = RL_LEVEL (pp); - - /* I1. Even */ - /* I2. Odd */ - if (FRIBIDI_IS_NUMBER (this_type)) - RL_LEVEL (pp) = (level + 2) & ~1; - else - RL_LEVEL (pp) = (level ^ FRIBIDI_DIR_TO_LEVEL (this_type)) + - (level & 1); - - if (RL_LEVEL (pp) > max_level) - max_level = RL_LEVEL (pp); - } - } - - compact_list (type_rl_list); - -/* Reinsert the explicit codes & bn's that already removed, from the - explicits_list to type_rl_list. */ - DBG ("Reinserting explicit codes\n"); - { - TypeLink *p; - - override_list (type_rl_list, explicits_list); - p = type_rl_list->next; - if (p->level < 0) - p->level = base_level; - for (; p->next; p = p->next) - if (p->level < 0) - p->level = p->prev->level; - } - - DBG ("Reset the embedding levels\n"); - { - int j, k, state, pos; - TypeLink *p, *q, *list, *list_end; - - const char *strp = str + bytelen; - - /* L1. Reset the embedding levels of some chars. */ - init_list (&list, &list_end); - q = list_end; - state = 1; - pos = *len - 1; - for (j = *len - 1; j >= -1; j--) - { - /* if state is on at the very first of string, do this too. */ - if (j >= 0) - k = fribidi_get_type (g_utf8_get_char (strp = g_utf8_prev_char (strp))); - else - k = FRIBIDI_TYPE_ON; - if (!state && FRIBIDI_IS_SEPARATOR (k)) - { - state = 1; - pos = j; - } - else if (state && !FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS (k)) - { - state = 0; - p = new_type_link (); - p->prev = p->next = NULL; - p->pos = j + 1; - p->len = pos - j; - p->type = base_dir; - p->level = base_level; - move_element_before (p, q); - q = p; - } - } - override_list (type_rl_list, list); - } - - *ptype_rl_list = type_rl_list; - *pmax_level = max_level; - *pbase_dir = base_dir; - - DBG ("Leaving fribidi_analyse_string()\n"); - return 1; -} - -/*====================================================================== - * fribidi_log2vis_get_embedding_levels() is used in order to just get - * the embedding levels. - *----------------------------------------------------------------------*/ -FRIBIDI_API FriBidiLevel * -fribidi_log2vis_get_embedding_levels_new_utf8 ( /* input */ - const char *str, - int bytelen, - FriBidiCharType *pbase_dir) -{ - TypeLink *type_rl_list, *pp; - FriBidiLevel max_level, *embedding_level_list; - FriBidiStrIndex len; - - DBG ("Entering fribidi_log2vis_get_embedding_levels()\n"); - - if (bytelen == 0) - { - DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n"); - return NULL; - } - - if (!fribidi_analyse_string_utf8 (str, bytelen, pbase_dir, - /* output */ - &len, &type_rl_list, &max_level)) - { - /* unidirectional. return all-zero or all-one embedding levels */ - - if (max_level) - { - embedding_level_list = g_new (FriBidiLevel, len); - /* assumes sizeof(FriBidiLevel) == 1, which is true! */ - memset (embedding_level_list, max_level, len); - return embedding_level_list; - } - else - { - return g_new0 (FriBidiLevel, len); - } - } - - embedding_level_list = g_new (FriBidiLevel, len); - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiStrIndex i, pos = RL_POS (pp), len = RL_LEN (pp); - FriBidiLevel level = RL_LEVEL (pp); - for (i = 0; i < len; i++) - embedding_level_list[pos + i] = level; - } - - free_rl_list (type_rl_list); - - DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n"); - return embedding_level_list; -} - |