/src/libreoffice/i18nutil/source/utility/scriptclass.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <config_locales.h> |
21 | | |
22 | | #include <i18nutil/scriptclass.hxx> |
23 | | #include <cppuhelper/supportsservice.hxx> |
24 | | #include <unicode/uchar.h> |
25 | | #include <i18nutil/unicode.hxx> |
26 | | #include <o3tl/string_view.hxx> |
27 | | |
28 | | #include <com/sun/star/i18n/CharType.hpp> |
29 | | #include <com/sun/star/i18n/ScriptType.hpp> |
30 | | #include <com/sun/star/i18n/WordType.hpp> |
31 | | #include <com/sun/star/uno/XComponentContext.hpp> |
32 | | |
33 | | #include <iterator> |
34 | | |
35 | | using namespace ::com::sun::star; |
36 | | using namespace ::com::sun::star::uno; |
37 | | using namespace ::com::sun::star::i18n; |
38 | | using namespace ::com::sun::star::lang; |
39 | | |
40 | | namespace i18nutil |
41 | | { |
42 | | namespace |
43 | | { |
44 | | sal_Int16 getScriptClassByUAX24Script(sal_uInt32 currentChar) |
45 | 64.4M | { |
46 | 64.4M | int32_t script = u_getIntPropertyValue(currentChar, UCHAR_SCRIPT); |
47 | 64.4M | return unicode::getScriptClassFromUScriptCode(static_cast<UScriptCode>(script)); |
48 | 64.4M | } |
49 | | |
50 | | struct UBlock2Script |
51 | | { |
52 | | UBlockCode from; |
53 | | UBlockCode to; |
54 | | sal_Int16 script; |
55 | | }; |
56 | | |
57 | | const UBlock2Script scriptList[] = { |
58 | | { UBLOCK_NO_BLOCK, UBLOCK_NO_BLOCK, ScriptType::WEAK }, |
59 | | { UBLOCK_BASIC_LATIN, UBLOCK_SPACING_MODIFIER_LETTERS, ScriptType::LATIN }, |
60 | | { UBLOCK_GREEK, UBLOCK_ARMENIAN, ScriptType::LATIN }, |
61 | | { UBLOCK_HEBREW, UBLOCK_MYANMAR, ScriptType::COMPLEX }, |
62 | | { UBLOCK_GEORGIAN, UBLOCK_GEORGIAN, ScriptType::LATIN }, |
63 | | { UBLOCK_HANGUL_JAMO, UBLOCK_HANGUL_JAMO, ScriptType::ASIAN }, |
64 | | { UBLOCK_ETHIOPIC, UBLOCK_ETHIOPIC, ScriptType::COMPLEX }, |
65 | | { UBLOCK_CHEROKEE, UBLOCK_RUNIC, ScriptType::LATIN }, |
66 | | { UBLOCK_KHMER, UBLOCK_MONGOLIAN, ScriptType::COMPLEX }, |
67 | | { UBLOCK_LATIN_EXTENDED_ADDITIONAL, UBLOCK_GREEK_EXTENDED, ScriptType::LATIN }, |
68 | | { UBLOCK_NUMBER_FORMS, UBLOCK_NUMBER_FORMS, ScriptType::WEAK }, |
69 | | { UBLOCK_CJK_RADICALS_SUPPLEMENT, UBLOCK_HANGUL_SYLLABLES, ScriptType::ASIAN }, |
70 | | { UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS, UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS, ScriptType::ASIAN }, |
71 | | { UBLOCK_ARABIC_PRESENTATION_FORMS_A, UBLOCK_ARABIC_PRESENTATION_FORMS_A, ScriptType::COMPLEX }, |
72 | | { UBLOCK_CJK_COMPATIBILITY_FORMS, UBLOCK_CJK_COMPATIBILITY_FORMS, ScriptType::ASIAN }, |
73 | | { UBLOCK_ARABIC_PRESENTATION_FORMS_B, UBLOCK_ARABIC_PRESENTATION_FORMS_B, ScriptType::COMPLEX }, |
74 | | { UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS, UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS, |
75 | | ScriptType::ASIAN }, |
76 | | { UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B, UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT, |
77 | | ScriptType::ASIAN }, |
78 | | { UBLOCK_CJK_STROKES, UBLOCK_CJK_STROKES, ScriptType::ASIAN }, |
79 | | { UBLOCK_LATIN_EXTENDED_C, UBLOCK_LATIN_EXTENDED_D, ScriptType::LATIN } |
80 | | }; |
81 | | |
82 | | //always sets rScriptType |
83 | | |
84 | | //returns true for characters historically explicitly assigned to |
85 | | //latin/weak/asian |
86 | | |
87 | | //returns false for characters that historically implicitly assigned to |
88 | | //weak as unknown |
89 | | bool getCompatibilityScriptClassByBlock(sal_uInt32 currentChar, sal_Int16& rScriptType) |
90 | 1.10G | { |
91 | 1.10G | bool bKnown = true; |
92 | | //handle specific characters always as weak: |
93 | | // 0x01 - this breaks a word |
94 | | // 0x02 - this can be inside a word |
95 | | // 0x20 & 0xA0 - Bug 102975, declare western space and non-break space as WEAK char. |
96 | 1.10G | if (0x01 == currentChar || 0x02 == currentChar || 0x20 == currentChar || 0xA0 == currentChar) |
97 | 40.5M | rScriptType = ScriptType::WEAK; |
98 | | // Few Spacing Modifier Letters that can be Bopomofo tonal marks. |
99 | 1.06G | else if (0x2CA == currentChar || 0x2CB == currentChar || 0x2C7 == currentChar |
100 | 1.06G | || 0x2D9 == currentChar) |
101 | 410k | rScriptType = ScriptType::WEAK; |
102 | | // tdf#52577 superscript numbers should be we weak. |
103 | 1.05G | else if (0xB2 == currentChar || 0xB3 == currentChar || 0xB9 == currentChar) |
104 | 364k | rScriptType = ScriptType::WEAK; |
105 | | // workaround for Coptic |
106 | 1.05G | else if (0x2C80 <= currentChar && 0x2CE3 >= currentChar) |
107 | 76.4k | rScriptType = ScriptType::LATIN; |
108 | 1.05G | else |
109 | 1.05G | { |
110 | 1.05G | UBlockCode block = ublock_getCode(currentChar); |
111 | 1.05G | size_t i = 0; |
112 | 3.86G | while (i < std::size(scriptList)) |
113 | 3.85G | { |
114 | 3.85G | if (block <= scriptList[i].to) |
115 | 1.05G | break; |
116 | 2.80G | ++i; |
117 | 2.80G | } |
118 | 1.05G | if (i < std::size(scriptList) && block >= scriptList[i].from) |
119 | 994M | rScriptType = scriptList[i].script; |
120 | 64.4M | else |
121 | 64.4M | { |
122 | 64.4M | rScriptType = ScriptType::WEAK; |
123 | 64.4M | bKnown = false; |
124 | 64.4M | } |
125 | 1.05G | } |
126 | 1.10G | return bKnown; |
127 | 1.10G | } |
128 | | } |
129 | | } |
130 | | |
131 | | sal_Int16 i18nutil::GetScriptClass(sal_uInt32 currentChar) |
132 | 1.10G | { |
133 | 1.10G | sal_Int16 nRet = ScriptType::WEAK; |
134 | | |
135 | 1.10G | if (!getCompatibilityScriptClassByBlock(currentChar, nRet)) |
136 | 64.4M | { |
137 | 64.4M | nRet = getScriptClassByUAX24Script(currentChar); |
138 | 64.4M | } |
139 | | |
140 | 1.10G | return nRet; |
141 | 1.10G | } |
142 | | |
143 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |