Implementation of UBidiXXX functions

This commit is contained in:
Vincent Wei
2019-03-11 15:47:48 +08:00
parent 5dd2a21919
commit ca9d0200f3
9 changed files with 944 additions and 61 deletions
+3 -1
View File
@@ -13,7 +13,9 @@ SRC_FILES = charset.c charset-arabic.c legacy-bidi.c \
mapunitogb.c mapunitogbk.c mapunitobig5.c mapunitogb18030.c \
bitmapfont.c scripteasy.c \
unicode-emoji.c \
unicode-bidi.c
unicode-bidi.c \
unicode-joining-types.c unicode-joining.c unicode-shape.c \
unicode-shape-arabic.c
HDR_FILES = charset.h rawbitmap.h varbitmap.h freetype2.h qpf.h se_minigui.h \
upf.h bitmapfont.h unicode-bidi-tables.h \
+3 -3
View File
@@ -3608,7 +3608,7 @@ BidiType GUIAPI UCharGetBidiType(Uchar32 uc)
return linear_enum_to_bidi_type[UNIBIDI_GET_BIDI_TYPE(uc)];
}
void GUIAPI UCharGetBidiTypes(const Uchar32 *str, int len, BidiType *btypes)
void GUIAPI UStrGetBidiTypes(const Uchar32 *str, int len, BidiType *btypes)
{
register int i = len;
for (; i; i--) {
@@ -3650,7 +3650,7 @@ BidiBracketType UCharGetBracketType(Uchar32 ch)
return bracket_type;
}
void UCharGetBracketTypes(const Uchar32 *str, int len,
void UStrGetBracketTypes(const Uchar32 *str, int len,
const BidiType *types, BidiBracketType *btypes)
{
int i;
@@ -3773,7 +3773,7 @@ found:
return bracket_type;
}
void GUIAPI UCharGetBidiTypes(const Uchar32 *str, int len, BidiType *btypes)
void GUIAPI UStrGetBidiTypes(const Uchar32 *str, int len, BidiType *btypes)
{
register int i = len;
for (; i; i--) {
+7 -7
View File
@@ -644,7 +644,7 @@ static void print_pairing_nodes(BidiPairingNode *nodes)
#define BIDI_EMBEDDING_DIRECTION(link) \
BIDI_LEVEL_TO_DIR(RL_LEVEL(link))
int UCharGetParagraphDir(const BidiType *bidi_types, const int len)
int UBidiGetParagraphDir(const BidiType *bidi_types, const int len)
{
register int i;
@@ -738,7 +738,7 @@ static void free_pairing_nodes(BidiPairingNode *nodes)
}
}
BidiLevel UCharGetParagraphEmbeddingLevels(const BidiType *bidi_types,
BidiLevel UBidiGetParagraphEmbeddingLevels(const BidiType *bidi_types,
const BidiBracketType *bracket_types, const int len,
int *pbase_dir, BidiLevel *embedding_levels)
{
@@ -754,7 +754,7 @@ BidiLevel UCharGetParagraphEmbeddingLevels(const BidiType *bidi_types,
goto out;
}
_DBG_PRINTF ("in UCharGetParagraphEmbeddingLevels");
_DBG_PRINTF ("in UBidiGetParagraphEmbeddingLevels");
/* Determinate character types */
{
@@ -1507,7 +1507,7 @@ BidiLevel UCharGetParagraphEmbeddingLevels(const BidiType *bidi_types,
separator or paragraph separator, and
4. any sequence of whitespace characters and/or isolate formatting
characters at the end of the line.
... (to be continued in UCharReorderBidiLine()). */
... (to be continued in UBidiReorderLine()). */
list = new_run_list ();
if (!list) goto out;
q = list;
@@ -1566,7 +1566,7 @@ BidiLevel UCharGetParagraphEmbeddingLevels(const BidiType *bidi_types,
status = TRUE;
out:
_DBG_PRINTF ("leaving UCharGetParagraphEmbeddingLevels");
_DBG_PRINTF ("leaving UBidiGetParagraphEmbeddingLevels");
if (main_run_list)
free_run_list (main_run_list);
@@ -1599,7 +1599,7 @@ static void index_array_reverse (int *arr, int len)
}
}
BidiLevel UCharReorderBidiLine(Uint32 flags,
BidiLevel UBidiReorderLine(Uint32 flags,
const BidiType *bidi_types, int len, int off,
int base_dir, BidiLevel *embedding_levels,
Uchar32 *visual_str, int *map,
@@ -1613,7 +1613,7 @@ BidiLevel UCharReorderBidiLine(Uint32 flags,
goto out;
}
_DBG_PRINTF ("in UCharReorderBidiLine");
_DBG_PRINTF ("in UBidiReorderLine");
_DBG_PRINTF ("reset the embedding levels, 4. whitespace at the end of line");
{
+184 -1
View File
@@ -55,6 +55,41 @@
#define UNIBIDI_UNICODE_CHARS 0xFFFE
#endif
/* Some special Unicode characters */
/* Bidirectional marks */
#define BIDI_CHAR_LRM 0x200E
#define BIDI_CHAR_RLM 0x200F
#define BIDI_CHAR_LRE 0x202A
#define BIDI_CHAR_RLE 0x202B
#define BIDI_CHAR_PDF 0x202C
#define BIDI_CHAR_LRO 0x202D
#define BIDI_CHAR_RLO 0x202E
#define BIDI_CHAR_LRI 0x2066
#define BIDI_CHAR_RLI 0x2067
#define BIDI_CHAR_FSI 0x2068
#define BIDI_CHAR_PDI 0x2069
/* Line and Paragraph Separators */
#define BIDI_CHAR_LS 0x2028
#define BIDI_CHAR_PS 0x2029
/* Arabic Joining marks */
#define BIDI_CHAR_ZWNJ 0x200C
#define BIDI_CHAR_ZWJ 0x200D
/* Hebrew and Arabic */
#define BIDI_CHAR_HEBREW_ALEF 0x05D0
#define BIDI_CHAR_ARABIC_ALEF 0x0627
#define BIDI_CHAR_ARABIC_ZERO 0x0660
#define BIDI_CHAR_PERSIAN_ZERO 0x06F0
/* Misc */
#define BIDI_CHAR_ZWNBSP 0xFEFF
/* Char we place for a deleted slot, to delete later */
#define BIDI_CHAR_FILL BIDI_CHAR_ZWNBSP
/* some general macros */
#define STRINGIZE(symbol) #symbol
@@ -84,7 +119,155 @@
/* The maximum *number* of nested brackets: 0-63 */
#define BIDI_MAX_NESTED_BRACKET_PAIRS 63
#define BIDI_SENTINEL -1
#define BIDI_SENTINEL -1
/*
* Define bit masks that joining types are based on, each mask has
* only one bit set.
*/
#define BIDI_MASK_JOINS_RIGHT 0x01 /* May join to right */
#define BIDI_MASK_JOINS_LEFT 0x02 /* May join to right */
#define BIDI_MASK_ARAB_SHAPES 0x04 /* May Arabic shape */
#define BIDI_MASK_TRANSPARENT 0x08 /* Is transparent */
#define BIDI_MASK_IGNORED 0x10 /* Is ignored */
#define BIDI_MASK_LIGATURED 0x20 /* Is ligatured */
/*
* Define values for FriBidiJoiningType
*/
/* nUn-joining */
#define BIDI_JOINING_TYPE_U_VAL ( 0 )
/* Right-joining */
#define BIDI_JOINING_TYPE_R_VAL \
( BIDI_MASK_JOINS_RIGHT | BIDI_MASK_ARAB_SHAPES )
/* Dual-joining */
#define BIDI_JOINING_TYPE_D_VAL \
( BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT \
| BIDI_MASK_ARAB_SHAPES )
/* join-Causing */
#define BIDI_JOINING_TYPE_C_VAL \
( BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT )
/* Left-joining */
#define BIDI_JOINING_TYPE_L_VAL \
( BIDI_MASK_JOINS_LEFT | BIDI_MASK_ARAB_SHAPES )
/* Transparent */
#define BIDI_JOINING_TYPE_T_VAL \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_ARAB_SHAPES )
/* iGnored */
#define BIDI_JOINING_TYPE_G_VAL ( BIDI_MASK_IGNORED )
enum _BidiJoiningTypeEnum {
# define _UNIBIDI_ADD_TYPE(TYPE,SYMBOL) \
BIDI_JOINING_TYPE_##TYPE = BIDI_JOINING_TYPE_##TYPE##_VAL,
# include "unicode-joining-types-list.inc"
# undef _UNIBIDI_ADD_TYPE
_UNIBIDI_JOINING_TYPE_JUNK /* Don't use this */
};
/*
* The equivalent of JoiningType values for ArabicProp
*/
/* Primary Arabic Joining Classes (Table 8-2) */
/* nUn-joining */
#define BIDI_IS_JOINING_TYPE_U(p) \
( 0 == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT ) ) )
/* Right-joining */
#define BIDI_IS_JOINING_TYPE_R(p) \
( BIDI_MASK_JOINS_RIGHT == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT ) ) )
/* Dual-joining */
#define BIDI_IS_JOINING_TYPE_D(p) \
( ( BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT \
| BIDI_MASK_ARAB_SHAPES ) == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT \
| BIDI_MASK_ARAB_SHAPES ) ) )
/* join-Causing */
#define BIDI_IS_JOINING_TYPE_C(p) \
( ( BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT ) == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT \
| BIDI_MASK_ARAB_SHAPES ) ) )
/* Left-joining */
#define BIDI_IS_JOINING_TYPE_L(p) \
( BIDI_MASK_JOINS_LEFT == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT ) ) )
/* Transparent */
#define BIDI_IS_JOINING_TYPE_T(p) \
( BIDI_MASK_TRANSPARENT == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED ) ) )
/* iGnored */
#define BIDI_IS_JOINING_TYPE_G(p) \
( BIDI_MASK_IGNORED == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED ) ) )
/* and for Derived Arabic Joining Classes (Table 8-3) */
/* Right join-Causing */
#define BIDI_IS_JOINING_TYPE_RC(p) \
( BIDI_MASK_JOINS_RIGHT == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_JOINS_RIGHT ) ) )
/* Left join-Causing */
#define BIDI_IS_JOINING_TYPE_LC(p) \
( BIDI_MASK_JOINS_LEFT == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_JOINS_LEFT ) ) )
/*
* Defining macros for needed queries, It is fully dependent on the
* implementation of FriBidiJoiningType.
*/
/* Joins to right: R, D, C? */
#define BIDI_JOINS_RIGHT(p) ((p) & BIDI_MASK_JOINS_RIGHT)
/* Joins to left: L, D, C? */
#define BIDI_JOINS_LEFT(p) ((p) & BIDI_MASK_JOINS_LEFT)
/* May shape: R, D, L, T? */
#define BIDI_ARAB_SHAPES(p) ((p) & BIDI_MASK_ARAB_SHAPES)
/* Is skipped in joining: T, G? */
#define BIDI_IS_JOIN_SKIPPED(p) \
((p) & (BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED))
/* Is base that will be shaped: R, D, L? */
#define BIDI_IS_JOIN_BASE_SHAPES(p) \
( BIDI_MASK_ARAB_SHAPES == ( (p) & \
( BIDI_MASK_TRANSPARENT | BIDI_MASK_IGNORED \
| BIDI_MASK_ARAB_SHAPES ) ) )
#define BIDI_JOINS_PRECEDING_MASK(level) \
(BIDI_LEVEL_IS_RTL (level) ? BIDI_MASK_JOINS_RIGHT \
: BIDI_MASK_JOINS_LEFT)
#define BIDI_JOINS_FOLLOWING_MASK(level) \
(BIDI_LEVEL_IS_RTL (level) ? BIDI_MASK_JOINS_LEFT \
: BIDI_MASK_JOINS_RIGHT)
#define BIDI_JOIN_SHAPE(p) \
((p) & ( BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT ))
#ifdef __cplusplus
extern "C" {
+84
View File
@@ -0,0 +1,84 @@
/*
* 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/>.
*/
/*
** unicode-joining-types.c: character joining types
**
** Created by WEI Yongming at 2019/03/11
**
** This implementation is based on LGPL'd FriBidi:
**
** https://github.com/fribidi/fribidi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "common.h"
#ifdef _MGCHARSET_UNICODE
#include "minigui.h"
#include "gdi.h"
#include "unicode-bidi.h"
enum _BidiJoiningTypeShortEnum {
#define _UNIBIDI_ADD_TYPE(TYPE,SYMBOL) TYPE = BIDI_JOINING_TYPE_##TYPE,
#include "unicode-joining-types-list.inc"
#undef _UNIBIDI_ADD_TYPE
_UNIBIDI_NUM_TYPES
};
#include "unicode-joining-type-table.inc"
BidiJoiningType GUIAPI UCharGetJoiningType(Uchar32 ch)
{
return UNIBIDI_GET_JOINING_TYPE (ch);
}
void GUIAPI UStrGetJoiningTypes (const Uchar32 *ucs,
BidiJoiningType *joining_types, int len)
{
register int i = len;
for (; i; i--) {
*joining_types++ = UNIBIDI_GET_JOINING_TYPE (*ucs);
ucs++;
}
}
#endif /* _MGCHARSET_UNICODE */
+199
View File
@@ -0,0 +1,199 @@
/*
* 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/>.
*/
/*
** unicode-joining.c:
** The implementation of Arabic joining algorithm
**
** Created by WEI Yongming at 2019/03/11
**
** This implementation is based on LGPL'd FriBidi:
**
** https://github.com/fribidi/fribidi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "common.h"
#ifdef _MGCHARSET_UNICODE
#include "minigui.h"
#include "gdi.h"
#include "unicode-bidi.h"
#ifdef DEBUG
/*======================================================================
* For debugging, define some functions for printing joining types and
* properties.
*----------------------------------------------------------------------*/
static char get_char_from_joining_type(BidiJoiningType j, BOOL visual)
{
/* switch left and right if on visual run */
if (visual & ((BIDI_JOINS_RIGHT (j) && !BIDI_JOINS_LEFT (j)) |
(!BIDI_JOINS_RIGHT (j) && BIDI_JOINS_LEFT (j))))
j ^= BIDI_MASK_JOINS_RIGHT | BIDI_MASK_JOINS_LEFT;
# define _BIDI_ADD_TYPE(TYPE,SYMBOL) \
if (BIDI_IS_JOINING_TYPE_##TYPE(j)) return SYMBOL;
# include "fribidi-joining-types-list.h"
# undef _BIDI_ADD_TYPE
return '?';
}
static void print_joining_types(const BidiLevel *embedding_levels,
int len, const BidiJoiningType *jtypes)
{
register int i;
_DBG_PRINTF (" Join. types: ");
for (i = 0; i < len; i++)
_DBG_PRINTF2 ("%c", get_char_from_joining_type (jtypes[i],
!BIDI_LEVEL_IS_RTL(embedding_levels[i])));
_DBG_PRINTF ("\n");
}
#endif /* DEBUG */
#define UNIBIDI_CONSISTENT_LEVEL(i) \
(BIDI_IS_EXPLICIT_OR_BN (bidi_types[(i)]) \
? BIDI_SENTINEL \
: embedding_levels[(i)])
#define BIDI_LEVELS_MATCH(i, j) \
((i) == (j) || (i) == BIDI_SENTINEL || (j) == BIDI_SENTINEL)
void GUIAPI UBidiJoinArabic(const BidiType *bidi_types,
const BidiLevel *embedding_levels,
BidiArabicProp *ar_props, int len)
{
if (len == 0) return;
_DBG_PRINTF ("in fribidi_join_arabic");
#ifdef DEBUG
print_joining_types (embedding_levels, len, ar_props);
#endif /* DEBUG */
/* The joining algorithm turned out very very dirty :(. That's what happens
* when you follow the standard which has never been implemented closely
* before.
*/
/* 8.2 Arabic - Cursive Joining */
_DBG_PRINTF ("Arabic cursive joining");
{
/* The following do not need to be initialized as long as joins is
* initialized to FALSE. We just do to turn off compiler warnings. */
register int saved = 0;
register BidiLevel saved_level = BIDI_SENTINEL;
register BOOL saved_shapes = FALSE;
register BidiArabicProp saved_joins_following_mask = 0;
register BOOL joins = FALSE;
register int i;
for (i = 0; i < len; i++)
if (!BIDI_IS_JOINING_TYPE_G (ar_props[i]))
{
register BOOL disjoin = FALSE;
register BOOL shapes = BIDI_ARAB_SHAPES (ar_props[i]);
register BidiLevel level = UNIBIDI_CONSISTENT_LEVEL (i);
if (joins && !BIDI_LEVELS_MATCH (saved_level, level))
{
disjoin = TRUE;
joins = FALSE;
}
if (!BIDI_IS_JOIN_SKIPPED (ar_props[i]))
{
register const BidiArabicProp joins_preceding_mask =
BIDI_JOINS_PRECEDING_MASK (level);
if (!joins)
{
if (shapes)
BIDI_UNSET_BITS (ar_props[i], joins_preceding_mask);
}
else if (!BIDI_TEST_BITS (ar_props[i], joins_preceding_mask))
{
disjoin = TRUE;
}
else
{
register int j;
/* This is a FriBidi extension: we set joining properties
* for skipped characters in between, so we can put NSMs on tatweel
* later if we want. Useful on console for example.
*/
for (j = saved + 1; j < i; j++)
BIDI_SET_BITS (ar_props[j], joins_preceding_mask | saved_joins_following_mask);
}
}
if (disjoin && saved_shapes)
BIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);
if (!BIDI_IS_JOIN_SKIPPED (ar_props[i]))
{
saved = i;
saved_level = level;
saved_shapes = shapes;
saved_joins_following_mask =
BIDI_JOINS_FOLLOWING_MASK (level);
joins =
BIDI_TEST_BITS (ar_props[i], saved_joins_following_mask);
}
}
if ((joins) && saved_shapes)
BIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);
}
#ifdef DEBUG
print_joining_types (embedding_levels, len, ar_props);
#endif /* DEBUG */
_DBG_PRINTF ("leaving fribidi_join_arabic");
}
#endif /* _MGCHARSET_UNICODE */
+168
View File
@@ -0,0 +1,168 @@
/*
* 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/>.
*/
/*
** unicode-shape-arabic.c:
** The implementation of Arabic joining algorithm
**
** Created by WEI Yongming at 2019/03/11
**
** This implementation is based on LGPL'd FriBidi:
**
** https://github.com/fribidi/fribidi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "common.h"
#ifdef _MGCHARSET_UNICODE
#include "minigui.h"
#include "gdi.h"
#include "unicode-bidi.h"
typedef struct _PairMap {
Uchar32 pair[2], to;
} PairMap;
#define UNIBIDI_ACCESS_SHAPE_TABLE(table,min,max,x,shape) (table), (min), (max)
# define UNIBIDI_ACCESS_SHAPE_TABLE_REAL(table,min,max,x,shape) \
(((x)<(min)||(x)>(max))?(x):(table)[(x)-(min)][(shape)])
#include "unicode-arabic-shaping-table.inc"
#include "unicode-arabic-misc-table.inc"
static void unibidi_shape_arabic_joining (const Uchar32 table[][4],
Uchar32 min, Uchar32 max,
const int len,
const BidiArabicProp *ar_props,
Uchar32 *str)
{
register int i;
for (i = 0; i < len; i++) {
if (BIDI_ARAB_SHAPES(ar_props[i]))
str[i] = UNIBIDI_ACCESS_SHAPE_TABLE_REAL(table, min, max, str[i],
BIDI_JOIN_SHAPE (ar_props[i]));
}
}
static int comp_PairMap (const void *pa, const void *pb)
{
PairMap *a = (PairMap *)pa;
PairMap *b = (PairMap *)pb;
if (a->pair[0] != b->pair[0])
return a->pair[0] < b->pair[0] ? -1 : +1;
else
return a->pair[1] < b->pair[1] ? -1 :
a->pair[1] > b->pair[1] ? +1 : 0;
}
static Uchar32 find_pair_match (const PairMap *table, int size,
Uchar32 first, Uchar32 second)
{
PairMap *match;
PairMap x;
x.pair[0] = first;
x.pair[1] = second;
x.to = 0;
match = bsearch (&x, table, size, sizeof (table[0]), comp_PairMap);
return match ? match->to : 0;
}
#define PAIR_MATCH(table,len,first,second) \
((first)<(table[0].pair[0])||(first)>(table[len-1].pair[0])?0: \
find_pair_match(table, len, first, second))
static void unibidi_shape_arabic_ligature(const PairMap *table,
int size, const BidiLevel *embedding_levels,
int len,
BidiArabicProp *ar_props, Uchar32 *str)
{
/* TODO: This doesn't form ligatures for even-level Arabic text.
* no big problem though. */
register int i;
for (i = 0; i < len - 1; i++) {
register Uchar32 c;
if (BIDI_LEVEL_IS_RTL(embedding_levels[i]) &&
embedding_levels[i] == embedding_levels[i+1] &&
(c = PAIR_MATCH(table, size, str[i], str[i+1])))
{
str[i] = BIDI_CHAR_FILL;
BIDI_SET_BITS(ar_props[i], BIDI_MASK_LIGATURED);
str[i+1] = c;
}
}
}
#define DO_LIGATURING(table, levels, len, ar_props, str) \
unibidi_shape_arabic_ligature ((table), \
sizeof(table)/sizeof((table)[0]), levels, len, ar_props, str)
#define DO_SHAPING(tablemacro, len, ar_props, str) \
unibidi_shape_arabic_joining (tablemacro(,), len, ar_props, str)
void UBidiShapeArabic(Uint32 flags,
const BidiLevel *embedding_levels,
BidiArabicProp *ar_props,
Uchar32 *str, int len)
{
_DBG_PRINTF ("in UBidiShapeArabic");
if (len == 0 || !str) return;
if (BIDI_TEST_BITS (flags, BIDI_FLAG_SHAPE_ARAB_PRES)) {
DO_SHAPING (UNIBIDI_GET_ARABIC_SHAPE_PRES, len, ar_props, str);
}
if (BIDI_TEST_BITS (flags, BIDI_FLAG_SHAPE_ARAB_LIGA)) {
DO_LIGATURING (mandatory_liga_table, embedding_levels, len, ar_props, str);
}
if (BIDI_TEST_BITS (flags, BIDI_FLAG_SHAPE_ARAB_CONSOLE)) {
DO_LIGATURING (console_liga_table, embedding_levels, len, ar_props, str);
DO_SHAPING (UNIBIDI_GET_ARABIC_SHAPE_NSM, len, ar_props, str);
}
}
#endif /* _MGCHARSET_UNICODE */
+97
View File
@@ -0,0 +1,97 @@
/*
* 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/>.
*/
/*
** unicode-shape.c:
** The implementation of Arabic joining algorithm
**
** Created by WEI Yongming at 2019/03/11
**
** This implementation is based on LGPL'd FriBidi:
**
** https://github.com/fribidi/fribidi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "common.h"
#ifdef _MGCHARSET_UNICODE
#include "minigui.h"
#include "gdi.h"
#include "unicode-bidi.h"
void GUIAPI UBidiShapeMirroring(const BidiLevel *embedding_levels,
Uchar32* str, int len)
{
register int i;
_DBG_PRINTF("in fribidi_shape_mirroring");
if (len == 0 || !str) return;
/* L4. Mirror all characters that are in odd levels and have mirrors. */
for (i = len - 1; i >= 0; i--) {
if (BIDI_LEVEL_IS_RTL(embedding_levels[i])) {
Uchar32 mirrored_ch;
if (UCharGetMirror(str[i], &mirrored_ch))
str[i] = mirrored_ch;
}
}
}
void GUIAPI UBidiShape(Uint32 flags,
const BidiLevel *embedding_levels,
BidiArabicProp *ar_props, Uchar32 *str, int len)
{
if (len == 0 || !str)
return;
_DBG_PRINTF ("in fribidi_shape");
if (ar_props)
UBidiShapeArabic(flags, embedding_levels, ar_props, str, len);
if (BIDI_TEST_BITS (flags, BIDI_FLAG_SHAPE_MIRRORING))
UBidiShapeMirroring (embedding_levels, str, len);
}
#endif /* _MGCHARSET_UNICODE */