Files
MiniGUI/src/font/unicode-script.c
T

695 lines
23 KiB
C

/*
* 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/>.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "common.h"
#include "minigui.h"
#include "gdi.h"
#ifdef _MGCHARSET_UNICODE
#include "unicode-script-table.h"
#define SCRIPT_TABLE_MIDPOINT (TABLESIZE (unicode_script_table) / 2)
static inline int unichar_get_script_bsearch (Uchar32 ch)
{
int lower = 0;
int upper = (int)TABLESIZE (unicode_script_table) - 1;
static int saved_mid = SCRIPT_TABLE_MIDPOINT;
int mid = saved_mid;
do {
if (ch < unicode_script_table[mid].start)
upper = mid - 1;
else if (ch >= unicode_script_table[mid].start + unicode_script_table[mid].chars)
lower = mid + 1;
else
return unicode_script_table[saved_mid = mid].script;
mid = (lower + upper) / 2;
} while (lower <= upper);
return SCRIPT_UNKNOWN;
}
ScriptType GUIAPI UCharGetScriptType (Uchar32 ch)
{
if (ch < EASY_SCRIPTS_RANGE)
return (ScriptType)unicode_script_easy_table[ch];
else
return (ScriptType)unichar_get_script_bsearch(ch);
}
/* http://unicode.org/iso15924/ */
static const Uint32 iso15924_tags[] =
{
#define PACK(a,b,c,d) ((Uint32)((((Uint8)(a))<<24)|(((Uint8)(b))<<16)|(((Uint8)(c))<<8)|((Uint8)(d))))
PACK ('Z','y','y','y'), /* SCRIPT_COMMON */
PACK ('Z','i','n','h'), /* SCRIPT_INHERITED */
PACK ('A','r','a','b'), /* SCRIPT_ARABIC */
PACK ('A','r','m','n'), /* SCRIPT_ARMENIAN */
PACK ('B','e','n','g'), /* SCRIPT_BENGALI */
PACK ('B','o','p','o'), /* SCRIPT_BOPOMOFO */
PACK ('C','h','e','r'), /* SCRIPT_CHEROKEE */
PACK ('C','o','p','t'), /* SCRIPT_COPTIC */
PACK ('C','y','r','l'), /* SCRIPT_CYRILLIC */
PACK ('D','s','r','t'), /* SCRIPT_DESERET */
PACK ('D','e','v','a'), /* SCRIPT_DEVANAGARI */
PACK ('E','t','h','i'), /* SCRIPT_ETHIOPIC */
PACK ('G','e','o','r'), /* SCRIPT_GEORGIAN */
PACK ('G','o','t','h'), /* SCRIPT_GOTHIC */
PACK ('G','r','e','k'), /* SCRIPT_GREEK */
PACK ('G','u','j','r'), /* SCRIPT_GUJARATI */
PACK ('G','u','r','u'), /* SCRIPT_GURMUKHI */
PACK ('H','a','n','i'), /* SCRIPT_HAN */
PACK ('H','a','n','g'), /* SCRIPT_HANGUL */
PACK ('H','e','b','r'), /* SCRIPT_HEBREW */
PACK ('H','i','r','a'), /* SCRIPT_HIRAGANA */
PACK ('K','n','d','a'), /* SCRIPT_KANNADA */
PACK ('K','a','n','a'), /* SCRIPT_KATAKANA */
PACK ('K','h','m','r'), /* SCRIPT_KHMER */
PACK ('L','a','o','o'), /* SCRIPT_LAO */
PACK ('L','a','t','n'), /* SCRIPT_LATIN */
PACK ('M','l','y','m'), /* SCRIPT_MALAYALAM */
PACK ('M','o','n','g'), /* SCRIPT_MONGOLIAN */
PACK ('M','y','m','r'), /* SCRIPT_MYANMAR */
PACK ('O','g','a','m'), /* SCRIPT_OGHAM */
PACK ('I','t','a','l'), /* SCRIPT_OLD_ITALIC */
PACK ('O','r','y','a'), /* SCRIPT_ORIYA */
PACK ('R','u','n','r'), /* SCRIPT_RUNIC */
PACK ('S','i','n','h'), /* SCRIPT_SINHALA */
PACK ('S','y','r','c'), /* SCRIPT_SYRIAC */
PACK ('T','a','m','l'), /* SCRIPT_TAMIL */
PACK ('T','e','l','u'), /* SCRIPT_TELUGU */
PACK ('T','h','a','a'), /* SCRIPT_THAANA */
PACK ('T','h','a','i'), /* SCRIPT_THAI */
PACK ('T','i','b','t'), /* SCRIPT_TIBETAN */
PACK ('C','a','n','s'), /* SCRIPT_CANADIAN_ABORIGINAL */
PACK ('Y','i','i','i'), /* SCRIPT_YI */
PACK ('T','g','l','g'), /* SCRIPT_TAGALOG */
PACK ('H','a','n','o'), /* SCRIPT_HANUNOO */
PACK ('B','u','h','d'), /* SCRIPT_BUHID */
PACK ('T','a','g','b'), /* SCRIPT_TAGBANWA */
/* Unicode-4.0 additions */
PACK ('B','r','a','i'), /* SCRIPT_BRAILLE */
PACK ('C','p','r','t'), /* SCRIPT_CYPRIOT */
PACK ('L','i','m','b'), /* SCRIPT_LIMBU */
PACK ('O','s','m','a'), /* SCRIPT_OSMANYA */
PACK ('S','h','a','w'), /* SCRIPT_SHAVIAN */
PACK ('L','i','n','b'), /* SCRIPT_LINEAR_B */
PACK ('T','a','l','e'), /* SCRIPT_TAI_LE */
PACK ('U','g','a','r'), /* SCRIPT_UGARITIC */
/* Unicode-4.1 additions */
PACK ('T','a','l','u'), /* SCRIPT_NEW_TAI_LUE */
PACK ('B','u','g','i'), /* SCRIPT_BUGINESE */
PACK ('G','l','a','g'), /* SCRIPT_GLAGOLITIC */
PACK ('T','f','n','g'), /* SCRIPT_TIFINAGH */
PACK ('S','y','l','o'), /* SCRIPT_SYLOTI_NAGRI */
PACK ('X','p','e','o'), /* SCRIPT_OLD_PERSIAN */
PACK ('K','h','a','r'), /* SCRIPT_KHAROSHTHI */
/* Unicode-5.0 additions */
PACK ('Z','z','z','z'), /* SCRIPT_UNKNOWN */
PACK ('B','a','l','i'), /* SCRIPT_BALINESE */
PACK ('X','s','u','x'), /* SCRIPT_CUNEIFORM */
PACK ('P','h','n','x'), /* SCRIPT_PHOENICIAN */
PACK ('P','h','a','g'), /* SCRIPT_PHAGS_PA */
PACK ('N','k','o','o'), /* SCRIPT_NKO */
/* Unicode-5.1 additions */
PACK ('K','a','l','i'), /* SCRIPT_KAYAH_LI */
PACK ('L','e','p','c'), /* SCRIPT_LEPCHA */
PACK ('R','j','n','g'), /* SCRIPT_REJANG */
PACK ('S','u','n','d'), /* SCRIPT_SUNDANESE */
PACK ('S','a','u','r'), /* SCRIPT_SAURASHTRA */
PACK ('C','h','a','m'), /* SCRIPT_CHAM */
PACK ('O','l','c','k'), /* SCRIPT_OL_CHIKI */
PACK ('V','a','i','i'), /* SCRIPT_VAI */
PACK ('C','a','r','i'), /* SCRIPT_CARIAN */
PACK ('L','y','c','i'), /* SCRIPT_LYCIAN */
PACK ('L','y','d','i'), /* SCRIPT_LYDIAN */
/* Unicode-5.2 additions */
PACK ('A','v','s','t'), /* SCRIPT_AVESTAN */
PACK ('B','a','m','u'), /* SCRIPT_BAMUM */
PACK ('E','g','y','p'), /* SCRIPT_EGYPTIAN_HIEROGLYPHS */
PACK ('A','r','m','i'), /* SCRIPT_IMPERIAL_ARAMAIC */
PACK ('P','h','l','i'), /* SCRIPT_INSCRIPTIONAL_PAHLAVI */
PACK ('P','r','t','i'), /* SCRIPT_INSCRIPTIONAL_PARTHIAN */
PACK ('J','a','v','a'), /* SCRIPT_JAVANESE */
PACK ('K','t','h','i'), /* SCRIPT_KAITHI */
PACK ('L','i','s','u'), /* SCRIPT_LISU */
PACK ('M','t','e','i'), /* SCRIPT_MEETEI_MAYEK */
PACK ('S','a','r','b'), /* SCRIPT_OLD_SOUTH_ARABIAN */
PACK ('O','r','k','h'), /* SCRIPT_OLD_TURKIC */
PACK ('S','a','m','r'), /* SCRIPT_SAMARITAN */
PACK ('L','a','n','a'), /* SCRIPT_TAI_THAM */
PACK ('T','a','v','t'), /* SCRIPT_TAI_VIET */
/* Unicode-6.0 additions */
PACK ('B','a','t','k'), /* SCRIPT_BATAK */
PACK ('B','r','a','h'), /* SCRIPT_BRAHMI */
PACK ('M','a','n','d'), /* SCRIPT_MANDAIC */
/* Unicode-6.1 additions */
PACK ('C','a','k','m'), /* SCRIPT_CHAKMA */
PACK ('M','e','r','c'), /* SCRIPT_MEROITIC_CURSIVE */
PACK ('M','e','r','o'), /* SCRIPT_MEROITIC_HIEROGLYPHS */
PACK ('P','l','r','d'), /* SCRIPT_MIAO */
PACK ('S','h','r','d'), /* SCRIPT_SHARADA */
PACK ('S','o','r','a'), /* SCRIPT_SORA_SOMPENG */
PACK ('T','a','k','r'), /* SCRIPT_TAKRI */
/* Unicode 7.0 additions */
PACK ('B','a','s','s'), /* SCRIPT_BASSA_VAH */
PACK ('A','g','h','b'), /* SCRIPT_CAUCASIAN_ALBANIAN */
PACK ('D','u','p','l'), /* SCRIPT_DUPLOYAN */
PACK ('E','l','b','a'), /* SCRIPT_ELBASAN */
PACK ('G','r','a','n'), /* SCRIPT_GRANTHA */
PACK ('K','h','o','j'), /* SCRIPT_KHOJKI*/
PACK ('S','i','n','d'), /* SCRIPT_KHUDAWADI */
PACK ('L','i','n','a'), /* SCRIPT_LINEAR_A */
PACK ('M','a','h','j'), /* SCRIPT_MAHAJANI */
PACK ('M','a','n','u'), /* SCRIPT_MANICHAEAN */
PACK ('M','e','n','d'), /* SCRIPT_MENDE_KIKAKUI */
PACK ('M','o','d','i'), /* SCRIPT_MODI */
PACK ('M','r','o','o'), /* SCRIPT_MRO */
PACK ('N','b','a','t'), /* SCRIPT_NABATAEAN */
PACK ('N','a','r','b'), /* SCRIPT_OLD_NORTH_ARABIAN */
PACK ('P','e','r','m'), /* SCRIPT_OLD_PERMIC */
PACK ('H','m','n','g'), /* SCRIPT_PAHAWH_HMONG */
PACK ('P','a','l','m'), /* SCRIPT_PALMYRENE */
PACK ('P','a','u','c'), /* SCRIPT_PAU_CIN_HAU */
PACK ('P','h','l','p'), /* SCRIPT_PSALTER_PAHLAVI */
PACK ('S','i','d','d'), /* SCRIPT_SIDDHAM */
PACK ('T','i','r','h'), /* SCRIPT_TIRHUTA */
PACK ('W','a','r','a'), /* SCRIPT_WARANG_CITI */
/* Unicode 8.0 additions */
PACK ('A','h','o','m'), /* SCRIPT_AHOM */
PACK ('H','l','u','w'), /* SCRIPT_ANATOLIAN_HIEROGLYPHS */
PACK ('H','a','t','r'), /* SCRIPT_HATRAN */
PACK ('M','u','l','t'), /* SCRIPT_MULTANI */
PACK ('H','u','n','g'), /* SCRIPT_OLD_HUNGARIAN */
PACK ('S','g','n','w'), /* SCRIPT_SIGNWRITING */
/* Unicode 9.0 additions */
PACK ('A','d','l','m'), /* SCRIPT_ADLAM */
PACK ('B','h','k','s'), /* SCRIPT_BHAIKSUKI */
PACK ('M','a','r','c'), /* SCRIPT_MARCHEN */
PACK ('N','e','w','a'), /* SCRIPT_NEWA */
PACK ('O','s','g','e'), /* SCRIPT_OSAGE */
PACK ('T','a','n','g'), /* SCRIPT_TANGUT */
/* Unicode 10.0 additions */
PACK ('G','o','n','m'), /* SCRIPT_MASARAM_GONDI */
PACK ('N','s','h','u'), /* SCRIPT_NUSHU */
PACK ('S','o','y','o'), /* SCRIPT_SOYOMBO */
PACK ('Z','a','n','b'), /* SCRIPT_ZANABAZAR_SQUARE */
/* Unicode 11.0 additions */
PACK ('D','o','g','r'), /* SCRIPT_DOGRA */
PACK ('G','o','n','g'), /* SCRIPT_GUNJALA_GONDI */
PACK ('R','o','h','g'), /* SCRIPT_HANIFI_ROHINGYA */
PACK ('M','a','k','a'), /* SCRIPT_MAKASAR */
PACK ('M','e','d','f'), /* SCRIPT_MEDEFAIDRIN */
PACK ('S','o','g','o'), /* SCRIPT_OLD_SOGDIAN */
PACK ('S','o','g','d'), /* SCRIPT_SOGDIAN */
/* Unicode 12.0 additions */
PACK ('E','l','y','m'), /* SCRIPT_ELYMAIC */
PACK ('N','a','n','d'), /* SCRIPT_NANDINAGARI */
PACK ('H','m','n','p'), /* SCRIPT_NYIAKENG_PUACHUE_HMONG */
PACK ('W','c','h','o'), /* SCRIPT_WANCHO */
#undef PACK
};
Uint32 GUIAPI ScriptTypeToISO15924 (ScriptType script)
{
if (script == SCRIPT_INVALID_CODE)
return 0;
if (script < 0 || script >= (ScriptType) TABLESIZE (iso15924_tags))
return 0x5A7A7A7A;
return iso15924_tags[script];
}
ScriptType GUIAPI ScriptTypeFromISO15924 (Uint32 iso15924)
{
unsigned int i;
if (!iso15924)
return SCRIPT_INVALID_CODE;
for (i = 0; i < TABLESIZE (iso15924_tags); i++)
if (iso15924_tags[i] == iso15924)
return (ScriptType) i;
return SCRIPT_UNKNOWN;
}
#include "script-language-table.inc"
static int comp_lang(const void *k1, const void *k2)
{
ScriptTypeForLang *sl1 = (ScriptTypeForLang*) k1;
ScriptTypeForLang *sl2 = (ScriptTypeForLang*) k2;
return strcmp(sl1->lang, sl2->lang);
}
const ScriptType* GUIAPI GetScriptsForLang(const char* lang_name,
LanguageCode* lang_code, int* nr_scripts)
{
const ScriptType* scripts;
const ScriptTypeForLang* matched;
matched = bsearch(lang_name, _script_for_lang,
TABLESIZE(_script_for_lang), sizeof (_script_for_lang[0]),
comp_lang);
if (matched) {
if (lang_code)
*lang_code = LanguageCodeFromISO639s1Code(matched->lang);
scripts = matched->scripts;
if (nr_scripts) {
int i;
for (i = 0; i < TABLESIZE(_script_for_lang->scripts); i++) {
if (_script_for_lang->scripts[i] == 0)
break;
}
*nr_scripts = i;
}
return scripts;
}
if (lang_code)
*lang_code = LANGCODE_unknown;
return NULL;
}
BOOL __mg_language_includes_script(LanguageCode lc, ScriptType script)
{
const ScriptType *scripts;
int num_scripts, j;
/* copied from the one in pango-script.c */
#define REAL_SCRIPT(script) \
((script) > SCRIPT_INHERITED && (script) != SCRIPT_UNKNOWN)
if (!REAL_SCRIPT (script))
return TRUE;
#undef REAL_SCRIPT
scripts = GetScriptsForLang (LanguageCodeToISO639s1(lc), &lc, &num_scripts);
if (!scripts)
return TRUE;
for (j = 0; j < num_scripts; j++)
if (scripts[j] == script)
return TRUE;
return FALSE;
}
/*
* https://www.w3.org/TR/css-text-3/#script-tagging
*/
ScriptType GUIAPI NormalizeScriptType(LanguageCode cl,
ScriptType ws)
{
if (ws == SCRIPT_BOPOMOFO) {
return SCRIPT_HAN;
}
if (ws != SCRIPT_INVALID_CODE)
return ws;
switch (cl) {
case LANGCODE_zh:
return SCRIPT_HAN;
case LANGCODE_ja:
return SCRIPT_HAN;
case LANGCODE_ko:
return SCRIPT_HANGUL;
case LANGCODE_unknown:
return SCRIPT_COMMON;
default:
break;
}
return ws;
}
typedef enum {
HORIZONTAL_DIRECTION_LTR,
HORIZONTAL_DIRECTION_RTL,
HORIZONTAL_DIRECTION_WEAK,
} HorizontalDirection;
typedef enum {
VERTICAL_DIRECTION_NONE,
VERTICAL_DIRECTION_TTB,
VERTICAL_DIRECTION_BTT,
} VerticalDirection;
typedef struct {
/* GlyphRunDir */
Uint8 horiz_dir; /* Orientation in horizontal context */
/* VerticalDirection */
Uint8 vert_dir; /* Orientation in vertical context */
/* LayoutGravity */
Uint8 preferred_gravity; /* Preferred context gravity */
/* BOOL */
Uint8 wide; /* Whether script is mostly wide.
* Wide characters are upright (ie.
* not rotated) in foreign context */
} ScriptTypeProperties;
#define NONE VERTICAL_DIRECTION_NONE
#define TTB VERTICAL_DIRECTION_TTB
#define BTT VERTICAL_DIRECTION_BTT
#define LTR HORIZONTAL_DIRECTION_LTR
#define RTL HORIZONTAL_DIRECTION_RTL
#define WEAK HORIZONTAL_DIRECTION_WEAK
#define S LAYOUT_GRAVITY_SOUTH
#define E LAYOUT_GRAVITY_EAST
#define W LAYOUT_GRAVITY_WEST
#define UNKNOWN_SCRIPT_PROPERTY \
{LTR, NONE, S, FALSE}
const ScriptTypeProperties script_properties[] =
{
{LTR, NONE, S, FALSE}, /* Zyyy */
{LTR, NONE, S, FALSE}, /* Qaai */
{RTL, NONE, S, FALSE}, /* Arab */
{LTR, NONE, S, FALSE}, /* Armn */
{LTR, NONE, S, FALSE}, /* Beng */
{LTR, TTB, E, TRUE }, /* Bopo */
{LTR, NONE, S, FALSE}, /* Cher */
{LTR, NONE, S, FALSE}, /* Qaac */
{LTR, NONE, S, FALSE}, /* Cyrl (Cyrs) */
{LTR, NONE, S, FALSE}, /* Dsrt */
{LTR, NONE, S, FALSE}, /* Deva */
{LTR, NONE, S, FALSE}, /* Ethi */
{LTR, NONE, S, FALSE}, /* Geor (Geon, Geoa) */
{LTR, NONE, S, FALSE}, /* Goth */
{LTR, NONE, S, FALSE}, /* Grek */
{LTR, NONE, S, FALSE}, /* Gujr */
{LTR, NONE, S, FALSE}, /* Guru */
{LTR, TTB, E, TRUE }, /* Hani */
{LTR, TTB, E, TRUE }, /* Hang */
{RTL, NONE, S, FALSE}, /* Hebr */
{LTR, TTB, E, TRUE }, /* Hira */
{LTR, NONE, S, FALSE}, /* Knda */
{LTR, TTB, E, TRUE }, /* Kana */
{LTR, NONE, S, FALSE}, /* Khmr */
{LTR, NONE, S, FALSE}, /* Laoo */
{LTR, NONE, S, FALSE}, /* Latn (Latf, Latg) */
{LTR, NONE, S, FALSE}, /* Mlym */
{WEAK,TTB, W, FALSE}, /* Mong */
{LTR, NONE, S, FALSE}, /* Mymr */
{LTR, BTT, W, FALSE}, /* Ogam */
{LTR, NONE, S, FALSE}, /* Ital */
{LTR, NONE, S, FALSE}, /* Orya */
{LTR, NONE, S, FALSE}, /* Runr */
{LTR, NONE, S, FALSE}, /* Sinh */
{RTL, NONE, S, FALSE}, /* Syrc (Syrj, Syrn, Syre) */
{LTR, NONE, S, FALSE}, /* Taml */
{LTR, NONE, S, FALSE}, /* Telu */
{RTL, NONE, S, FALSE}, /* Thaa */
{LTR, NONE, S, FALSE}, /* Thai */
{LTR, NONE, S, FALSE}, /* Tibt */
{LTR, NONE, S, FALSE}, /* Cans */
{LTR, TTB, S, TRUE }, /* Yiii */
{LTR, NONE, S, FALSE}, /* Tglg */
{LTR, NONE, S, FALSE}, /* Hano */
{LTR, NONE, S, FALSE}, /* Buhd */
{LTR, NONE, S, FALSE}, /* Tagb */
/* Unicode-4.0 additions */
{LTR, NONE, S, FALSE}, /* Brai */
{RTL, NONE, S, FALSE}, /* Cprt */
{LTR, NONE, S, FALSE}, /* Limb */
{LTR, NONE, S, FALSE}, /* Osma */
{LTR, NONE, S, FALSE}, /* Shaw */
{LTR, NONE, S, FALSE}, /* Linb */
{LTR, NONE, S, FALSE}, /* Tale */
{LTR, NONE, S, FALSE}, /* Ugar */
/* Unicode-4.1 additions */
{LTR, NONE, S, FALSE}, /* Talu */
{LTR, NONE, S, FALSE}, /* Bugi */
{LTR, NONE, S, FALSE}, /* Glag */
{LTR, NONE, S, FALSE}, /* Tfng */
{LTR, NONE, S, FALSE}, /* Sylo */
{LTR, NONE, S, FALSE}, /* Xpeo */
{LTR, NONE, S, FALSE}, /* Khar */
/* Unicode-5.0 additions */
{LTR, NONE, S, FALSE}, /* Zzzz */
{LTR, NONE, S, FALSE}, /* Bali */
{LTR, NONE, S, FALSE}, /* Xsux */
{RTL, NONE, S, FALSE}, /* Phnx */
{LTR, NONE, S, FALSE}, /* Phag */
{RTL, NONE, S, FALSE}, /* Nkoo */
/* Unicode-5.1 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Kali */
UNKNOWN_SCRIPT_PROPERTY, /* Lepc */
UNKNOWN_SCRIPT_PROPERTY, /* Rjng */
UNKNOWN_SCRIPT_PROPERTY, /* Sund */
UNKNOWN_SCRIPT_PROPERTY, /* Saur */
UNKNOWN_SCRIPT_PROPERTY, /* Cham */
UNKNOWN_SCRIPT_PROPERTY, /* Olck */
UNKNOWN_SCRIPT_PROPERTY, /* Vaii */
UNKNOWN_SCRIPT_PROPERTY, /* Cari */
UNKNOWN_SCRIPT_PROPERTY, /* Lyci */
UNKNOWN_SCRIPT_PROPERTY, /* Lydi */
/* Unicode-5.2 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Avst */
UNKNOWN_SCRIPT_PROPERTY, /* Bamu */
UNKNOWN_SCRIPT_PROPERTY, /* Egyp */
UNKNOWN_SCRIPT_PROPERTY, /* Armi */
UNKNOWN_SCRIPT_PROPERTY, /* Phli */
UNKNOWN_SCRIPT_PROPERTY, /* Prti */
UNKNOWN_SCRIPT_PROPERTY, /* Java */
UNKNOWN_SCRIPT_PROPERTY, /* Kthi */
UNKNOWN_SCRIPT_PROPERTY, /* Lisu */
UNKNOWN_SCRIPT_PROPERTY, /* Mtei */
UNKNOWN_SCRIPT_PROPERTY, /* Sarb */
UNKNOWN_SCRIPT_PROPERTY, /* Orkh */
UNKNOWN_SCRIPT_PROPERTY, /* Samr */
UNKNOWN_SCRIPT_PROPERTY, /* Lana */
UNKNOWN_SCRIPT_PROPERTY, /* Tavt */
/* Unicode-6.0 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Batk */
UNKNOWN_SCRIPT_PROPERTY, /* Brah */
UNKNOWN_SCRIPT_PROPERTY, /* Mand */
/* Unicode-6.1 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Cakm */
UNKNOWN_SCRIPT_PROPERTY, /* Merc */
UNKNOWN_SCRIPT_PROPERTY, /* Mero */
UNKNOWN_SCRIPT_PROPERTY, /* Plrd */
UNKNOWN_SCRIPT_PROPERTY, /* Shrd */
UNKNOWN_SCRIPT_PROPERTY, /* Sora */
UNKNOWN_SCRIPT_PROPERTY, /* Takr */
/* Unicode 7.0 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Bass */
UNKNOWN_SCRIPT_PROPERTY, /* Aghb */
UNKNOWN_SCRIPT_PROPERTY, /* Dupl */
UNKNOWN_SCRIPT_PROPERTY, /* Elba */
UNKNOWN_SCRIPT_PROPERTY, /* Gran */
UNKNOWN_SCRIPT_PROPERTY, /* Khoj */
UNKNOWN_SCRIPT_PROPERTY, /* Sind */
UNKNOWN_SCRIPT_PROPERTY, /* Lina */
UNKNOWN_SCRIPT_PROPERTY, /* Mahj */
UNKNOWN_SCRIPT_PROPERTY, /* Manu */
UNKNOWN_SCRIPT_PROPERTY, /* Mend */
UNKNOWN_SCRIPT_PROPERTY, /* Modi */
UNKNOWN_SCRIPT_PROPERTY, /* Mroo */
UNKNOWN_SCRIPT_PROPERTY, /* Nbat */
UNKNOWN_SCRIPT_PROPERTY, /* Narb */
UNKNOWN_SCRIPT_PROPERTY, /* Perm */
UNKNOWN_SCRIPT_PROPERTY, /* Hmng */
UNKNOWN_SCRIPT_PROPERTY, /* Palm */
UNKNOWN_SCRIPT_PROPERTY, /* Pauc */
UNKNOWN_SCRIPT_PROPERTY, /* Phlp */
UNKNOWN_SCRIPT_PROPERTY, /* Sidd */
UNKNOWN_SCRIPT_PROPERTY, /* Tirh */
UNKNOWN_SCRIPT_PROPERTY, /* Wara */
/* Unicode 8.0 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Ahom */
UNKNOWN_SCRIPT_PROPERTY, /* Hluw */
UNKNOWN_SCRIPT_PROPERTY, /* Hatr */
UNKNOWN_SCRIPT_PROPERTY, /* Mult */
UNKNOWN_SCRIPT_PROPERTY, /* Hung */
UNKNOWN_SCRIPT_PROPERTY, /* Sgnw */
/* Unicode 9.0 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Adlm */
UNKNOWN_SCRIPT_PROPERTY, /* Bhks */
UNKNOWN_SCRIPT_PROPERTY, /* Marc */
UNKNOWN_SCRIPT_PROPERTY, /* Newa */
UNKNOWN_SCRIPT_PROPERTY, /* Osge */
UNKNOWN_SCRIPT_PROPERTY, /* Tang */
/* Unicode 10.0 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Gonm */
UNKNOWN_SCRIPT_PROPERTY, /* Nshu */
UNKNOWN_SCRIPT_PROPERTY, /* Soyo */
UNKNOWN_SCRIPT_PROPERTY, /* Zanb */
/* Unicode 11.0 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Dogr */
UNKNOWN_SCRIPT_PROPERTY, /* Gong */
UNKNOWN_SCRIPT_PROPERTY, /* Rohg */
UNKNOWN_SCRIPT_PROPERTY, /* Maka */
UNKNOWN_SCRIPT_PROPERTY, /* Medf */
UNKNOWN_SCRIPT_PROPERTY, /* Sogo */
UNKNOWN_SCRIPT_PROPERTY, /* Sogd */
/* Unicode 12.0 additions */
UNKNOWN_SCRIPT_PROPERTY, /* Elymaic */
UNKNOWN_SCRIPT_PROPERTY, /* Nandinagari */
UNKNOWN_SCRIPT_PROPERTY, /* Nyiakeng Puachue Hmong */
UNKNOWN_SCRIPT_PROPERTY, /* Wancho */
};
#undef NONE
#undef TTB
#undef BTT
#undef LTR
#undef RTL
#undef WEAK
#undef S
#undef E
#undef N
#undef W
static inline ScriptTypeProperties get_script_properties (ScriptType script)
{
if (script < 0 || (size_t)script >= TABLESIZE (script_properties))
return script_properties[0];
return script_properties[script];
}
LayoutGravity ScriptGetLayoutGravity (ScriptType script,
LayoutGravity base_gravity, LayoutGravityPolicy hint)
{
ScriptTypeProperties props = get_script_properties (script);
if (base_gravity == LAYOUT_GRAVITY_AUTO)
base_gravity = props.preferred_gravity;
return ScriptGetLayoutGravityForWide (script, props.wide,
base_gravity, hint);
}
LayoutGravity ScriptGetLayoutGravityForWide (ScriptType script,
BOOL wide, LayoutGravity base_gravity, LayoutGravityPolicy hint)
{
ScriptTypeProperties props = get_script_properties (script);
BOOL vertical;
if (base_gravity == LAYOUT_GRAVITY_AUTO)
base_gravity = props.preferred_gravity;
vertical = LAYOUT_GRAVITY_IS_VERTICAL(base_gravity);
/* Everything is designed such that a system with no vertical support
* renders everything correctly horizontally. So, if not in a vertical
* gravity, base and resolved gravities are always the same.
*
* Wide characters are always upright.
*/
if (!vertical || wide)
return base_gravity;
/* If here, we have a narrow character in a vertical gravity setting.
* Resolve depending on the hint.
*/
switch (hint) {
default:
case LAYOUT_GRAVITY_POLICY_NATURAL:
if (props.vert_dir == VERTICAL_DIRECTION_NONE)
return LAYOUT_GRAVITY_SOUTH;
if ((base_gravity == LAYOUT_GRAVITY_EAST) ^
(props.vert_dir == VERTICAL_DIRECTION_BTT))
return LAYOUT_GRAVITY_SOUTH;
else
return LAYOUT_GRAVITY_NORTH;
case LAYOUT_GRAVITY_POLICY_STRONG:
return base_gravity;
case LAYOUT_GRAVITY_POLICY_LINE:
if ((base_gravity == LAYOUT_GRAVITY_EAST) ^
(props.horiz_dir == GLYPH_RUN_DIR_RTL))
return LAYOUT_GRAVITY_SOUTH;
else
return LAYOUT_GRAVITY_NORTH;
}
}
#endif /* _MGCHARSET_UNICODE */