new implementation of UNICODE BIDIRECTIONAL ALGORITHM

This commit is contained in:
Vincent Wei
2019-03-08 20:38:04 +08:00
parent cc01ce0bbc
commit 27e508848d
2 changed files with 2024 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+263
View File
@@ -0,0 +1,263 @@
/*
* This file is part of MiniGUI, a mature cross-platform windowing
* and Graphics User Interface (GUI) support system for embedded systems
* and smart IoT devices.
*
* Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd.
* Copyright (C) 1998~2002, WEI Yongming
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Or,
*
* As this program is a library, any link to this program must follow
* GNU General Public License version 3 (GPLv3). If you cannot accept
* GPLv3, you need to be licensed from FMSoft.
*
* If you have got a commercial license of this program, please use it
* under the terms and conditions of the commercial license.
*
* For more information about the commercial license, please refer to
* <http://www.minigui.com/en/about/licensing-policy/>.
*/
/*
** general-bidi.h:
**
** A general implementation of UNICODE BIDIRECTIONAL ALGORITHM
**
** https://www.unicode.org/reports/tr9/
**
** Created by WEI Yongming at 2019/03/08
**
** This implementation is based on LGPL'd Bidi:
**
** https://github.com/gbidi/gbidi
**
** Authors:
** Behdad Esfahbod, 2001, 2002, 2004
** Dov Grobgeld, 1999, 2000, 2017
**
** Copyright (C) 2004 Sharif FarsiWeb, Inc
** Copyright (C) 2001,2002 Behdad Esfahbod
** Copyright (C) 1999,2000,2017 Dov Grobgeld
*/
#ifndef _MGFONT_GENERAL_BIDI_H
#define _MGFONT_GENERAL_BIDI_H
/* A few macros for working with bits */
#define BIDI_TEST_BITS(x, mask) (((x) & (mask)) ? 1 : 0)
#define BIDI_INCLUDE_BITS(x, mask) ((x) | (mask))
#define BIDI_EXCLUDE_BITS(x, mask) ((x) & ~(mask))
#define BIDI_SET_BITS(x, mask) ((x) |= (mask))
#define BIDI_UNSET_BITS(x, mask) ((x) &= ~(mask))
#define BIDI_ADJUST_BITS(x, mask, cond) \
((x) = ((x) & ~(mask)) | ((cond) ? (mask) : 0))
#define BIDI_ADJUST_AND_TEST_BITS(x, mask, cond) \
BIDI_TEST_BITS(BIDI_ADJUST_BITS((x), (mask), (cond)), (mask))
/* The maximum embedding level value assigned by explicit marks */
#define BIDI_MAX_EXPLICIT_LEVEL 125
/* The maximum *number* of different resolved embedding levels: 0-126 */
#define BIDI_MAX_RESOLVED_LEVELS 127
/* The maximum *number* of nested brackets: 0-63 */
#define BIDI_MAX_NESTED_BRACKET_PAIRS 63
#define BIDI_SENTINEL -1
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
typedef struct _BidiRun BidiRun;
struct _BidiRun {
BidiRun *prev;
BidiRun *next;
/* Additional links for connecting the isolate tree */
BidiRun *prev_isolate;
BidiRun *next_isolate;
int pos, len;
BidiType type;
BidiLevel level;
BidiLevel isolate_level;
Uint8 bracket_type;
};
#define swap(a,b) \
do { \
void *t; \
(t) = (a); \
(a) = (b); \
(b) = (t); \
} while(0)
#define merge_lists(a,b) \
do { \
swap((a)->prev->next, (b)->prev->next); \
swap((a)->prev, (b)->prev); \
} while(0)
#define delete_node(x) \
do { \
(x)->prev->next = (x)->next; \
(x)->next->prev = (x)->prev; \
} while(0)
#define insert_node_before(x, list) \
do { \
(x)->prev = (list)->prev; \
(list)->prev->next = (x); \
(x)->next = (list); \
(list)->prev = (x); \
} while(0)
#define move_node_before(x, list) \
do { \
if ((x)->prev) { \
delete_node(x); \
} \
insert_node_before((x), (list)); \
} while(0)
#define for_run_list(x, list) \
for ((x) = (list)->next; (x)->type != BIDI_TYPE_SENTINEL; (x) = (x)->next)
/**
* \fn gbidi_get_paragraph_dir
* \brief get base paragraph direction
*
* This function finds the base direction of a single paragraph,
* as defined by rule P2 of the Unicode Bidirectional Algorithm available at
* http://www.unicode.org/reports/tr9/#P2.
*
* You typically do not need this function as
* gbidi_get_paragraph_els() knows how to compute base direction
* itself, but you may need this to implement a more sophisticated paragraph
* direction handling. Note that you can pass more than a paragraph to this
* function and the direction of the first non-neutral paragraph is returned,
* which is a very good heuristic to set direction of the neutral paragraphs
* at the beginning of text. For other neutral paragraphs, you better use the
* direction of the previous paragraph.
*
* \param bidi_types the pointer to the BidiType array as returned by
* gbidi_get_bidi_types()
* \param len The length of bidi_types
*
* \return Base pargraph direction. No weak paragraph direction is returned,
* only BIDI_PGDIR_LTR, BIDI_PGDIR_RTL, or BIDI_PGDIR_ON.
*
*/
int gbidi_get_paragraph_dir(const BidiType *bidi_types, int len);
/* gbidi_get_paragraph_els_ex - get bidi embedding levels of a paragraph
*
* This function finds the bidi embedding levels of a single paragraph,
* as defined by the Unicode Bidirectional Algorithm available at
* http://www.unicode.org/reports/tr9/.
*
* This function implements rules P2 to I1 inclusive, and parts 1 to 3 of L1,
* except for rule X9 which is implemented in gbidi_remove_bidi_marks().
* Part 4 of L1 is implemented in gbidi_reorder_line().
*
* There are a few macros defined in gbidi-bidi-types.h to work with this
* embedding levels.
*
* \param bidi_types the pointer to the BidiType array as returned by
* gbidi_get_bidi_types()
* \param bracket_types The pointer to a Uint8 which contains the
bracket types as returned by gbidi_get_bracket_types()
* \param len The length of the list.
* \param base_dir requested and resolved paragraph base direction
* \param embedding_levels The pointer to a buffer which will restore
* the embedding levels
*
* \return The Maximum level found plus one, or zero if any error occurred
* (memory allocation failure most probably).
*/
BidiLevel gbidi_get_paragraph_els_ex(const BidiType *bidi_types,
const Uint8* bracket_types, int len,
int *base_dir, BidiLevel *embedding_levels);
/* gbidi_reorder_line - reorder a line of logical string to visual
*
* This function reorders the characters in a line of text from logical to
* final visual order.
*
* This function implements part 4 of rule L1, and rules
* L2 and L3 of the Unicode Bidirectional Algorithm available at
* http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels.
*
* As a side effect it also sets position maps if not NULL.
*
* You should provide the resolved paragraph direction and embedding levels as
* set by gbidi_get_paragraph_els(). Also note that the embedding
* levels may change a bit. To be exact, the embedding level of any sequence
* of white space at the end of line is reset to the paragraph embedding level
* (That is part 4 of rule L1).
*
* Note that the bidi types and embedding levels are not reordered.
* You can reorder these (or any other) arrays using the map later.
* The user is responsible to initialize map to something sensible,
* like an identity mapping, or pass NULL if no map is needed.
*
* There is an optional part to this function, which is whether non-spacing
* marks for right-to-left parts of the text should be reordered to come after
* their base characters in the visual string or not.
*
* Most rendering engines expect this behavior, but console-based systems
* for example do not like it. This is controlled by the
* BIDI_FLAG_REORDER_NSM flag. The flag is on in BIDI_FLAGS_DEFAULT.
*
* \param flags The reorder flags.
* \param bidi_types the pointer to the BidiType array as returned by
* gbidi_get_bidi_types()
* \param bracket_types The pointer to a Uint8 which contains the
bracket types as returned by gbidi_get_bracket_types()
* \param len The length of the list.
* \param off The input offset of the beginning of the line in the paragraph.
* \param base_dir The resolved paragraph base direction.
* \param embedding_levels The embedding levels, as returned by
gbidi_get_paragraph_els()
* \param visual_str
* \param extra The pointer to the extra array to reorder; can be NULL.
* \param cb_reverse_extra The callback function to reverse the extra array.
* \param map a map of string indices which is reordered to reflect
* where each glyph ends up.
*
* \return Maximum level found in this line plus one, or zero if any error
* occurred (memory allocation failure most probably).
*/
BidiLevel gbidi_reorder_line(Uint32 flags, const BidiType *bidi_types,
int len, int off, int base_dir, BidiLevel *embedding_levels,
Achar32 *visual_str, int *map,
void* extra, CB_REVERSE_EXTRA cb_reverse_extra);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* !_MGFONT_GENERAL_BIDI_H */