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