1 Star 0 Fork 0

tony1981/qemacs

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
qfribidi.c 20.91 KB
一键复制 编辑 原始数据 按行查看 历史
tony1981 提交于 2022-02-13 21:25 . init repo
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
/* FriBidi - Library of BiDi algorithm
* Copyright (C) 1999 Dov Grobgeld
*
* The optimizations to reduce the code size from 13 KB to 3 KB and
* the embed/override hack handling are
* Copyright (C) 2000 Fabrice Bellard.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA. */
#include <stdlib.h>
#include <stdio.h>
#include "qfribidi.h"
//#define TEST
//#define DEBUG
/*======================================================================
// Mirrored characters include all the characters in the Unicode list
// that have been declared as being mirrored and that have a mirrored
// equivalent.
//
// There are lots of characters that are designed as being mirrored
// but do not have any mirrored glyph, e.g. the sign for there exist.
// Are these used in Arabic? That is are all the mathematical signs
// that are assigned to be mirrorable actually mirrored in Arabic?
// If that is the case, I'll change the below code to include also
// characters that mirror to themself. It will then be the responsibility
// of the display engine to actually mirror these.
//----------------------------------------------------------------------*/
/* The character (n & 0x7fff) is the mirror of (n & 0x7fff) +1 */
/* except for AB <-> BB, 3C <-> 3E, 5B <-> 5D, 7B <-> 7D which have
their high order bit set */
static const unsigned short mirror_table[] = {
0x0028, 0x803C, 0x805B, 0x807B, 0x80AB, 0x2039, 0x2045, 0x207D,
0x208D, 0x2264, 0x2266, 0x2268, 0x226A, 0x226E, 0x2270, 0x2272,
0x2274, 0x22A2, 0x22C9, 0x22CB, 0x22D6, 0x22D8, 0x22DC, 0x22E6,
0x22F0, 0x2308, 0x230A, 0x2329, 0x3008, 0x300A, 0x300C, 0x300E,
0x3010, 0x3014, 0x3016, 0x3018, 0x301A,
};
/*
* Note: the first 256 bytes could be stored explicitely to optimize
* the speed. The table 'property_val' could be stored in 4
* bits/symbol to reduce its size.
*/
static const unsigned short property_start[366] = {
0x0000, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x001c,
0x001f, 0x0020, 0x0021, 0x0023, 0x0026, 0x002b, 0x002c, 0x002d,
0x002e, 0x002f, 0x0030, 0x003a, 0x003b, 0x0041, 0x005b, 0x0061,
0x007b, 0x007f, 0x0085, 0x0086, 0x00a0, 0x00a1, 0x00a2, 0x00a6,
0x00aa, 0x00ab, 0x00b0, 0x00b2, 0x00b4, 0x00b5, 0x00b6, 0x00b9,
0x00ba, 0x00bb, 0x00c0, 0x00d7, 0x00d8, 0x00f7, 0x00f8, 0x02b9,
0x02bb, 0x02c2, 0x02d0, 0x02d2, 0x02e0, 0x02e5, 0x02ee, 0x0300,
0x0374, 0x037a, 0x037e, 0x0386, 0x0387, 0x0388, 0x0483, 0x048c,
0x058a, 0x0591, 0x05be, 0x05bf, 0x05c0, 0x05c1, 0x05c3, 0x05c4,
0x05d0, 0x0600, 0x061b, 0x064b, 0x0660, 0x066a, 0x066b, 0x066d,
0x0670, 0x0671, 0x06d6, 0x06e5, 0x06e7, 0x06e9, 0x06ea, 0x06f0,
0x06fa, 0x070f, 0x0710, 0x0711, 0x0712, 0x0730, 0x0780, 0x07a6,
0x0800, 0x0900, 0x0903, 0x093c, 0x093d, 0x0941, 0x0949, 0x094d,
0x0950, 0x0951, 0x0958, 0x0962, 0x0964, 0x0981, 0x0982, 0x09bc,
0x09be, 0x09c1, 0x09c7, 0x09cd, 0x09d7, 0x09e2, 0x09e6, 0x09f2,
0x09f4, 0x0a00, 0x0a05, 0x0a3c, 0x0a3e, 0x0a41, 0x0a59, 0x0a70,
0x0a72, 0x0a81, 0x0a83, 0x0abc, 0x0abd, 0x0ac1, 0x0ac9, 0x0acd,
0x0ad0, 0x0b00, 0x0b02, 0x0b3c, 0x0b3d, 0x0b3f, 0x0b40, 0x0b41,
0x0b47, 0x0b4d, 0x0b57, 0x0b82, 0x0b83, 0x0bc0, 0x0bc1, 0x0bcd,
0x0bd7, 0x0c3e, 0x0c41, 0x0c46, 0x0c60, 0x0cbf, 0x0cc0, 0x0cc6,
0x0cc7, 0x0ccc, 0x0cd5, 0x0d41, 0x0d46, 0x0d4d, 0x0d57, 0x0dca,
0x0dcf, 0x0dd2, 0x0dd8, 0x0e31, 0x0e32, 0x0e34, 0x0e3f, 0x0e40,
0x0e47, 0x0e4f, 0x0eb1, 0x0eb2, 0x0eb4, 0x0ebd, 0x0ec8, 0x0ed0,
0x0f18, 0x0f1a, 0x0f35, 0x0f36, 0x0f37, 0x0f38, 0x0f39, 0x0f3a,
0x0f3e, 0x0f71, 0x0f7f, 0x0f80, 0x0f85, 0x0f86, 0x0f88, 0x0f90,
0x0fbe, 0x0fc6, 0x0fc7, 0x102d, 0x1031, 0x1032, 0x1038, 0x1039,
0x1040, 0x1058, 0x10a0, 0x1680, 0x1681, 0x169b, 0x16a0, 0x17b7,
0x17be, 0x17c6, 0x17c7, 0x17c9, 0x17d4, 0x17db, 0x17dc, 0x1800,
0x180b, 0x1810, 0x18a9, 0x1900, 0x1fbd, 0x1fbe, 0x1fbf, 0x1fc2,
0x1fcd, 0x1fd0, 0x1fdd, 0x1fe0, 0x1fed, 0x1ff2, 0x1ffd, 0x2000,
0x200b, 0x200e, 0x200f, 0x2010, 0x2028, 0x2029, 0x202a, 0x202b,
0x202c, 0x202d, 0x202e, 0x202f, 0x2030, 0x2035, 0x206a, 0x2070,
0x207a, 0x207c, 0x207f, 0x2080, 0x208a, 0x208c, 0x20a0, 0x20d0,
0x2100, 0x2102, 0x2103, 0x2107, 0x2108, 0x210a, 0x2114, 0x2115,
0x2116, 0x2119, 0x211e, 0x2124, 0x2125, 0x2126, 0x2127, 0x2128,
0x2129, 0x212a, 0x212e, 0x212f, 0x2132, 0x2133, 0x213a, 0x2160,
0x2190, 0x2212, 0x2214, 0x2336, 0x237b, 0x2395, 0x2396, 0x2460,
0x249c, 0x24ea, 0x2500, 0x2900, 0x2e00, 0x3000, 0x3001, 0x3005,
0x3008, 0x3021, 0x302a, 0x3030, 0x3031, 0x3036, 0x3038, 0x303e,
0x3041, 0x3099, 0x309b, 0x309d, 0x30fb, 0x30fc, 0xa490, 0xa500,
0xfb1d, 0xfb1e, 0xfb1f, 0xfb29, 0xfb2a, 0xfb50, 0xfd3e, 0xfd50,
0xfe00, 0xfe30, 0xfe50, 0xfe51, 0xfe52, 0xfe54, 0xfe55, 0xfe56,
0xfe5f, 0xfe60, 0xfe62, 0xfe64, 0xfe69, 0xfe6b, 0xfe70, 0xfeff,
0xff00, 0xff03, 0xff06, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f,
0xff10, 0xff1a, 0xff1b, 0xff21, 0xff3b, 0xff41, 0xff5b, 0xff66,
0xffe0, 0xffe2, 0xffe5, 0xffe8, 0xfff9, 0xfffc,
};
static const unsigned char property_val[366] = {
0x0e, 0x0a, 0x09, 0x0a, 0x0b, 0x09, 0x0e, 0x09,
0x0a, 0x0b, 0x0f, 0x06, 0x0f, 0x06, 0x08, 0x06,
0x08, 0x05, 0x04, 0x08, 0x0f, 0x00, 0x0f, 0x00,
0x0f, 0x0e, 0x09, 0x0e, 0x08, 0x0f, 0x06, 0x0f,
0x00, 0x0f, 0x06, 0x04, 0x0f, 0x00, 0x0f, 0x04,
0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f,
0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0d,
0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0d, 0x00,
0x0f, 0x0d, 0x01, 0x0d, 0x01, 0x0d, 0x01, 0x0d,
0x01, 0x08, 0x0c, 0x0d, 0x07, 0x06, 0x07, 0x0c,
0x0d, 0x0c, 0x0d, 0x0c, 0x0d, 0x0f, 0x0d, 0x04,
0x0c, 0x0e, 0x0c, 0x0d, 0x0c, 0x0d, 0x0c, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x06,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x06, 0x00,
0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00,
0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x0f,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x0d,
0x00, 0x0d, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0f,
0x0e, 0x00, 0x0d, 0x00, 0x0f, 0x00, 0x0f, 0x00,
0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x0b,
0x0e, 0x00, 0x01, 0x0f, 0x0b, 0x09, 0x10, 0x11,
0x12, 0x13, 0x14, 0x0b, 0x06, 0x0f, 0x0e, 0x04,
0x06, 0x0f, 0x00, 0x04, 0x06, 0x0f, 0x06, 0x0d,
0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00,
0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00,
0x0f, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x0f, 0x00,
0x0f, 0x06, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x04,
0x00, 0x04, 0x0f, 0x00, 0x0f, 0x0b, 0x0f, 0x00,
0x0f, 0x00, 0x0d, 0x0f, 0x00, 0x0f, 0x00, 0x0f,
0x00, 0x0d, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00,
0x01, 0x0d, 0x01, 0x06, 0x01, 0x0c, 0x0f, 0x0c,
0x0d, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
0x06, 0x0f, 0x06, 0x0f, 0x06, 0x0f, 0x0c, 0x0e,
0x0f, 0x06, 0x0f, 0x06, 0x08, 0x06, 0x08, 0x05,
0x04, 0x08, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00,
0x06, 0x0f, 0x06, 0x0f, 0x0e, 0x0f,
};
FriBidiCharType fribidi_get_type(FriBidiChar ch)
{
int a, b, m, ch1;
#if defined(TEST) || 0
/* for testing only */
if (ch >= 'A' && ch <= 'Z')
return FRIBIDI_TYPE_RTL;
#endif
a = 0;
b = (sizeof(property_start) / 2) - 1;
while (a <= b) {
m = (a + b) >> 1;
ch1 = property_start[m];
if (ch1 == ch)
goto found;
else if (ch1 > ch) {
b = m - 1;
} else {
a = m + 1;
}
}
m = a;
if (m > 0)
m--;
found:
return property_val[m];
}
/* version for test with ASCII chars */
FriBidiCharType fribidi_get_type_test(FriBidiChar ch)
{
if (ch >= 'A' && ch <= 'Z')
return FRIBIDI_TYPE_RTL;
else
return fribidi_get_type(ch);
}
FriBidiChar
fribidi_get_mirror_char(FriBidiChar ch)
{
int a, b, m, ch1, d, e;
if (ch >= 0x8000)
return ch;
a = 0;
b = (sizeof(mirror_table) / 2) - 1;
while (a <= b) {
m = (a + b) >> 1;
ch1 = mirror_table[m];
if ((ch1 & 0x7fff) == ch)
goto found;
else if ((ch1 & 0x7fff) > ch) {
b = m - 1;
} else {
a = m + 1;
}
}
if (a > 0)
a--;
ch1 = mirror_table[a];
found:
e = 1 + (ch1 >> 15);
ch1 = ch1 & 0x7fff;
/* special case */
if (ch1 == 0xab)
e = 16;
d = ch - ch1;
if (d == 0)
return ch + e;
else if (d == e)
return ch - e;
else
return ch;
}
/* 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 void compact_list(TypeLink * list_tab)
{
TypeLink *p, *lp, *q;
int type, len;
p = list_tab;
q = list_tab;
for(;;) {
lp = p;
type = p->type;
len = p->len;
p++;
if (type == FRIBIDI_TYPE_NULL) {
/* nothing to do */
} else if (type != FRIBIDI_TYPE_EOT) {
while (p->type == type) {
len += p->len;
p++;
}
q->type = type;
q->len = len;
q->pos = lp->pos;
q->level = lp->level;
q++;
} else {
q->type = FRIBIDI_TYPE_EOT;
q->pos = lp->pos;
q++;
break;
}
}
}
/* Define a rule macro */
/* Rules for overriding current type */
#define TYPE_RULE1(old_this, \
new_this) \
if (this_type == TYPE_ ## old_this) \
RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \
/* Rules for current and previous type */
#define TYPE_RULE2(old_prev, old_this, \
new_prev, new_this) \
if ( prev_type == FRIBIDI_TYPE_ ## old_prev \
&& this_type == FRIBIDI_TYPE_ ## old_this) \
{ \
RL_TYPE(pp->prev) = FRIBIDI_TYPE_ ## new_prev; \
RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \
continue; \
}
/* A full rule that assigns all three types */
#define TYPE_RULE(old_prev, old_this, old_next, \
new_prev, new_this, new_next) \
if ( prev_type == FRIBIDI_TYPE_ ## old_prev \
&& this_type == FRIBIDI_TYPE_ ## old_this \
&& next_type == FRIBIDI_TYPE_ ## old_next) \
{ \
RL_TYPE(pp->prev) = FRIBIDI_TYPE_ ## new_prev; \
RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \
RL_TYPE(pp->next) = FRIBIDI_TYPE_ ## new_next; \
continue; \
}
/* For optimization the following macro only assigns the center type */
#define TYPE_RULE_C(old_prev, old_this, old_next, \
new_this) \
if ( prev_type == FRIBIDI_TYPE_ ## old_prev \
&& this_type == FRIBIDI_TYPE_ ## old_this \
&& next_type == FRIBIDI_TYPE_ ## old_next) \
{ \
RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \
continue; \
}
#ifdef DEBUG
/*======================================================================
// For debugging, define some macros for printing the types and the
// levels.
//----------------------------------------------------------------------*/
static int type_to_char(int type)
{
int ch;
if (type == FRIBIDI_TYPE_R)
ch = 'R';
else if (type == FRIBIDI_TYPE_L)
ch = 'L';
else if (type == FRIBIDI_TYPE_E)
ch = 'E';
else if (type == FRIBIDI_TYPE_EN)
ch = 'n';
else if (type == FRIBIDI_TYPE_N)
ch = 'N';
else
ch = '?';
return ch;
}
static void print_types_re(TypeLink * pp_tab, int level)
{
TypeLink *pp;
for(pp = pp_tab + 1; pp->type != FRIBIDI_TYPE_EOT; pp++) {
printf("%d:%c(%d)[%d] ", RL_POS(pp), type_to_char(RL_TYPE(pp)), RL_LEN(pp), level ? RL_LEVEL(pp) : 0);
}
printf("\n");
}
#endif
#define STACK_SIZE 64
/*======================================================================
// This function should follow the Unicode specification closely!
//
// It is still lacking the support for <RLO> and <LRO>.
//----------------------------------------------------------------------*/
void fribidi_analyse_string(TypeLink * type_rl_list,
FriBidiCharType * pbase_dir,
int *pmax_level)
{
int base_level, base_dir;
int max_level, level, override;
int last_strong;
TypeLink *pp;
unsigned char stack_level[STACK_SIZE];
unsigned char stack_override[STACK_SIZE];
int stack_index;
#ifdef DEBUG
print_types_re(type_rl_list, 0);
#endif
/* Find the base level */
if (*pbase_dir == FRIBIDI_TYPE_L) {
base_dir = FRIBIDI_TYPE_L;
base_level = 0;
} else if (*pbase_dir == FRIBIDI_TYPE_R) {
base_dir = FRIBIDI_TYPE_R;
base_level = 1;
}
/* Search for first strong character and use its direction as base
direction */
else {
base_level = 0; /* Default */
base_dir = FRIBIDI_TYPE_N;
for (pp = type_rl_list; pp->type != FRIBIDI_TYPE_EOT; pp++) {
int type;
type = RL_TYPE(pp);
if (type == FRIBIDI_TYPE_R ||
type == FRIBIDI_TYPE_RLE ||
type == FRIBIDI_TYPE_RLO) {
base_level = 1;
base_dir = FRIBIDI_TYPE_R;
break;
} else if (type == FRIBIDI_TYPE_L ||
type == FRIBIDI_TYPE_LRE ||
type == FRIBIDI_TYPE_LRO) {
base_level = 0;
base_dir = FRIBIDI_TYPE_L;
break;
}
}
/* If no strong base_dir was found, resort to the weak direction
* that was passed on input.
*/
if (base_dir == FRIBIDI_TYPE_N) {
if (*pbase_dir == FRIBIDI_TYPE_WR) {
base_dir = FRIBIDI_TYPE_RTL;
base_level = 1;
} else if (*pbase_dir == FRIBIDI_TYPE_WL) {
base_dir = FRIBIDI_TYPE_LTR;
base_level = 0;
}
}
}
/* hack for RLE/LRE/RLO/LRO/PDF. It is not complete in case of
errors or with neutrals. Better take the latest version of
fribidi ? */
level = base_level;
override = FRIBIDI_TYPE_N;
stack_index = 0;
for (pp = type_rl_list + 1; pp->type != FRIBIDI_TYPE_EOT; pp++) {
int type, i;
type = RL_TYPE(pp);
if (type == FRIBIDI_TYPE_LRE ||
type == FRIBIDI_TYPE_RLE ||
type == FRIBIDI_TYPE_LRO ||
type == FRIBIDI_TYPE_RLO) {
for(i=0;i<RL_LEN(pp);i++) {
if (stack_index < STACK_SIZE) {
/* push level & override */
stack_level[stack_index] = level;
stack_override[stack_index] = override;
stack_index++;
/* compute new level */
if (type == FRIBIDI_TYPE_LRE ||
type == FRIBIDI_TYPE_LRO) {
level = (level + 2) & ~1; /* least greater even */
} else {
level = (level + 1) | 1; /* least greater odd */
}
/* compute new override */
if (type == FRIBIDI_TYPE_LRO)
override = FRIBIDI_TYPE_L;
else if (type == FRIBIDI_TYPE_RLO)
override = FRIBIDI_TYPE_R;
else
override = FRIBIDI_TYPE_N;
}
}
RL_TYPE(pp) = FRIBIDI_TYPE_NULL;
} else if (type == FRIBIDI_TYPE_PDF) {
for(i=0;i<RL_LEN(pp);i++) {
if (stack_index > 0) {
stack_index--;
/* pop level & override */
level = stack_level[stack_index];
override = stack_override[stack_index];
}
}
RL_TYPE(pp) = FRIBIDI_TYPE_NULL;
} else {
RL_LEVEL(pp) = level;
/* if override defined, then modify type accordingly */
if (override != FRIBIDI_TYPE_N)
RL_TYPE(pp) = override;
}
}
compact_list(type_rl_list);
/* 4. Resolving weak types */
last_strong = base_dir;
for (pp = type_rl_list + 1; pp->type != FRIBIDI_TYPE_EOT; pp++) {
int prev_type = RL_TYPE(pp-1);
int this_type = RL_TYPE(pp);
int next_type = RL_TYPE(pp+1);
/* Remember the last strong character */
if (prev_type == FRIBIDI_TYPE_AL
|| prev_type == FRIBIDI_TYPE_R
|| prev_type == FRIBIDI_TYPE_L)
last_strong = prev_type;
/* W1. NSM */
if (this_type == FRIBIDI_TYPE_NSM) {
if (prev_type == FRIBIDI_TYPE_SOT)
RL_TYPE(pp) = FRIBIDI_TYPE_N; /* Will be resolved to base dir */
else
RL_TYPE(pp) = prev_type;
}
/* W2: European numbers */
if (this_type == FRIBIDI_TYPE_N
&& last_strong == FRIBIDI_TYPE_AL)
RL_TYPE(pp) = FRIBIDI_TYPE_AN;
/* W3: Change ALs to R
We have to do this for prev character as we would otherwise
interfer with the next last_strong which is FRIBIDI_TYPE_AL.
*/
if (prev_type == FRIBIDI_TYPE_AL)
RL_TYPE(pp-1) = FRIBIDI_TYPE_R;
/* 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 (RL_LEN(pp) == 1) {
TYPE_RULE_C(EN, ES, EN, EN);
TYPE_RULE_C(EN, CS, EN, EN);
TYPE_RULE_C(AN, CS, AN, AN);
}
/* W5. A sequence of European terminators adjacent to European
numbers changes to All European numbers.
*/
if (this_type == FRIBIDI_TYPE_ET) {
if (next_type == FRIBIDI_TYPE_EN
|| prev_type == FRIBIDI_TYPE_EN) {
RL_TYPE(pp) = FRIBIDI_TYPE_EN;
}
}
/* This type may have been overriden */
this_type = RL_TYPE(pp);
/* W6. Otherwise change separators and terminators to other neutral */
if (this_type == FRIBIDI_TYPE_ET
|| this_type == FRIBIDI_TYPE_CS
|| this_type == FRIBIDI_TYPE_ES)
RL_TYPE(pp) = FRIBIDI_TYPE_ON;
/* W7. Change european numbers to L. */
if (prev_type == FRIBIDI_TYPE_EN
&& last_strong == FRIBIDI_TYPE_L)
RL_TYPE(pp-1) = FRIBIDI_TYPE_L;
}
compact_list(type_rl_list);
/* 5. Resolving Neutral Types */
/* We can now collapse all separators and other neutral types to
plain neutrals */
for (pp = type_rl_list + 1; pp->type != FRIBIDI_TYPE_EOT; pp++) {
int this_type = RL_TYPE(pp);
if (this_type == FRIBIDI_TYPE_WS
|| this_type == FRIBIDI_TYPE_ON
|| this_type == FRIBIDI_TYPE_ES
|| this_type == FRIBIDI_TYPE_ET
|| this_type == FRIBIDI_TYPE_CS
|| this_type == FRIBIDI_TYPE_BN)
RL_TYPE(pp) = FRIBIDI_TYPE_N;
}
compact_list(type_rl_list);
for (pp = type_rl_list + 1; pp->type != FRIBIDI_TYPE_EOT; pp++) {
int prev_type = RL_TYPE(pp-1);
int this_type = RL_TYPE(pp);
int next_type = RL_TYPE(pp+1);
if (this_type == FRIBIDI_TYPE_N) { /* optimization! */
/* "European and arabic numbers are treated
as though they were R" */
if (prev_type == FRIBIDI_TYPE_EN || prev_type == FRIBIDI_TYPE_AN)
prev_type = FRIBIDI_TYPE_R;
if (next_type == FRIBIDI_TYPE_EN || next_type == FRIBIDI_TYPE_AN)
next_type = FRIBIDI_TYPE_R;
/* N1. */
TYPE_RULE_C(R, N, R, R);
TYPE_RULE_C(L, N, L, L);
/* N2. Any remaining neutrals takes the embedding direction */
if (RL_TYPE(pp) == FRIBIDI_TYPE_N)
RL_TYPE(pp) = FRIBIDI_TYPE_E;
}
}
compact_list(type_rl_list);
/* 6. Resolving Implicit levels */
max_level = base_level;
for (pp = type_rl_list + 1; pp->type != FRIBIDI_TYPE_EOT; pp++) {
int this_type = RL_TYPE(pp);
level = RL_LEVEL(pp);
if ((level & 1) == 0) {
/* Even */
if (this_type == FRIBIDI_TYPE_R)
RL_LEVEL(pp) = level + 1;
else if (this_type == FRIBIDI_TYPE_AN)
RL_LEVEL(pp) = level + 2;
else if (RL_TYPE(pp-1) != FRIBIDI_TYPE_L && this_type == FRIBIDI_TYPE_EN)
RL_LEVEL(pp) = level + 2;
else
RL_LEVEL(pp) = level;
} else {
/* Odd */
if (this_type == FRIBIDI_TYPE_L
|| this_type == FRIBIDI_TYPE_AN
|| this_type == FRIBIDI_TYPE_EN)
RL_LEVEL(pp) = level + 1;
else
RL_LEVEL(pp) = level;
}
if (RL_LEVEL(pp) > max_level)
max_level = RL_LEVEL(pp);
}
compact_list(type_rl_list);
*pmax_level = max_level;
*pbase_dir = base_dir;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/chaoswong/qemacs.git
git@gitee.com:chaoswong/qemacs.git
chaoswong
qemacs
qemacs
master

搜索帮助