1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_unotools.hxx"
26 #include <unotools/fontdefs.hxx>
27 #include <unotools/fontcfg.hxx>
28 #include <hash_map>
29
30 struct ImplLocalizedFontName
31 {
32 const char* mpEnglishName;
33 const sal_Unicode* mpLocalizedNames;
34 };
35
36 // TODO: where did the 0,0 delimiters come from? A single 0 should suffice...
37 static sal_Unicode const aBatang[] = { 0xBC14, 0xD0D5, 0, 0 };
38 static sal_Unicode const aBatangChe[] = { 0xBC14, 0xD0D5, 0xCCB4, 0, 0 };
39 static sal_Unicode const aGungsuh[] = { 0xAD81, 0xC11C, 0, 0 };
40 static sal_Unicode const aGungsuhChe[] = { 0xAD81, 0xC11C, 0xCCB4, 0, 0 };
41 static sal_Unicode const aGulim[] = { 0xAD74, 0xB9BC, 0, 0 };
42 static sal_Unicode const aGulimChe[] = { 0xAD74, 0xB9BC, 0xCCB4, 0, 0 };
43 static sal_Unicode const aDotum[] = { 0xB3CB, 0xC6C0, 0, 0 };
44 static sal_Unicode const aDotumChe[] = { 0xB3CB, 0xC6C0, 0xCCB4, 0, 0 };
45 static sal_Unicode const aSimSun[] = { 0x5B8B, 0x4F53, 0, 0 };
46 static sal_Unicode const aNSimSun[] = { 0x65B0, 0x5B8B, 0x4F53, 0, 0 };
47 static sal_Unicode const aSimHei[] = { 0x9ED1, 0x4F53, 0, 0 };
48 static sal_Unicode const aSimKai[] = { 0x6977, 0x4F53, 0, 0 };
49 static sal_Unicode const azycjkSun[] = { 0x4E2D, 0x6613, 0x5B8B, 0x4F53, 0, 0 };
50 static sal_Unicode const azycjkHei[] = { 0x4E2D, 0x6613, 0x9ED1, 0x4F53, 0, 0 };
51 static sal_Unicode const azycjkKai[] = { 0x4E2D, 0x6613, 0x6977, 0x4F53, 0, 0 };
52 static sal_Unicode const aFZHei[] = { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0, 0 };
53 static sal_Unicode const aFZKai[] = { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0, 0 };
54 static sal_Unicode const aFZSongYI[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4E00, 0, 0 };
55 static sal_Unicode const aFZShuSong[] = { 0x65B9, 0x6B63, 0x4E66, 0x5B8B, 0, 0 };
56 static sal_Unicode const aFZFangSong[] = { 0x65B9, 0x6B63, 0x4EFF, 0x5B8B, 0, 0 };
57 // Attention: this fonts includes the wrong encoding vector - so we double the names with correct and wrong encoding
58 // First one is the GB-Encoding (we think the correct one), second is the big5 encoded name
59 static sal_Unicode const aMHei[] = { 'm', 0x7B80, 0x9ED1, 0, 'm', 0x6F60, 0x7AAA, 0, 0 };
60 static sal_Unicode const aMKai[] = { 'm', 0x7B80, 0x6977, 0x566C, 0, 'm', 0x6F60, 0x7FF1, 0x628E, 0, 0 };
61 static sal_Unicode const aMSong[] = { 'm', 0x7B80, 0x5B8B, 0, 'm', 0x6F60, 0x51BC, 0, 0 };
62 static sal_Unicode const aCFangSong[] = { 'm', 0x7B80, 0x592B, 0x5B8B, 0, 'm', 0x6F60, 0x6E98, 0x51BC, 0, 0 };
63 static sal_Unicode const aMingLiU[] = { 0x7D30, 0x660E, 0x9AD4, 0, 0 };
64 static sal_Unicode const aPMingLiU[] = { 0x65B0, 0x7D30, 0x660E, 0x9AD4, 0, 0 };
65 static sal_Unicode const aHei[] = { 0x6865, 0, 0 };
66 static sal_Unicode const aKai[] = { 0x6B61, 0, 0 };
67 static sal_Unicode const aMing[] = { 0x6D69, 0x6E67, 0, 0 };
68 static sal_Unicode const aMSGothic[] = { 'm','s', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
69 static sal_Unicode const aMSPGothic[] = { 'm','s','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
70 static sal_Unicode const aMSMincho[] = { 'm', 's', 0x660E, 0x671D, 0 };
71 static sal_Unicode const aMSPMincho[] = { 'm','s','p', 0x660E, 0x671D, 0 };
72 static sal_Unicode const aMSYaHei[] = { 0x5FAE, 0x8F6F, 0x96C5, 0x9ED1, 0 };
73 static sal_Unicode const aMSJhengHei[] = { 0x5FAE, 0x8EDF, 0x6B63, 0x9ED1, 0x9AD4, 0 };
74 static sal_Unicode const aMeiryo[] = { 0x30e1, 0x30a4, 0x30ea, 0x30aa, 0 };
75 static sal_Unicode const aHGMinchoL[] = { 'h','g', 0x660E, 0x671D, 'l', 0, 0 };
76 static sal_Unicode const aHGGothicB[] = { 'h','g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
77 static sal_Unicode const aHGPMinchoL[] = { 'h','g','p', 0x660E, 0x671D, 'l', 0 };
78 static sal_Unicode const aHGPGothicB[] = { 'h','g','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
79 static sal_Unicode const aHGMinchoLSun[] = { 'h','g', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
80 static sal_Unicode const aHGPMinchoLSun[] = { 'h','g','p', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
81 static sal_Unicode const aHGGothicBSun[] = { 'h', 'g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
82 static sal_Unicode const aHGPGothicBSun[] = { 'h', 'g', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
83 static sal_Unicode const aHGHeiseiMin[] = { 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 0, 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 'w', '3', 'x', '1', '2', 0, 0 };
84 static sal_Unicode const aIPAMincho[] = { 'i', 'p', 'a', 0x660E, 0x671D, 0 };
85 static sal_Unicode const aIPAPMincho[] = { 'i', 'p', 'a', 'p', 0x660E, 0x671D, 0 };
86 static sal_Unicode const aIPAGothic[] = { 'i', 'p', 'a', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
87 static sal_Unicode const aIPAPGothic[] = { 'i', 'p', 'a', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
88 static sal_Unicode const aIPAUIGothic[] = { 'i', 'p', 'a', 'u', 'i', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
89 static sal_Unicode const aSazanamiMincho[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x660E, 0x671D, 0, 0 };
90 static sal_Unicode const aSazanamiGothic[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
91 static sal_Unicode const aKochiMincho[] = { 0x6771, 0x98A8, 0x660E, 0x671D, 0, 0 };
92 static sal_Unicode const aKochiGothic[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0, 0 };
93 static sal_Unicode const aSunDotum[] = { 0xC36C, 0xB3CB, 0xC6C0, 0, 0 };
94 static sal_Unicode const aSunGulim[] = { 0xC36C, 0xAD74, 0xB9BC, 0, 0 };
95 static sal_Unicode const aSunBatang[] = { 0xC36C, 0xBC14, 0xD0D5, 0, 0 };
96 static sal_Unicode const aBaekmukDotum[] = { 0xBC31, 0xBB35, 0xB3CB, 0xC6C0, 0, 0 };
97 static sal_Unicode const aBaekmukGulim[] = { 0xBC31, 0xBB35, 0xAD74, 0xB9BC, 0, 0 };
98 static sal_Unicode const aBaekmukBatang[] = { 0xBC31, 0xBB35, 0xBC14, 0xD0D5, 0, 0 };
99 static sal_Unicode const aFzMingTi[] = { 0x65B9, 0x6B63, 0x660E, 0x9AD4, 0, 0 };
100 static sal_Unicode const aFzHeiTiTW[]= { 0x65B9, 0x6B63, 0x9ED1, 0x9AD4, 0, 0 };
101 static sal_Unicode const aFzKaiTiTW[]= { 0x65B9, 0x6B63, 0x6977, 0x9AD4, 0, 0 };
102 static sal_Unicode const aFzHeiTiCN[]= { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0, 0 };
103 static sal_Unicode const aFzKaiTiCN[]= { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0, 0 };
104 static sal_Unicode const aFzSongTi[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4F53, 0, 0 };
105 static sal_Unicode const aHYMyeongJoExtra[] = { 'h', 'y', 0xACAC, 0xBA85, 0xC870, 0, 0 };
106 static sal_Unicode const aHYSinMyeongJoMedium[] = { 'h', 'y', 0xC2E0, 0xBA85, 0xC870, 0, 0 };
107 static sal_Unicode const aHYGothicMedium[] = { 'h', 'y', 0xC911, 0xACE0, 0xB515, 0, 0 };
108 static sal_Unicode const aHYGraphicMedium[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 'm', 0, 0 };
109 static sal_Unicode const aHYGraphic[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 0, 0 };
110 static sal_Unicode const aNewGulim[] = { 0xC0C8, 0xAD74, 0xB9BC, 0, 0 };
111 static sal_Unicode const aSunGungseo[] = { 0xC36C, 0xAD81, 0xC11C, 0, 0 };
112 static sal_Unicode const aHYGungSoBold[] = { 'h','y', 0xAD81, 0xC11C, 'b', 0, 0 };
113 static sal_Unicode const aHYGungSo[] = { 'h','y', 0xAD81, 0xC11C, 0, 0 };
114 static sal_Unicode const aSunHeadLine[] = { 0xC36C, 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0, 0 };
115 static sal_Unicode const aHYHeadLineMedium[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 'm', 0, 0 };
116 static sal_Unicode const aHYHeadLine[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0, 0 };
117 static sal_Unicode const aYetR[] = { 0xD734, 0xBA3C, 0xC61B, 0xCCB4, 0, 0 };
118 static sal_Unicode const aHYGothicExtra[] = { 'h', 'y', 0xACAC, 0xACE0, 0xB515, 0, 0 };
119 static sal_Unicode const aSunMokPan[] = { 0xC36C, 0xBAA9, 0xD310, 0, 0 };
120 static sal_Unicode const aSunYeopseo[] = { 0xC36C, 0xC5FD, 0xC11C, 0, 0 };
121 static sal_Unicode const aSunBaekSong[] = { 0xC36C, 0xBC31, 0xC1A1, 0, 0 };
122 static sal_Unicode const aHYPostLight[] = { 'h', 'y', 0xC5FD, 0xC11C, 'l', 0, 0 };
123 static sal_Unicode const aHYPost[] = { 'h', 'y', 0xC5FD, 0xC11C, 0, 0 };
124 static sal_Unicode const aMagicR[] = { 0xD734, 0xBA3C, 0xB9E4, 0xC9C1, 0xCCB4, 0, 0 };
125 static sal_Unicode const aSunCrystal[] = { 0xC36C, 0xD06C, 0xB9AC, 0xC2A4, 0xD0C8, 0, 0 };
126 static sal_Unicode const aSunSaemmul[] = { 0xC36C, 0xC0D8, 0xBB3C, 0, 0 };
127 static sal_Unicode const aHaansoftBatang[] = { 0xD55C, 0xCEF4, 0xBC14, 0xD0D5, 0, 0 };
128 static sal_Unicode const aHaansoftDotum[] = { 0xD55C, 0xCEF4, 0xB3CB, 0xC6C0, 0, 0 };
129 static sal_Unicode const aHyhaeseo[] = { 0xD55C, 0xC591, 0xD574, 0xC11C, 0, 0 };
130 static sal_Unicode const aMDSol[] = { 'm', 'd', 0xC194, 0xCCB4, 0, 0 };
131 static sal_Unicode const aMDGaesung[] = { 'm', 'd', 0xAC1C, 0xC131, 0xCCB4, 0, 0 };
132 static sal_Unicode const aMDArt[] = { 'm', 'd', 0xC544, 0xD2B8, 0xCCB4, 0, 0 };
133 static sal_Unicode const aMDAlong[] = { 'm', 'd', 0xC544, 0xB871, 0xCCB4, 0, 0 };
134 static sal_Unicode const aMDEasop[] = { 'm', 'd', 0xC774, 0xC19D, 0xCCB4, 0, 0 };
135 static sal_Unicode const aHYShortSamulMedium[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 'm', 0 };
136 static sal_Unicode const aHYShortSamul[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 0 };
137 static sal_Unicode const aHGGothicE[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
138 static sal_Unicode const aHGPGothicE[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
139 static sal_Unicode const aHGSGothicE[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
140 static sal_Unicode const aHGGothicM[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
141 static sal_Unicode const aHGPGothicM[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
142 static sal_Unicode const aHGSGothicM[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
143 static sal_Unicode const aHGGyoshotai[] = { 'h','g', 0x884C, 0x66F8, 0x4F53, 0 };
144 static sal_Unicode const aHGPGyoshotai[] = { 'h','g','p', 0x884C, 0x66F8, 0x4F53, 0 };
145 static sal_Unicode const aHGSGyoshotai[] = { 'h','g','s', 0x884C, 0x66F8, 0x4F53, 0 };
146 static sal_Unicode const aHGKyokashotai[] = { 'h','g', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
147 static sal_Unicode const aHGPKyokashotai[] = { 'h','g','p', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
148 static sal_Unicode const aHGSKyokashotai[] = { 'h','g','s', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
149 static sal_Unicode const aHGMinchoB[] = { 'h','g', 0x660E, 0x671D, 'b', 0 };
150 static sal_Unicode const aHGPMinchoB[] = { 'h','g','p', 0x660E, 0x671D, 'b', 0 };
151 static sal_Unicode const aHGSMinchoB[] = { 'h','g','s', 0x660E, 0x671D, 'b', 0 };
152 static sal_Unicode const aHGMinchoE[] = { 'h','g', 0x660E, 0x671D, 'e', 0 };
153 static sal_Unicode const aHGPMinchoE[] = { 'h','g','p', 0x660E, 0x671D, 'e', 0 };
154 static sal_Unicode const aHGSMinchoE[] = { 'h','g','s', 0x660E, 0x671D, 'e', 0 };
155 static sal_Unicode const aHGSoeiKakupoptai[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF8E,
156 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
157 static sal_Unicode const aHGPSoeiKakupoptai[] = { 'h','g', 'p', 0x5275,0x82F1,0x89D2,0xFF8E,
158 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
159 static sal_Unicode const aHGSSoeiKakupoptai[] = { 'h','g', 's', 0x5275,0x82F1,0x89D2,0xFF8E,
160 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
161 static sal_Unicode const aHGSoeiPresenceEB[] = { 'h','g', 0x5275,0x82F1,0xFF8C,0xFF9F,
162 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
163 static sal_Unicode const aHGPSoeiPresenceEB[] = { 'h','g','p', 0x5275,0x82F1,0xFF8C,0xFF9F,
164 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
165 static sal_Unicode const aHGSSoeiPresenceEB[] = { 'h','g','s', 0x5275,0x82F1,0xFF8C,0xFF9F,
166 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
167 static sal_Unicode const aHGSoeiKakugothicUB[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF7A,
168 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
169 static sal_Unicode const aHGPSoeiKakugothicUB[] = { 'h','g','p', 0x5275,0x82F1,0x89D2,0xFF7A,
170 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
171 static sal_Unicode const aHGSSoeiKakugothicUB[] = { 'h','g','s', 0x5275,0x82F1,0x89D2,0xFF7A,
172 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
173 static sal_Unicode const aHGSeikaishotaiPRO[] = { 'h','g', 0x6B63,0x6977,0x66F8,0x4F53, '-','p','r','o',0};
174 static sal_Unicode const aHGMaruGothicMPRO[] = { 'h','g', 0x4E38,0xFF7A,0xFF9E,0xFF7C,0xFF6F,0xFF78, '-','p','r','o',0};
175 static sal_Unicode const aHiraginoMinchoPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o',0};
176 static sal_Unicode const aHiraginoMinchoProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o','n',0};
177 static sal_Unicode const aHiraginoKakuGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o',0};
178 static sal_Unicode const aHiraginoKakuGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o','n',0};
179 static sal_Unicode const aHiraginoMaruGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o',0};
180 static sal_Unicode const aHiraginoMaruGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o','n',0};
181
182 static ImplLocalizedFontName aImplLocalizedNamesList[] =
183 {
184 { "batang", aBatang },
185 { "batangche", aBatangChe },
186 { "gungshu", aGungsuh },
187 { "gungshuche", aGungsuhChe },
188 { "gulim", aGulim },
189 { "gulimche", aGulimChe },
190 { "dotum", aDotum },
191 { "dotumche", aDotumChe },
192 { "simsun", aSimSun },
193 { "nsimsun", aNSimSun },
194 { "simhei", aSimHei },
195 { "simkai", aSimKai },
196 { "zycjksun", azycjkSun },
197 { "zycjkhei", azycjkHei },
198 { "zycjkkai", azycjkKai },
199 { "fzhei", aFZHei },
200 { "fzkai", aFZKai },
201 { "fzsong", aFZSongYI },
202 { "fzshusong", aFZShuSong },
203 { "fzfangsong", aFZFangSong },
204 { "mhei", aMHei },
205 { "mkai", aMKai },
206 { "msong", aMSong },
207 { "cfangsong", aCFangSong },
208 { "mingliu", aMingLiU },
209 { "pmingliu", aPMingLiU },
210 { "hei", aHei },
211 { "kai", aKai },
212 { "ming", aMing },
213 { "msgothic", aMSGothic },
214 { "mspgothic", aMSPGothic },
215 { "msmincho", aMSMincho },
216 { "mspmincho", aMSPMincho },
217 { "microsoftjhenghei", aMSJhengHei },
218 { "microsoftyahei", aMSYaHei },
219 { "meiryo", aMeiryo },
220 { "hgminchol", aHGMinchoL },
221 { "hggothicb", aHGGothicB },
222 { "hgpminchol", aHGPMinchoL },
223 { "hgpgothicb", aHGPGothicB },
224 { "hgmincholsun", aHGMinchoLSun },
225 { "hggothicbsun", aHGGothicBSun },
226 { "hgpmincholsun", aHGPMinchoLSun },
227 { "hgpgothicbsun", aHGPGothicBSun },
228 { "hgheiseimin", aHGHeiseiMin },
229 { "ipamincho", aIPAMincho },
230 { "ipapmincho", aIPAPMincho },
231 { "ipagothic", aIPAGothic },
232 { "ipapgothic", aIPAPGothic },
233 { "ipauigothic", aIPAUIGothic },
234 { "sazanamimincho", aSazanamiMincho },
235 { "sazanamigothic", aSazanamiGothic },
236 { "kochimincho", aKochiMincho },
237 { "kochigothic", aKochiGothic },
238 { "sundotum", aSunDotum },
239 { "sungulim", aSunGulim },
240 { "sunbatang", aSunBatang },
241 { "baekmukdotum", aBaekmukDotum },
242 { "baekmukgulim", aBaekmukGulim },
243 { "baekmukbatang", aBaekmukBatang },
244 { "fzheiti", aFzHeiTiCN },
245 { "fzheiti", aFzHeiTiTW },
246 { "fzkaiti", aFzKaiTiCN },
247 { "fzkaitib", aFzKaiTiTW },
248 { "fzmingtib", aFzMingTi },
249 { "fzsongti", aFzSongTi },
250 { "hymyeongjoextra", aHYMyeongJoExtra },
251 { "hysinmyeongjomedium", aHYSinMyeongJoMedium },
252 { "hygothicmedium", aHYGothicMedium },
253 { "hygraphicmedium", aHYGraphicMedium },
254 { "hygraphic", aHYGraphic },
255 { "newgulim", aNewGulim },
256 { "sungungseo", aSunGungseo },
257 { "hygungsobold", aHYGungSoBold },
258 { "hygungso", aHYGungSo },
259 { "sunheadline", aSunHeadLine },
260 { "hyheadlinemedium", aHYHeadLineMedium },
261 { "hyheadline", aHYHeadLine },
262 { "yetr", aYetR },
263 { "hygothicextra", aHYGothicExtra },
264 { "sunmokpan", aSunMokPan },
265 { "sunyeopseo", aSunYeopseo },
266 { "sunbaeksong", aSunBaekSong },
267 { "hypostlight", aHYPostLight },
268 { "hypost", aHYPost },
269 { "magicr", aMagicR },
270 { "suncrystal", aSunCrystal },
271 { "sunsaemmul", aSunSaemmul },
272 { "hyshortsamulmedium", aHYShortSamulMedium },
273 { "hyshortsamul", aHYShortSamul },
274 { "haansoftbatang", aHaansoftBatang },
275 { "haansoftdotum", aHaansoftDotum },
276 { "hyhaeseo", aHyhaeseo },
277 { "mdsol", aMDSol },
278 { "mdgaesung", aMDGaesung },
279 { "mdart", aMDArt },
280 { "mdalong", aMDAlong },
281 { "mdeasop", aMDEasop },
282 { "hggothice", aHGGothicE },
283 { "hgpgothice", aHGPGothicE },
284 { "hgpothice", aHGSGothicE },
285 { "hggothicm", aHGGothicM },
286 { "hgpgothicm", aHGPGothicM },
287 { "hgpgothicm", aHGSGothicM },
288 { "hggyoshotai", aHGGyoshotai },
289 { "hgpgyoshotai", aHGPGyoshotai },
290 { "hgsgyoshotai", aHGSGyoshotai },
291 { "hgkyokashotai", aHGKyokashotai },
292 { "hgpkyokashotai", aHGPKyokashotai },
293 { "hgskyokashotai", aHGSKyokashotai },
294 { "hgminchob", aHGMinchoB },
295 { "hgpminchob", aHGPMinchoB },
296 { "hgsminchob", aHGSMinchoB },
297 { "hgminchoe", aHGMinchoE },
298 { "hgpminchoe", aHGPMinchoE },
299 { "hgsminchoe", aHGSMinchoE },
300 { "hgsoeikakupoptai", aHGSoeiKakupoptai },
301 { "hgpsoeikakupopta", aHGPSoeiKakupoptai },
302 { "hgssoeikakupopta", aHGSSoeiKakupoptai },
303 { "hgsoeipresenceeb", aHGSoeiPresenceEB },
304 { "hgpsoeipresenceeb", aHGPSoeiPresenceEB },
305 { "hgssoeipresenceeb", aHGSSoeiPresenceEB },
306 { "hgsoeikakugothicub", aHGSoeiKakugothicUB },
307 { "hgpsoeikakugothicub", aHGPSoeiKakugothicUB },
308 { "hgssoeikakugothicub", aHGSSoeiKakugothicUB },
309 { "hgseikaishotaipro", aHGSeikaishotaiPRO },
310 { "hgmarugothicmpro", aHGMaruGothicMPRO },
311 { "hiraginominchopro", aHiraginoMinchoPro },
312 { "hiraginominchopron", aHiraginoMinchoProN },
313 { "hiraginokakugothicpro", aHiraginoKakuGothicPro },
314 { "hiraginokakugothicpron", aHiraginoKakuGothicProN },
315 { "hiraginomarugothicpro", aHiraginoMaruGothicPro },
316 { "hiraginomarugothicpron", aHiraginoMaruGothicProN },
317 { NULL, NULL },
318 };
319
320 // -----------------------------------------------------------------------
321
GetEnglishSearchFontName(String & rName)322 void GetEnglishSearchFontName( String& rName )
323 {
324 bool bNeedTranslation = false;
325 xub_StrLen nLen = rName.Len();
326
327 // Remove trailing whitespaces
328 xub_StrLen i = nLen;
329 while ( i && (rName.GetChar( i-1 ) < 32) )
330 i--;
331 if ( i != nLen )
332 rName.Erase( i );
333
334 // Remove Script at the end
335 // Scriptname must be the last part of the fontname and
336 // looks like "fontname (scriptname)". So there can only be a
337 // script name at the and of the fontname, when the last char is ')'
338 if ( (nLen >= 3) && rName.GetChar( nLen-1 ) == ')' )
339 {
340 int nOpen = 1;
341 xub_StrLen nTempLen = nLen-2;
342 while ( nTempLen )
343 {
344 if ( rName.GetChar( nTempLen ) == '(' )
345 {
346 nOpen--;
347 if ( !nOpen )
348 {
349 // Remove Space at the end
350 if ( nTempLen && (rName.GetChar( nTempLen-1 ) == ' ') )
351 nTempLen--;
352 rName.Erase( nTempLen );
353 nLen = nTempLen;
354 break;
355 }
356 }
357 if ( rName.GetChar( nTempLen ) == ')' )
358 nOpen++;
359 nTempLen--;
360 }
361 }
362
363 // remove all whitespaces and converts to lower case ASCII
364 // TODO: better transliteration to ASCII e.g. all digits
365 i = 0;
366 while ( i < nLen )
367 {
368 sal_Unicode c = rName.GetChar( i );
369 if ( c > 127 )
370 {
371 // Translate to Lowercase-ASCII
372 // FullWidth-ASCII to half ASCII
373 if ( (c >= 0xFF00) && (c <= 0xFF5E) )
374 {
375 c -= 0xFF00-0x0020;
376 // Upper to Lower
377 if ( (c >= 'A') && (c <= 'Z') )
378 c += 'a' - 'A';
379 rName.SetChar( i, c );
380 }
381 else
382 {
383 // Only Fontnames with None-Ascii-Characters must be translated
384 bNeedTranslation = true;
385 }
386 }
387 // not lowercase Ascii
388 else if ( !((c >= 'a') && (c <= 'z')) )
389 {
390 // To Lowercase-Ascii
391 if ( (c >= 'A') && (c <= 'Z') )
392 {
393 c += 'a' - 'A';
394 rName.SetChar( i, c );
395 }
396 else if( ((c < '0') || (c > '9')) && (c != ';') ) // not 0-9 or semicolon
397 {
398 // Remove white spaces and special characters
399 rName.Erase( i, 1 );
400 nLen--;
401 continue;
402 }
403 }
404
405 i++;
406 }
407
408 // translate normalized localized name to its normalized English ASCII name
409 if( bNeedTranslation )
410 {
411 typedef std::hash_map<const String, const char*,FontNameHash> FontNameDictionary;
412 static FontNameDictionary aDictionary( sizeof(aImplLocalizedNamesList) / sizeof(*aImplLocalizedNamesList) );
413 // the font name dictionary needs to be intialized once
414 if( aDictionary.empty() )
415 {
416 // TODO: check if all dictionary entries are already normalized?
417 const ImplLocalizedFontName* pList = aImplLocalizedNamesList;
418 for(; pList->mpEnglishName; ++pList )
419 aDictionary[ pList->mpLocalizedNames ] = pList->mpEnglishName;
420 }
421
422 FontNameDictionary::const_iterator it = aDictionary.find( rName );
423 if( it != aDictionary.end() )
424 rName.AssignAscii( it->second );
425 }
426 }
427
428 // -----------------------------------------------------------------------
429
GetNextFontToken(const String & rTokenStr,xub_StrLen & rIndex)430 String GetNextFontToken( const String& rTokenStr, xub_StrLen& rIndex )
431 {
432 // check for valid start index
433 int nStringLen = rTokenStr.Len();
434 if( rIndex >= nStringLen )
435 {
436 rIndex = STRING_NOTFOUND;
437 return String();
438 }
439
440 // find the next token delimiter and return the token substring
441 const sal_Unicode* pStr = rTokenStr.GetBuffer() + rIndex;
442 const sal_Unicode* pEnd = rTokenStr.GetBuffer() + nStringLen;
443 for(; pStr < pEnd; ++pStr )
444 if( (*pStr == ';') || (*pStr == ',') )
445 break;
446
447 xub_StrLen nTokenStart = rIndex;
448 xub_StrLen nTokenLen;
449 if( pStr < pEnd )
450 {
451 rIndex = sal::static_int_cast<xub_StrLen>(pStr - rTokenStr.GetBuffer());
452 nTokenLen = rIndex - nTokenStart;
453 ++rIndex; // skip over token separator
454 }
455 else
456 {
457 // no token delimiter found => handle last token
458 rIndex = STRING_NOTFOUND;
459 nTokenLen = STRING_LEN;
460
461 // optimize if the token string consists of just one token
462 if( !nTokenStart )
463 return rTokenStr;
464 }
465
466 return String( rTokenStr, nTokenStart, nTokenLen );
467 }
468
469 // TODO: get rid of this in another incompatible build with SW project.
470 // SW's WW8 and RTF filters still use this (from fontcvt.hxx)
GetFontToken(const String & rTokenStr,xub_StrLen nToken,xub_StrLen & rIndex)471 String GetFontToken( const String& rTokenStr, xub_StrLen nToken, xub_StrLen& rIndex )
472 {
473 // skip nToken Tokens
474 for( xub_StrLen i = 0; (i < nToken) && (rIndex != STRING_NOTFOUND); ++i )
475 GetNextFontToken( rTokenStr, rIndex );
476
477 return GetNextFontToken( rTokenStr, rIndex );
478 }
479
480 // =======================================================================
481
ImplIsFontToken(const String & rName,const String & rToken)482 static bool ImplIsFontToken( const String& rName, const String& rToken )
483 {
484 String aTempName;
485 xub_StrLen nIndex = 0;
486 do
487 {
488 aTempName = GetNextFontToken( rName, nIndex );
489 if ( rToken == aTempName )
490 return true;
491 }
492 while ( nIndex != STRING_NOTFOUND );
493
494 return false;
495 }
496
497 // -----------------------------------------------------------------------
498
ImplAppendFontToken(String & rName,const String & rNewToken)499 static void ImplAppendFontToken( String& rName, const String& rNewToken )
500 {
501 if ( rName.Len() )
502 {
503 rName.Append( ';' );
504 rName.Append( rNewToken );
505 }
506 else
507 rName = rNewToken;
508 }
509
AddTokenFontName(String & rName,const String & rNewToken)510 void AddTokenFontName( String& rName, const String& rNewToken )
511 {
512 if ( !ImplIsFontToken( rName, rNewToken ) )
513 ImplAppendFontToken( rName, rNewToken );
514 }
515
516 // =======================================================================
517
GetSubsFontName(const String & rName,sal_uLong nFlags)518 String GetSubsFontName( const String& rName, sal_uLong nFlags )
519 {
520 String aName;
521
522 xub_StrLen nIndex = 0;
523 String aOrgName = GetNextFontToken( rName, nIndex );
524 GetEnglishSearchFontName( aOrgName );
525
526 // #93662# do not try to replace StarSymbol with MS only font
527 if( nFlags == (SUBSFONT_MS|SUBSFONT_ONLYONE)
528 && ( aOrgName.EqualsAscii( "starsymbol" )
529 || aOrgName.EqualsAscii( "opensymbol" ) ) )
530 return aName;
531
532 const utl::FontNameAttr* pAttr = utl::FontSubstConfiguration::get()->getSubstInfo( aOrgName );
533 if ( pAttr )
534 {
535 for( int i = 0; i < 3; i++ )
536 {
537 const ::std::vector< String >* pVector = NULL;
538 switch( i )
539 {
540 case 0:
541 if( nFlags & SUBSFONT_MS && pAttr->MSSubstitutions.size() )
542 pVector = &pAttr->MSSubstitutions;
543 break;
544 case 1:
545 if( nFlags & SUBSFONT_PS && pAttr->PSSubstitutions.size() )
546 pVector = &pAttr->PSSubstitutions;
547 break;
548 case 2:
549 if( nFlags & SUBSFONT_HTML && pAttr->HTMLSubstitutions.size() )
550 pVector = &pAttr->HTMLSubstitutions;
551 break;
552 }
553 if( ! pVector )
554 continue;
555 for( ::std::vector< String >::const_iterator it = pVector->begin(); it != pVector->end(); ++it )
556 if( ! ImplIsFontToken( rName, *it ) )
557 {
558 ImplAppendFontToken( aName, *it );
559 if( nFlags & SUBSFONT_ONLYONE )
560 {
561 i = 4;
562 break;
563 }
564 }
565 }
566 }
567
568 return aName;
569 }
570
571 // -----------------------------------------------------------------------
572
573 // TODO: use a more generic String hash
operator ()(const String & rStr) const574 int FontNameHash::operator()( const String& rStr ) const
575 {
576 // this simple hash just has to be good enough for font names
577 int nHash = 0;
578 const int nLen = rStr.Len();
579 const sal_Unicode* p = rStr.GetBuffer();
580 switch( nLen )
581 {
582 default: nHash = (p[0]<<16) - (p[1]<<8) + p[2];
583 nHash += nLen;
584 p += nLen - 3;
585 // fall through
586 case 3: nHash += (p[2]<<16); // fall through
587 case 2: nHash += (p[1]<<8); // fall through
588 case 1: nHash += p[0]; // fall through
589 case 0: break;
590 };
591
592 return nHash;
593 }
594
595