1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <o3tl/safeint.hxx>
21 #include <o3tl/string_view.hxx>
22 #include <unotools/fontdefs.hxx>
23 #include <unotools/fontcfg.hxx>
24 #include <rtl/ustrbuf.hxx>
26 #include <string_view>
27 #include <unordered_map>
29 sal_Unicode
const aBatang
[] = { 0xBC14, 0xD0D5, 0 };
30 sal_Unicode
const aBatangChe
[] = { 0xBC14, 0xD0D5, 0xCCB4, 0 };
31 sal_Unicode
const aGungsuh
[] = { 0xAD81, 0xC11C, 0 };
32 sal_Unicode
const aGungsuhChe
[] = { 0xAD81, 0xC11C, 0xCCB4, 0 };
33 sal_Unicode
const aGulim
[] = { 0xAD74, 0xB9BC, 0 };
34 sal_Unicode
const aGulimChe
[] = { 0xAD74, 0xB9BC, 0xCCB4, 0 };
35 sal_Unicode
const aDotum
[] = { 0xB3CB, 0xC6C0, 0 };
36 sal_Unicode
const aDotumChe
[] = { 0xB3CB, 0xC6C0, 0xCCB4, 0 };
37 sal_Unicode
const aSimSun
[] = { 0x5B8B, 0x4F53, 0 };
38 sal_Unicode
const aNSimSun
[] = { 0x65B0, 0x5B8B, 0x4F53, 0 };
39 sal_Unicode
const aSimHei
[] = { 0x9ED1, 0x4F53, 0 };
40 sal_Unicode
const aSimKai
[] = { 0x6977, 0x4F53, 0 };
41 sal_Unicode
const azycjkSun
[] = { 0x4E2D, 0x6613, 0x5B8B, 0x4F53, 0 };
42 sal_Unicode
const azycjkHei
[] = { 0x4E2D, 0x6613, 0x9ED1, 0x4F53, 0 };
43 sal_Unicode
const azycjkKai
[] = { 0x4E2D, 0x6613, 0x6977, 0x4F53, 0 };
44 sal_Unicode
const aFZHei
[] = { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0 };
45 sal_Unicode
const aFZKai
[] = { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0 };
46 sal_Unicode
const aFZSongYI
[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4E00, 0 };
47 sal_Unicode
const aFZShuSong
[] = { 0x65B9, 0x6B63, 0x4E66, 0x5B8B, 0 };
48 sal_Unicode
const aFZFangSong
[] = { 0x65B9, 0x6B63, 0x4EFF, 0x5B8B, 0 };
49 // Attention: this fonts includes the wrong encoding vector - so we double the names with correct and wrong encoding
50 // First one is the GB-Encoding (we think the correct one), second is the big5 encoded name
51 sal_Unicode
const aMHei1
[] = { 'm', 0x7B80, 0x9ED1, 0 };
52 sal_Unicode
const aMHei2
[] = { 'm', 0x6F60, 0x7AAA, 0 };
53 sal_Unicode
const aMKai1
[] = { 'm', 0x7B80, 0x6977, 0x566C, 0 };
54 sal_Unicode
const aMKai2
[] = { 'm', 0x6F60, 0x7FF1, 0x628E, 0 };
55 sal_Unicode
const aMSong1
[] = { 'm', 0x7B80, 0x5B8B, 0 };
56 sal_Unicode
const aMSong2
[] = { 'm', 0x6F60, 0x51BC, 0 };
57 sal_Unicode
const aCFangSong1
[] = { 'm', 0x7B80, 0x592B, 0x5B8B, 0 };
58 sal_Unicode
const aCFangSong2
[] = { 'm', 0x6F60, 0x6E98, 0x51BC, 0 };
59 sal_Unicode
const aMingLiU
[] = { 0x7D30, 0x660E, 0x9AD4, 0 };
60 sal_Unicode
const aPMingLiU
[] = { 0x65B0, 0x7D30, 0x660E, 0x9AD4, 0 };
61 sal_Unicode
const aHei
[] = { 0x6865, 0 };
62 sal_Unicode
const aKai
[] = { 0x6B61, 0 };
63 sal_Unicode
const aMing
[] = { 0x6D69, 0x6E67, 0 };
64 sal_Unicode
const aMSGothic
[] = { 'm','s', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
65 sal_Unicode
const aMSPGothic
[] = { 'm','s','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
66 sal_Unicode
const aMSMincho
[] = { 'm', 's', 0x660E, 0x671D, 0 };
67 sal_Unicode
const aMSPMincho
[] = { 'm','s','p', 0x660E, 0x671D, 0 };
68 sal_Unicode
const aMSYaHei
[] = { 0x5FAE, 0x8F6F, 0x96C5, 0x9ED1, 0 };
69 sal_Unicode
const aMSJhengHei
[] = { 0x5FAE, 0x8EDF, 0x6B63, 0x9ED1, 0x9AD4, 0 };
70 sal_Unicode
const aMeiryo
[] = { 0x30e1, 0x30a4, 0x30ea, 0x30aa, 0 };
71 sal_Unicode
const aHGMinchoL
[] = { 'h','g', 0x660E, 0x671D, 'l', 0 };
72 sal_Unicode
const aHGGothicB
[] = { 'h','g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
73 sal_Unicode
const aHGPMinchoL
[] = { 'h','g','p', 0x660E, 0x671D, 'l', 0 };
74 sal_Unicode
const aHGPGothicB
[] = { 'h','g','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
75 sal_Unicode
const aHGMinchoLSun
[] = { 'h','g', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
76 sal_Unicode
const aHGPMinchoLSun
[] = { 'h','g','p', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
77 sal_Unicode
const aHGGothicBSun
[] = { 'h', 'g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
78 sal_Unicode
const aHGPGothicBSun
[] = { 'h', 'g', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
79 sal_Unicode
const aHGHeiseiMin1
[] = { 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 0 };
80 sal_Unicode
const aHGHeiseiMin2
[] = { 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 'w', '3', 'x', '1', '2', 0 };
81 sal_Unicode
const aIPAMincho
[] = { 'i', 'p', 'a', 0x660E, 0x671D, 0 };
82 sal_Unicode
const aIPAPMincho
[] = { 'i', 'p', 'a', 'p', 0x660E, 0x671D, 0 };
83 sal_Unicode
const aIPAGothic
[] = { 'i', 'p', 'a', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
84 sal_Unicode
const aIPAPGothic
[] = { 'i', 'p', 'a', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
85 sal_Unicode
const aIPAUIGothic
[] = { 'i', 'p', 'a', 'u', 'i', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
86 sal_Unicode
const aTakaoMincho
[] = { 't', 'a', 'k', 'a', 'o', 0x660E, 0x671D, 0 };
87 sal_Unicode
const aTakaoPMincho
[] = { 't', 'a', 'k', 'a', 'o', 'p', 0x660E, 0x671D, 0 };
88 sal_Unicode
const aTakaoGothic
[] = { 't', 'a', 'k', 'a', 'o', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
89 sal_Unicode
const aTakaoPGothic
[] = { 't', 'a', 'k', 'a', 'o', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
90 sal_Unicode
const aSazanamiMincho
[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x660E, 0x671D, 0 };
91 sal_Unicode
const aSazanamiGothic
[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
92 sal_Unicode
const aKochiMincho
[] = { 0x6771, 0x98A8, 0x660E, 0x671D, 0 };
93 sal_Unicode
const aKochiGothic
[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
94 sal_Unicode
const aSunDotum
[] = { 0xC36C, 0xB3CB, 0xC6C0, 0 };
95 sal_Unicode
const aSunGulim
[] = { 0xC36C, 0xAD74, 0xB9BC, 0 };
96 sal_Unicode
const aSunBatang
[] = { 0xC36C, 0xBC14, 0xD0D5, 0 };
97 sal_Unicode
const aBaekmukDotum
[] = { 0xBC31, 0xBB35, 0xB3CB, 0xC6C0, 0 };
98 sal_Unicode
const aBaekmukGulim
[] = { 0xBC31, 0xBB35, 0xAD74, 0xB9BC, 0 };
99 sal_Unicode
const aBaekmukBatang
[] = { 0xBC31, 0xBB35, 0xBC14, 0xD0D5, 0 };
100 sal_Unicode
const aFzMingTi
[] = { 0x65B9, 0x6B63, 0x660E, 0x9AD4, 0 };
101 sal_Unicode
const aFzHeiTiTW
[]= { 0x65B9, 0x6B63, 0x9ED1, 0x9AD4, 0 };
102 sal_Unicode
const aFzKaiTiTW
[]= { 0x65B9, 0x6B63, 0x6977, 0x9AD4, 0 };
103 sal_Unicode
const aFzHeiTiCN
[]= { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0 };
104 sal_Unicode
const aFzKaiTiCN
[]= { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0 };
105 sal_Unicode
const aFzSongTi
[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4F53, 0 };
106 sal_Unicode
const aHYMyeongJoExtra
[] = { 'h', 'y', 0xACAC, 0xBA85, 0xC870, 0 };
107 sal_Unicode
const aHYSinMyeongJoMedium
[] = { 'h', 'y', 0xC2E0, 0xBA85, 0xC870, 0 };
108 sal_Unicode
const aHYGothicMedium
[] = { 'h', 'y', 0xC911, 0xACE0, 0xB515, 0 };
109 sal_Unicode
const aHYGraphicMedium
[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 'm', 0 };
110 sal_Unicode
const aHYGraphic
[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 0 };
111 sal_Unicode
const aNewGulim
[] = { 0xC0C8, 0xAD74, 0xB9BC, 0 };
112 sal_Unicode
const aSunGungseo
[] = { 0xC36C, 0xAD81, 0xC11C, 0 };
113 sal_Unicode
const aHYGungSoBold
[] = { 'h','y', 0xAD81, 0xC11C, 'b', 0 };
114 sal_Unicode
const aHYGungSo
[] = { 'h','y', 0xAD81, 0xC11C, 0 };
115 sal_Unicode
const aSunHeadLine
[] = { 0xC36C, 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0 };
116 sal_Unicode
const aHYHeadLineMedium
[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 'm', 0 };
117 sal_Unicode
const aHYHeadLine
[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0 };
118 sal_Unicode
const aYetR
[] = { 0xD734, 0xBA3C, 0xC61B, 0xCCB4, 0 };
119 sal_Unicode
const aHYGothicExtra
[] = { 'h', 'y', 0xACAC, 0xACE0, 0xB515, 0 };
120 sal_Unicode
const aSunMokPan
[] = { 0xC36C, 0xBAA9, 0xD310, 0 };
121 sal_Unicode
const aSunYeopseo
[] = { 0xC36C, 0xC5FD, 0xC11C, 0 };
122 sal_Unicode
const aSunBaekSong
[] = { 0xC36C, 0xBC31, 0xC1A1, 0 };
123 sal_Unicode
const aHYPostLight
[] = { 'h', 'y', 0xC5FD, 0xC11C, 'l', 0 };
124 sal_Unicode
const aHYPost
[] = { 'h', 'y', 0xC5FD, 0xC11C, 0 };
125 sal_Unicode
const aMagicR
[] = { 0xD734, 0xBA3C, 0xB9E4, 0xC9C1, 0xCCB4, 0 };
126 sal_Unicode
const aSunCrystal
[] = { 0xC36C, 0xD06C, 0xB9AC, 0xC2A4, 0xD0C8, 0 };
127 sal_Unicode
const aSunSaemmul
[] = { 0xC36C, 0xC0D8, 0xBB3C, 0 };
128 sal_Unicode
const aHaansoftBatang
[] = { 0xD55C, 0xCEF4, 0xBC14, 0xD0D5, 0 };
129 sal_Unicode
const aHaansoftDotum
[] = { 0xD55C, 0xCEF4, 0xB3CB, 0xC6C0, 0 };
130 sal_Unicode
const aHyhaeseo
[] = { 0xD55C, 0xC591, 0xD574, 0xC11C, 0 };
131 sal_Unicode
const aMDSol
[] = { 'm', 'd', 0xC194, 0xCCB4, 0 };
132 sal_Unicode
const aMDGaesung
[] = { 'm', 'd', 0xAC1C, 0xC131, 0xCCB4, 0 };
133 sal_Unicode
const aMDArt
[] = { 'm', 'd', 0xC544, 0xD2B8, 0xCCB4, 0 };
134 sal_Unicode
const aMDAlong
[] = { 'm', 'd', 0xC544, 0xB871, 0xCCB4, 0 };
135 sal_Unicode
const aMDEasop
[] = { 'm', 'd', 0xC774, 0xC19D, 0xCCB4, 0 };
136 sal_Unicode
const aHYShortSamulMedium
[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 'm', 0 };
137 sal_Unicode
const aHYShortSamul
[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 0 };
138 sal_Unicode
const aHGGothicE
[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
139 sal_Unicode
const aHGPGothicE
[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
140 sal_Unicode
const aHGSGothicE
[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
141 sal_Unicode
const aHGGothicM
[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
142 sal_Unicode
const aHGPGothicM
[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
143 sal_Unicode
const aHGSGothicM
[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
144 sal_Unicode
const aHGGyoshotai
[] = { 'h','g', 0x884C, 0x66F8, 0x4F53, 0 };
145 sal_Unicode
const aHGPGyoshotai
[] = { 'h','g','p', 0x884C, 0x66F8, 0x4F53, 0 };
146 sal_Unicode
const aHGSGyoshotai
[] = { 'h','g','s', 0x884C, 0x66F8, 0x4F53, 0 };
147 sal_Unicode
const aHGKyokashotai
[] = { 'h','g', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
148 sal_Unicode
const aHGPKyokashotai
[] = { 'h','g','p', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
149 sal_Unicode
const aHGSKyokashotai
[] = { 'h','g','s', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
150 sal_Unicode
const aHGMinchoB
[] = { 'h','g', 0x660E, 0x671D, 'b', 0 };
151 sal_Unicode
const aHGPMinchoB
[] = { 'h','g','p', 0x660E, 0x671D, 'b', 0 };
152 sal_Unicode
const aHGSMinchoB
[] = { 'h','g','s', 0x660E, 0x671D, 'b', 0 };
153 sal_Unicode
const aHGMinchoE
[] = { 'h','g', 0x660E, 0x671D, 'e', 0 };
154 sal_Unicode
const aHGPMinchoE
[] = { 'h','g','p', 0x660E, 0x671D, 'e', 0 };
155 sal_Unicode
const aHGSMinchoE
[] = { 'h','g','s', 0x660E, 0x671D, 'e', 0 };
156 sal_Unicode
const aHGSoeiKakupoptai
[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF8E,
157 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
158 sal_Unicode
const aHGPSoeiKakupoptai
[] = { 'h','g', 'p', 0x5275,0x82F1,0x89D2,0xFF8E,
159 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
160 sal_Unicode
const aHGSSoeiKakupoptai
[] = { 'h','g', 's', 0x5275,0x82F1,0x89D2,0xFF8E,
161 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
162 sal_Unicode
const aHGSoeiPresenceEB
[] = { 'h','g', 0x5275,0x82F1,0xFF8C,0xFF9F,
163 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
164 sal_Unicode
const aHGPSoeiPresenceEB
[] = { 'h','g','p', 0x5275,0x82F1,0xFF8C,0xFF9F,
165 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
166 sal_Unicode
const aHGSSoeiPresenceEB
[] = { 'h','g','s', 0x5275,0x82F1,0xFF8C,0xFF9F,
167 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
168 sal_Unicode
const aHGSoeiKakugothicUB
[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF7A,
169 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
170 sal_Unicode
const aHGPSoeiKakugothicUB
[] = { 'h','g','p', 0x5275,0x82F1,0x89D2,0xFF7A,
171 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
172 sal_Unicode
const aHGSSoeiKakugothicUB
[] = { 'h','g','s', 0x5275,0x82F1,0x89D2,0xFF7A,
173 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
174 sal_Unicode
const aHGSeikaishotaiPRO
[] = { 'h','g', 0x6B63,0x6977,0x66F8,0x4F53, '-','p','r','o',0};
175 sal_Unicode
const aHGMaruGothicMPRO
[] = { 'h','g', 0x4E38,0xFF7A,0xFF9E,0xFF7C,0xFF6F,0xFF78, '-','p','r','o',0};
176 sal_Unicode
const aHiraginoMinchoPro
[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o',0};
177 sal_Unicode
const aHiraginoMinchoProN
[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o','n',0};
178 sal_Unicode
const aHiraginoKakuGothic
[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF,0};
179 sal_Unicode
const aHiraginoKakuGothicPro
[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o',0};
180 sal_Unicode
const aHiraginoKakuGothicProN
[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o','n',0};
181 sal_Unicode
const aHiraginoMaruGothicPro
[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o',0};
182 sal_Unicode
const aHiraginoMaruGothicProN
[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o','n',0};
183 sal_Unicode
const aYuGothic
[] = { 0x6E38, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0};
184 sal_Unicode
const aYuGothicTai
[] = { 0x6E38, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0x4F53, 0};
185 sal_Unicode
const aYuMincho
[] = { 0x6E38, 0x660E, 0x671D, 0};
186 sal_Unicode
const aYuMinchoTai
[] = { 0x6E38, 0x660E, 0x671D, 0x4F53, 0};
187 sal_Unicode
const aGennoKakuGothic
[] = { 0x6E90, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0};
188 sal_Unicode
const aGennoKakuGothicJP
[] = { 0x6E90, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'j', 'p', 0};
189 sal_Unicode
const aGennoKakuGothicHW
[] = { 0x6E90, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'h','w', 0};
190 sal_Unicode
const aGennoMincho
[] = { 0x6E90, 0x30CE, 0x660E, 0x671D, 0};
191 sal_Unicode
const aGennoMinchoJP
[] = { 0x6E90, 0x30CE, 0x660E, 0x671D, 'j', 'p', 0};
192 sal_Unicode
const aIPAmjMincho
[] = { 'i', 'p', 'a', 'm', 'j', 0x660E, 0x671D, 0};
193 sal_Unicode
const aIPAexGothic
[] = { 'i', 'p', 'a', 'e', 'x', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0};
194 sal_Unicode
const aIPAexMincho
[] = { 'i', 'p', 'a', 'e', 'x', 0x660E, 0x671D, 0};
196 OUString
StripScriptFromName(const OUString
& _aName
)
198 // I worry that someone will have a font which *does* have
199 // e.g. "Greek" legitimately at the end of its name :-(
200 const char*const suffixes
[] = { " baltic",
211 OUString aName
= _aName
;
212 // These can be crazily piled up, e.g. Times New Roman CYR Greek
213 bool bFinished
= false;
217 for (const char* suffix
: suffixes
)
219 size_t nLen
= strlen(suffix
);
220 if (aName
.endsWithIgnoreAsciiCaseAsciiL(suffix
, nLen
))
223 aName
= aName
.copy(0, aName
.getLength() - nLen
);
230 //return true if the character is stripped from the string
231 static bool toOnlyLowerAsciiOrStrip(sal_Unicode c
, OUStringBuffer
&rName
, sal_Int32 nIndex
, sal_Int32
& rLen
)
233 // not lowercase Ascii
234 if (c
< 'a' || c
> 'z')
236 // To Lowercase-Ascii
237 if ( (c
>= 'A') && (c
<= 'Z') )
242 else if( ((c
< '0') || (c
> '9')) && (c
!= ';') && (c
!= '(') && (c
!= ')') ) // not 0-9, semicolon, or brackets
244 // Remove white spaces and special characters
245 rName
.remove(nIndex
, 1);
253 OUString
GetEnglishSearchFontName(std::u16string_view rInName
)
255 OUStringBuffer
rName(rInName
);
256 bool bNeedTranslation
= false;
257 sal_Int32 nLen
= rName
.getLength();
259 // Remove trailing whitespaces
261 while ( i
&& (rName
[ i
-1 ] < 32) )
266 nLen
= rName
.getLength();
268 // remove all whitespaces and converts to lower case ASCII
269 // TODO: better transliteration to ASCII e.g. all digits
273 sal_Unicode c
= rName
[ i
];
276 // Translate to Lowercase-ASCII
277 // FullWidth-ASCII to half ASCII
278 if ( (c
>= 0xFF00) && (c
<= 0xFF5E) )
282 if (toOnlyLowerAsciiOrStrip(c
, rName
, i
, nLen
))
287 // Only Fontnames with None-Ascii-Characters must be translated
288 bNeedTranslation
= true;
291 else if (toOnlyLowerAsciiOrStrip(c
, rName
, i
, nLen
))
296 OUString rNameStr
= rName
.makeStringAndClear();
297 // translate normalized localized name to its normalized English ASCII name
298 if( bNeedTranslation
)
300 typedef std::unordered_map
<OUString
, OUString
> FontNameDictionary
;
301 static FontNameDictionary
const aDictionary
= {
303 {aBatangChe
, "batangche"},
304 {aGungsuh
, "gungshu"},
305 {aGungsuhChe
, "gungshuche"},
307 {aGulimChe
, "gulimche"},
309 {aDotumChe
, "dotumche"},
311 {aNSimSun
, "nsimsun"},
314 {azycjkSun
, "zycjksun"},
315 {azycjkHei
, "zycjkhei"},
316 {azycjkKai
, "zycjkkai"},
319 {aFZSongYI
, "fzsong"},
320 {aFZShuSong
, "fzshusong"},
321 {aFZFangSong
, "fzfangsong"},
328 {aCFangSong1
, "cfangsong"},
329 {aCFangSong2
, "cfangsong"},
330 {aMingLiU
, "mingliu"},
331 {aPMingLiU
, "pmingliu"},
335 {aMSGothic
, "msgothic"},
336 {aMSPGothic
, "mspgothic"},
337 {aMSMincho
, "msmincho"},
338 {aMSPMincho
, "mspmincho"},
339 {aMSJhengHei
, "microsoftjhenghei"},
340 {aMSYaHei
, "microsoftyahei"},
342 {aHGMinchoL
, "hgminchol"},
343 {aHGGothicB
, "hggothicb"},
344 {aHGPMinchoL
, "hgpminchol"},
345 {aHGPGothicB
, "hgpgothicb"},
346 {aHGMinchoLSun
, "hgmincholsun"},
347 {aHGGothicBSun
, "hggothicbsun"},
348 {aHGPMinchoLSun
, "hgpmincholsun"},
349 {aHGPGothicBSun
, "hgpgothicbsun"},
350 {aHGHeiseiMin1
, "hgheiseimin"},
351 {aHGHeiseiMin2
, "hgheiseimin"},
352 {aIPAMincho
, "ipamincho"},
353 {aIPAPMincho
, "ipapmincho"},
354 {aIPAGothic
, "ipagothic"},
355 {aIPAPGothic
, "ipapgothic"},
356 {aIPAUIGothic
, "ipauigothic"},
357 {aTakaoMincho
, "takaomincho"},
358 {aTakaoPMincho
, "takaopmincho"},
359 {aTakaoGothic
, "takaogothic"},
360 {aTakaoPGothic
, "takaopgothic"},
361 {aSazanamiMincho
, "sazanamimincho"},
362 {aSazanamiGothic
, "sazanamigothic"},
363 {aKochiMincho
, "kochimincho"},
364 {aKochiGothic
, "kochigothic"},
365 {aSunDotum
, "sundotum"},
366 {aSunGulim
, "sungulim"},
367 {aSunBatang
, "sunbatang"},
368 {aBaekmukDotum
, "baekmukdotum"},
369 {aBaekmukGulim
, "baekmukgulim"},
370 {aBaekmukBatang
, "baekmukbatang"},
371 {aFzHeiTiCN
, "fzheiti"},
372 {aFzHeiTiTW
, "fzheiti"},
373 {aFzKaiTiCN
, "fzkaiti"},
374 {aFzKaiTiTW
, "fzkaitib"},
375 {aFzMingTi
, "fzmingtib"},
376 {aFzSongTi
, "fzsongti"},
377 {aHYMyeongJoExtra
, "hymyeongjoextra"},
378 {aHYSinMyeongJoMedium
, "hysinmyeongjomedium"},
379 {aHYGothicMedium
, "hygothicmedium"},
380 {aHYGraphicMedium
, "hygraphicmedium"},
381 {aHYGraphic
, "hygraphic"},
382 {aNewGulim
, "newgulim"},
383 {aSunGungseo
, "sungungseo"},
384 {aHYGungSoBold
, "hygungsobold"},
385 {aHYGungSo
, "hygungso"},
386 {aSunHeadLine
, "sunheadline"},
387 {aHYHeadLineMedium
, "hyheadlinemedium"},
388 {aHYHeadLine
, "hyheadline"},
390 {aHYGothicExtra
, "hygothicextra"},
391 {aSunMokPan
, "sunmokpan"},
392 {aSunYeopseo
, "sunyeopseo"},
393 {aSunBaekSong
, "sunbaeksong"},
394 {aHYPostLight
, "hypostlight"},
397 {aSunCrystal
, "suncrystal"},
398 {aSunSaemmul
, "sunsaemmul"},
399 {aHYShortSamulMedium
, "hyshortsamulmedium"},
400 {aHYShortSamul
, "hyshortsamul"},
401 {aHaansoftBatang
, "haansoftbatang"},
402 {aHaansoftDotum
, "haansoftdotum"},
403 {aHyhaeseo
, "hyhaeseo"},
405 {aMDGaesung
, "mdgaesung"},
407 {aMDAlong
, "mdalong"},
408 {aMDEasop
, "mdeasop"},
409 {aHGGothicE
, "hggothice"},
410 {aHGPGothicE
, "hgpgothice"},
411 {aHGSGothicE
, "hgsgothice"},
412 {aHGGothicM
, "hggothicm"},
413 {aHGPGothicM
, "hgpgothicm"},
414 {aHGSGothicM
, "hgsgothicm"},
415 {aHGGyoshotai
, "hggyoshotai"},
416 {aHGPGyoshotai
, "hgpgyoshotai"},
417 {aHGSGyoshotai
, "hgsgyoshotai"},
418 {aHGKyokashotai
, "hgkyokashotai"},
419 {aHGPKyokashotai
, "hgpkyokashotai"},
420 {aHGSKyokashotai
, "hgskyokashotai"},
421 {aHGMinchoB
, "hgminchob"},
422 {aHGPMinchoB
, "hgpminchob"},
423 {aHGSMinchoB
, "hgsminchob"},
424 {aHGMinchoE
, "hgminchoe"},
425 {aHGPMinchoE
, "hgpminchoe"},
426 {aHGSMinchoE
, "hgsminchoe"},
427 {aHGSoeiKakupoptai
, "hgsoeikakupoptai"},
428 {aHGPSoeiKakupoptai
, "hgpsoeikakupopta"},
429 {aHGSSoeiKakupoptai
, "hgssoeikakupopta"},
430 {aHGSoeiPresenceEB
, "hgsoeipresenceeb"},
431 {aHGPSoeiPresenceEB
, "hgpsoeipresenceeb"},
432 {aHGSSoeiPresenceEB
, "hgssoeipresenceeb"},
433 {aHGSoeiKakugothicUB
, "hgsoeikakugothicub"},
434 {aHGPSoeiKakugothicUB
, "hgpsoeikakugothicub"},
435 {aHGSSoeiKakugothicUB
, "hgssoeikakugothicub"},
436 {aHGSeikaishotaiPRO
, "hgseikaishotaipro"},
437 {aHGMaruGothicMPRO
, "hgmarugothicmpro"},
438 {aHiraginoMinchoPro
, "hiraginominchopro"},
439 {aHiraginoMinchoProN
, "hiraginominchopron"},
440 {aHiraginoKakuGothic
, "hiraginosans"},
441 {aHiraginoKakuGothicPro
, "hiraginokakugothicpro"},
442 {aHiraginoKakuGothicProN
, "hiraginokakugothicpron"},
443 {aHiraginoMaruGothicPro
, "hiraginomarugothicpro"},
444 {aHiraginoMaruGothicProN
, "hiraginomarugothicpron"},
445 {aHiraginoMaruGothicProN
, "hiraginomarugothicpron"},
446 {aYuGothic
, "yugothic"},
447 {aYuGothicTai
, "yugothictai"},
448 {aYuMincho
, "yumincho"},
449 {aYuMinchoTai
, "yuminchotai"},
450 {aGennoKakuGothic
, "sourcehansans"},
451 {aGennoKakuGothicJP
, "sourcehansansjp"},
452 {aGennoKakuGothicHW
, "sourcehansanshw"},
453 {aGennoMincho
, "sourcehanserif"},
454 {aGennoMinchoJP
, "sourcehanserifjp"},
455 {aIPAmjMincho
, "ipamjmincho"},
456 {aIPAexGothic
, "ipaexgothic"},
457 {aIPAexMincho
, "ipaexmimcho"}};
459 FontNameDictionary::const_iterator it
= aDictionary
.find( rNameStr
);
460 if( it
!= aDictionary
.end() )
461 rNameStr
= it
->second
;
467 std::u16string_view
GetNextFontToken( std::u16string_view rTokenStr
, sal_Int32
& rIndex
)
469 // check for valid start index
470 size_t nStringLen
= rTokenStr
.size();
471 if( o3tl::make_unsigned(rIndex
) >= nStringLen
)
477 // find the next token delimiter and return the token substring
478 const sal_Unicode
* pStr
= rTokenStr
.data() + rIndex
;
479 const sal_Unicode
* pEnd
= rTokenStr
.data() + nStringLen
;
480 for(; pStr
< pEnd
; ++pStr
)
481 if( (*pStr
== ';') || (*pStr
== ',') )
484 sal_Int32 nTokenStart
= rIndex
;
488 rIndex
= sal::static_int_cast
<sal_Int32
>(pStr
- rTokenStr
.data());
489 nTokenLen
= rIndex
- nTokenStart
;
490 ++rIndex
; // skip over token separator
494 // no token delimiter found => handle last token
497 // optimize if the token string consists of just one token
504 nTokenLen
= nStringLen
- nTokenStart
;
508 return rTokenStr
.substr( nTokenStart
, nTokenLen
);
511 static bool ImplIsFontToken( std::u16string_view rName
, std::u16string_view rToken
)
513 sal_Int32 nIndex
= 0;
516 std::u16string_view aTempName
= GetNextFontToken( rName
, nIndex
);
517 if ( rToken
== aTempName
)
520 while ( nIndex
!= -1 );
525 static void ImplAppendFontToken( OUString
& rName
, std::u16string_view rNewToken
)
527 if ( !rName
.isEmpty() )
534 void AddTokenFontName( OUString
& rName
, std::u16string_view rNewToken
)
536 if ( !ImplIsFontToken( rName
, rNewToken
) )
537 ImplAppendFontToken( rName
, rNewToken
);
540 OUString
GetSubsFontName( std::u16string_view rName
, SubsFontFlags nFlags
)
544 sal_Int32 nIndex
= 0;
545 OUString aOrgName
= GetEnglishSearchFontName(
546 GetNextFontToken( rName
, nIndex
) );
548 // #93662# do not try to replace StarSymbol with MS only font
549 if( nFlags
== (SubsFontFlags::MS
|SubsFontFlags::ONLYONE
)
550 && ( aOrgName
== "starsymbol"
551 || aOrgName
== "opensymbol" ) )
554 if (nFlags
& SubsFontFlags::MS
)
556 const utl::FontNameAttr
* pAttr
= utl::FontSubstConfiguration::get().getSubstInfo( aOrgName
);
558 for( const auto& rSubstitution
: pAttr
->MSSubstitutions
)
559 if( ! ImplIsFontToken( rName
, rSubstitution
) )
561 ImplAppendFontToken( aName
, rSubstitution
);
562 if( nFlags
& SubsFontFlags::ONLYONE
)
572 bool IsOpenSymbol(std::u16string_view rFontName
)
574 sal_Int32 nIndex
= 0;
575 std::u16string_view
sFamilyNm(GetNextFontToken(rFontName
, nIndex
));
576 return (o3tl::equalsIgnoreAsciiCase(sFamilyNm
, "starsymbol") ||
577 o3tl::equalsIgnoreAsciiCase(sFamilyNm
, "opensymbol"));
580 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */