summaryrefslogtreecommitdiffstats
path: root/unotools/source/misc/fontdefs.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--unotools/source/misc/fontdefs.cxx575
1 files changed, 575 insertions, 0 deletions
diff --git a/unotools/source/misc/fontdefs.cxx b/unotools/source/misc/fontdefs.cxx
new file mode 100644
index 000000000..568110315
--- /dev/null
+++ b/unotools/source/misc/fontdefs.cxx
@@ -0,0 +1,575 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/safeint.hxx>
+#include <unotools/fontdefs.hxx>
+#include <unotools/fontcfg.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <string_view>
+#include <unordered_map>
+
+sal_Unicode const aBatang[] = { 0xBC14, 0xD0D5, 0 };
+sal_Unicode const aBatangChe[] = { 0xBC14, 0xD0D5, 0xCCB4, 0 };
+sal_Unicode const aGungsuh[] = { 0xAD81, 0xC11C, 0 };
+sal_Unicode const aGungsuhChe[] = { 0xAD81, 0xC11C, 0xCCB4, 0 };
+sal_Unicode const aGulim[] = { 0xAD74, 0xB9BC, 0 };
+sal_Unicode const aGulimChe[] = { 0xAD74, 0xB9BC, 0xCCB4, 0 };
+sal_Unicode const aDotum[] = { 0xB3CB, 0xC6C0, 0 };
+sal_Unicode const aDotumChe[] = { 0xB3CB, 0xC6C0, 0xCCB4, 0 };
+sal_Unicode const aSimSun[] = { 0x5B8B, 0x4F53, 0 };
+sal_Unicode const aNSimSun[] = { 0x65B0, 0x5B8B, 0x4F53, 0 };
+sal_Unicode const aSimHei[] = { 0x9ED1, 0x4F53, 0 };
+sal_Unicode const aSimKai[] = { 0x6977, 0x4F53, 0 };
+sal_Unicode const azycjkSun[] = { 0x4E2D, 0x6613, 0x5B8B, 0x4F53, 0 };
+sal_Unicode const azycjkHei[] = { 0x4E2D, 0x6613, 0x9ED1, 0x4F53, 0 };
+sal_Unicode const azycjkKai[] = { 0x4E2D, 0x6613, 0x6977, 0x4F53, 0 };
+sal_Unicode const aFZHei[] = { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0 };
+sal_Unicode const aFZKai[] = { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0 };
+sal_Unicode const aFZSongYI[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4E00, 0 };
+sal_Unicode const aFZShuSong[] = { 0x65B9, 0x6B63, 0x4E66, 0x5B8B, 0 };
+sal_Unicode const aFZFangSong[] = { 0x65B9, 0x6B63, 0x4EFF, 0x5B8B, 0 };
+// Attention: this fonts includes the wrong encoding vector - so we double the names with correct and wrong encoding
+// First one is the GB-Encoding (we think the correct one), second is the big5 encoded name
+sal_Unicode const aMHei1[] = { 'm', 0x7B80, 0x9ED1, 0 };
+sal_Unicode const aMHei2[] = { 'm', 0x6F60, 0x7AAA, 0 };
+sal_Unicode const aMKai1[] = { 'm', 0x7B80, 0x6977, 0x566C, 0 };
+sal_Unicode const aMKai2[] = { 'm', 0x6F60, 0x7FF1, 0x628E, 0 };
+sal_Unicode const aMSong1[] = { 'm', 0x7B80, 0x5B8B, 0 };
+sal_Unicode const aMSong2[] = { 'm', 0x6F60, 0x51BC, 0 };
+sal_Unicode const aCFangSong1[] = { 'm', 0x7B80, 0x592B, 0x5B8B, 0 };
+sal_Unicode const aCFangSong2[] = { 'm', 0x6F60, 0x6E98, 0x51BC, 0 };
+sal_Unicode const aMingLiU[] = { 0x7D30, 0x660E, 0x9AD4, 0 };
+sal_Unicode const aPMingLiU[] = { 0x65B0, 0x7D30, 0x660E, 0x9AD4, 0 };
+sal_Unicode const aHei[] = { 0x6865, 0 };
+sal_Unicode const aKai[] = { 0x6B61, 0 };
+sal_Unicode const aMing[] = { 0x6D69, 0x6E67, 0 };
+sal_Unicode const aMSGothic[] = { 'm','s', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aMSPGothic[] = { 'm','s','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aMSMincho[] = { 'm', 's', 0x660E, 0x671D, 0 };
+sal_Unicode const aMSPMincho[] = { 'm','s','p', 0x660E, 0x671D, 0 };
+sal_Unicode const aMSYaHei[] = { 0x5FAE, 0x8F6F, 0x96C5, 0x9ED1, 0 };
+sal_Unicode const aMSJhengHei[] = { 0x5FAE, 0x8EDF, 0x6B63, 0x9ED1, 0x9AD4, 0 };
+sal_Unicode const aMeiryo[] = { 0x30e1, 0x30a4, 0x30ea, 0x30aa, 0 };
+sal_Unicode const aHGMinchoL[] = { 'h','g', 0x660E, 0x671D, 'l', 0 };
+sal_Unicode const aHGGothicB[] = { 'h','g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
+sal_Unicode const aHGPMinchoL[] = { 'h','g','p', 0x660E, 0x671D, 'l', 0 };
+sal_Unicode const aHGPGothicB[] = { 'h','g','p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 0 };
+sal_Unicode const aHGMinchoLSun[] = { 'h','g', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
+sal_Unicode const aHGPMinchoLSun[] = { 'h','g','p', 0x660E, 0x671D, 'l', 's', 'u', 'n', 0 };
+sal_Unicode const aHGGothicBSun[] = { 'h', 'g', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
+sal_Unicode const aHGPGothicBSun[] = { 'h', 'g', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'b', 's', 'u', 'n', 0 };
+sal_Unicode const aHGHeiseiMin1[] = { 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 0 };
+sal_Unicode const aHGHeiseiMin2[] = { 'h', 'g', 0x5E73, 0x6210, 0x660E, 0x671D, 0x4F53, 'w', '3', 'x', '1', '2', 0 };
+sal_Unicode const aIPAMincho[] = { 'i', 'p', 'a', 0x660E, 0x671D, 0 };
+sal_Unicode const aIPAPMincho[] = { 'i', 'p', 'a', 'p', 0x660E, 0x671D, 0 };
+sal_Unicode const aIPAGothic[] = { 'i', 'p', 'a', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aIPAPGothic[] = { 'i', 'p', 'a', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aIPAUIGothic[] = { 'i', 'p', 'a', 'u', 'i', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aTakaoMincho[] = { 't', 'a', 'k', 'a', 'o', 0x660E, 0x671D, 0 };
+sal_Unicode const aTakaoPMincho[] = { 't', 'a', 'k', 'a', 'o', 'p', 0x660E, 0x671D, 0 };
+sal_Unicode const aTakaoGothic[] = { 't', 'a', 'k', 'a', 'o', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aTakaoPGothic[] = { 't', 'a', 'k', 'a', 'o', 'p', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aSazanamiMincho[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x660E, 0x671D, 0 };
+sal_Unicode const aSazanamiGothic[] = { 0x3055, 0x3056, 0x306A, 0x307F, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aKochiMincho[] = { 0x6771, 0x98A8, 0x660E, 0x671D, 0 };
+sal_Unicode const aKochiGothic[] = { 0x6771, 0x98A8, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0 };
+sal_Unicode const aSunDotum[] = { 0xC36C, 0xB3CB, 0xC6C0, 0 };
+sal_Unicode const aSunGulim[] = { 0xC36C, 0xAD74, 0xB9BC, 0 };
+sal_Unicode const aSunBatang[] = { 0xC36C, 0xBC14, 0xD0D5, 0 };
+sal_Unicode const aBaekmukDotum[] = { 0xBC31, 0xBB35, 0xB3CB, 0xC6C0, 0 };
+sal_Unicode const aBaekmukGulim[] = { 0xBC31, 0xBB35, 0xAD74, 0xB9BC, 0 };
+sal_Unicode const aBaekmukBatang[] = { 0xBC31, 0xBB35, 0xBC14, 0xD0D5, 0 };
+sal_Unicode const aFzMingTi[] = { 0x65B9, 0x6B63, 0x660E, 0x9AD4, 0 };
+sal_Unicode const aFzHeiTiTW[]= { 0x65B9, 0x6B63, 0x9ED1, 0x9AD4, 0 };
+sal_Unicode const aFzKaiTiTW[]= { 0x65B9, 0x6B63, 0x6977, 0x9AD4, 0 };
+sal_Unicode const aFzHeiTiCN[]= { 0x65B9, 0x6B63, 0x9ED1, 0x4F53, 0 };
+sal_Unicode const aFzKaiTiCN[]= { 0x65B9, 0x6B63, 0x6977, 0x4F53, 0 };
+sal_Unicode const aFzSongTi[] = { 0x65B9, 0x6B63, 0x5B8B, 0x4F53, 0 };
+sal_Unicode const aHYMyeongJoExtra[] = { 'h', 'y', 0xACAC, 0xBA85, 0xC870, 0 };
+sal_Unicode const aHYSinMyeongJoMedium[] = { 'h', 'y', 0xC2E0, 0xBA85, 0xC870, 0 };
+sal_Unicode const aHYGothicMedium[] = { 'h', 'y', 0xC911, 0xACE0, 0xB515, 0 };
+sal_Unicode const aHYGraphicMedium[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 'm', 0 };
+sal_Unicode const aHYGraphic[] = { 'h', 'y', 0xADF8, 0xB798, 0xD53D, 0 };
+sal_Unicode const aNewGulim[] = { 0xC0C8, 0xAD74, 0xB9BC, 0 };
+sal_Unicode const aSunGungseo[] = { 0xC36C, 0xAD81, 0xC11C, 0 };
+sal_Unicode const aHYGungSoBold[] = { 'h','y', 0xAD81, 0xC11C, 'b', 0 };
+sal_Unicode const aHYGungSo[] = { 'h','y', 0xAD81, 0xC11C, 0 };
+sal_Unicode const aSunHeadLine[] = { 0xC36C, 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0 };
+sal_Unicode const aHYHeadLineMedium[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 'm', 0 };
+sal_Unicode const aHYHeadLine[] = { 'h', 'y', 0xD5E4, 0xB4DC, 0xB77C, 0xC778, 0 };
+sal_Unicode const aYetR[] = { 0xD734, 0xBA3C, 0xC61B, 0xCCB4, 0 };
+sal_Unicode const aHYGothicExtra[] = { 'h', 'y', 0xACAC, 0xACE0, 0xB515, 0 };
+sal_Unicode const aSunMokPan[] = { 0xC36C, 0xBAA9, 0xD310, 0 };
+sal_Unicode const aSunYeopseo[] = { 0xC36C, 0xC5FD, 0xC11C, 0 };
+sal_Unicode const aSunBaekSong[] = { 0xC36C, 0xBC31, 0xC1A1, 0 };
+sal_Unicode const aHYPostLight[] = { 'h', 'y', 0xC5FD, 0xC11C, 'l', 0 };
+sal_Unicode const aHYPost[] = { 'h', 'y', 0xC5FD, 0xC11C, 0 };
+sal_Unicode const aMagicR[] = { 0xD734, 0xBA3C, 0xB9E4, 0xC9C1, 0xCCB4, 0 };
+sal_Unicode const aSunCrystal[] = { 0xC36C, 0xD06C, 0xB9AC, 0xC2A4, 0xD0C8, 0 };
+sal_Unicode const aSunSaemmul[] = { 0xC36C, 0xC0D8, 0xBB3C, 0 };
+sal_Unicode const aHaansoftBatang[] = { 0xD55C, 0xCEF4, 0xBC14, 0xD0D5, 0 };
+sal_Unicode const aHaansoftDotum[] = { 0xD55C, 0xCEF4, 0xB3CB, 0xC6C0, 0 };
+sal_Unicode const aHyhaeseo[] = { 0xD55C, 0xC591, 0xD574, 0xC11C, 0 };
+sal_Unicode const aMDSol[] = { 'm', 'd', 0xC194, 0xCCB4, 0 };
+sal_Unicode const aMDGaesung[] = { 'm', 'd', 0xAC1C, 0xC131, 0xCCB4, 0 };
+sal_Unicode const aMDArt[] = { 'm', 'd', 0xC544, 0xD2B8, 0xCCB4, 0 };
+sal_Unicode const aMDAlong[] = { 'm', 'd', 0xC544, 0xB871, 0xCCB4, 0 };
+sal_Unicode const aMDEasop[] = { 'm', 'd', 0xC774, 0xC19D, 0xCCB4, 0 };
+sal_Unicode const aHYShortSamulMedium[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 'm', 0 };
+sal_Unicode const aHYShortSamul[] = { 'h', 'y', 0xC595, 0xC740, 0xC0D8, 0xBB3C, 0 };
+sal_Unicode const aHGGothicE[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
+sal_Unicode const aHGPGothicE[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
+sal_Unicode const aHGSGothicE[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'e', 0 };
+sal_Unicode const aHGGothicM[] = { 'h','g', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
+sal_Unicode const aHGPGothicM[] = { 'h','g','p', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
+sal_Unicode const aHGSGothicM[] = { 'h','g','s', 0xFF7A, 0xFF9E, 0xFF7C, 0xFF6F, 0xFF78, 'm', 0 };
+sal_Unicode const aHGGyoshotai[] = { 'h','g', 0x884C, 0x66F8, 0x4F53, 0 };
+sal_Unicode const aHGPGyoshotai[] = { 'h','g','p', 0x884C, 0x66F8, 0x4F53, 0 };
+sal_Unicode const aHGSGyoshotai[] = { 'h','g','s', 0x884C, 0x66F8, 0x4F53, 0 };
+sal_Unicode const aHGKyokashotai[] = { 'h','g', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
+sal_Unicode const aHGPKyokashotai[] = { 'h','g','p', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
+sal_Unicode const aHGSKyokashotai[] = { 'h','g','s', 0x6559, 0x79D1, 0x66F8, 0x4F53, 0 };
+sal_Unicode const aHGMinchoB[] = { 'h','g', 0x660E, 0x671D, 'b', 0 };
+sal_Unicode const aHGPMinchoB[] = { 'h','g','p', 0x660E, 0x671D, 'b', 0 };
+sal_Unicode const aHGSMinchoB[] = { 'h','g','s', 0x660E, 0x671D, 'b', 0 };
+sal_Unicode const aHGMinchoE[] = { 'h','g', 0x660E, 0x671D, 'e', 0 };
+sal_Unicode const aHGPMinchoE[] = { 'h','g','p', 0x660E, 0x671D, 'e', 0 };
+sal_Unicode const aHGSMinchoE[] = { 'h','g','s', 0x660E, 0x671D, 'e', 0 };
+sal_Unicode const aHGSoeiKakupoptai[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF8E,
+ 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
+sal_Unicode const aHGPSoeiKakupoptai[] = { 'h','g', 'p', 0x5275,0x82F1,0x89D2,0xFF8E,
+ 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
+sal_Unicode const aHGSSoeiKakupoptai[] = { 'h','g', 's', 0x5275,0x82F1,0x89D2,0xFF8E,
+ 0xFF9F,0xFF6F,0xFF8C,0xFF9F,0x4F53,0};
+sal_Unicode const aHGSoeiPresenceEB[] = { 'h','g', 0x5275,0x82F1,0xFF8C,0xFF9F,
+ 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
+sal_Unicode const aHGPSoeiPresenceEB[] = { 'h','g','p', 0x5275,0x82F1,0xFF8C,0xFF9F,
+ 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
+sal_Unicode const aHGSSoeiPresenceEB[] = { 'h','g','s', 0x5275,0x82F1,0xFF8C,0xFF9F,
+ 0xFF9A,0xFF7E,0xFF9E,0xFF9D,0xFF7D, 'e','b',0};
+sal_Unicode const aHGSoeiKakugothicUB[] = { 'h','g', 0x5275,0x82F1,0x89D2,0xFF7A,
+ 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
+sal_Unicode const aHGPSoeiKakugothicUB[] = { 'h','g','p', 0x5275,0x82F1,0x89D2,0xFF7A,
+ 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
+sal_Unicode const aHGSSoeiKakugothicUB[] = { 'h','g','s', 0x5275,0x82F1,0x89D2,0xFF7A,
+ 0xFF9E,0xFF7C,0xFF6F,0xFF78,'u','b',0};
+sal_Unicode const aHGSeikaishotaiPRO[] = { 'h','g', 0x6B63,0x6977,0x66F8,0x4F53, '-','p','r','o',0};
+sal_Unicode const aHGMaruGothicMPRO[] = { 'h','g', 0x4E38,0xFF7A,0xFF9E,0xFF7C,0xFF6F,0xFF78, '-','p','r','o',0};
+sal_Unicode const aHiraginoMinchoPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o',0};
+sal_Unicode const aHiraginoMinchoProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x660E, 0x671D, 'p','r','o','n',0};
+sal_Unicode const aHiraginoKakuGothic[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF,0};
+sal_Unicode const aHiraginoKakuGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o',0};
+sal_Unicode const aHiraginoKakuGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x89D2, 0x30B4, 'p','r','o','n',0};
+sal_Unicode const aHiraginoMaruGothicPro[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o',0};
+sal_Unicode const aHiraginoMaruGothicProN[] = { 0x30D2, 0x30E9, 0x30AE, 0x30CE, 0x4E38, 0x30B4, 'p','r','o','n',0};
+sal_Unicode const aYuGothic[] = { 0x6E38, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0};
+sal_Unicode const aYuGothicTai[] = { 0x6E38, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0x4F53, 0};
+sal_Unicode const aYuMincho[] = { 0x6E38, 0x660E, 0x671D, 0};
+sal_Unicode const aYuMinchoTai[] = { 0x6E38, 0x660E, 0x671D, 0x4F53, 0};
+sal_Unicode const aGennoKakuGothic[] = { 0x6E90, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0};
+sal_Unicode const aGennoKakuGothicJP[] = { 0x6E90, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'j', 'p', 0};
+sal_Unicode const aGennoKakuGothicHW[] = { 0x6E90, 0x30CE, 0x89D2, 0x30B4, 0x30B7, 0x30C3, 0x30AF, 'h','w', 0};
+sal_Unicode const aGennoMincho[] = { 0x6E90, 0x30CE, 0x660E, 0x671D, 0};
+sal_Unicode const aGennoMinchoJP[] = { 0x6E90, 0x30CE, 0x660E, 0x671D, 'j', 'p', 0};
+sal_Unicode const aIPAmjMincho[] = { 'i', 'p', 'a', 'm', 'j', 0x660E, 0x671D, 0};
+sal_Unicode const aIPAexGothic[] = { 'i', 'p', 'a', 'e', 'x', 0x30B4, 0x30B7, 0x30C3, 0x30AF, 0};
+sal_Unicode const aIPAexMincho[] = { 'i', 'p', 'a', 'e', 'x', 0x660E, 0x671D, 0};
+
+OUString StripScriptFromName(const OUString& _aName)
+{
+ // I worry that someone will have a font which *does* have
+ // e.g. "Greek" legitimately at the end of its name :-(
+ const char*const suffixes[] = { " baltic",
+ " ce",
+ " cyr",
+ " greek",
+ " tur",
+ " (arabic)",
+ " (hebrew)",
+ " (thai)",
+ " (vietnamese)"
+ };
+
+ OUString aName = _aName;
+ // These can be crazily piled up, e.g. Times New Roman CYR Greek
+ bool bFinished = false;
+ while (!bFinished)
+ {
+ bFinished = true;
+ for (const char* suffix : suffixes)
+ {
+ size_t nLen = strlen(suffix);
+ if (aName.endsWithIgnoreAsciiCaseAsciiL(suffix, nLen))
+ {
+ bFinished = false;
+ aName = aName.copy(0, aName.getLength() - nLen);
+ }
+ }
+ }
+ return aName;
+}
+
+OUString GetEnglishSearchFontName(std::u16string_view rInName)
+{
+ OUStringBuffer rName(rInName);
+ bool bNeedTranslation = false;
+ sal_Int32 nLen = rName.getLength();
+
+ // Remove trailing whitespaces
+ sal_Int32 i = nLen;
+ while ( i && (rName[ i-1 ] < 32) )
+ i--;
+ if ( i != nLen )
+ rName.truncate(i);
+
+ nLen = rName.getLength();
+
+ // remove all whitespaces and converts to lower case ASCII
+ // TODO: better transliteration to ASCII e.g. all digits
+ i = 0;
+ while ( i < nLen )
+ {
+ sal_Unicode c = rName[ i ];
+ if ( c > 127 )
+ {
+ // Translate to Lowercase-ASCII
+ // FullWidth-ASCII to half ASCII
+ if ( (c >= 0xFF00) && (c <= 0xFF5E) )
+ {
+ c -= 0xFF00-0x0020;
+ // Upper to Lower
+ if ( (c >= 'A') && (c <= 'Z') )
+ c += 'a' - 'A';
+
+ rName[ i ] = c;
+
+ }
+ else
+ {
+ // Only Fontnames with None-Ascii-Characters must be translated
+ bNeedTranslation = true;
+ }
+ }
+ // not lowercase Ascii
+ else if ( (c < 'a') || (c > 'z') )
+ {
+ // To Lowercase-Ascii
+ if ( (c >= 'A') && (c <= 'Z') )
+ {
+ c += 'a' - 'A';
+ rName[ i ] = c;
+ }
+ else if( ((c < '0') || (c > '9')) && (c != ';') && (c != '(') && (c != ')') ) // not 0-9, semicolon, or brackets
+ {
+ // Remove white spaces and special characters
+ rName.remove(i,1);
+ nLen--;
+ continue;
+ }
+ }
+
+ i++;
+ }
+ OUString rNameStr = rName.makeStringAndClear();
+ // translate normalized localized name to its normalized English ASCII name
+ if( bNeedTranslation )
+ {
+ typedef std::unordered_map<OUString, OUString> FontNameDictionary;
+ static FontNameDictionary const aDictionary = {
+ {aBatang, "batang"},
+ {aBatangChe, "batangche"},
+ {aGungsuh, "gungshu"},
+ {aGungsuhChe, "gungshuche"},
+ {aGulim, "gulim"},
+ {aGulimChe, "gulimche"},
+ {aDotum, "dotum"},
+ {aDotumChe, "dotumche"},
+ {aSimSun, "simsun"},
+ {aNSimSun, "nsimsun"},
+ {aSimHei, "simhei"},
+ {aSimKai, "simkai"},
+ {azycjkSun, "zycjksun"},
+ {azycjkHei, "zycjkhei"},
+ {azycjkKai, "zycjkkai"},
+ {aFZHei, "fzhei"},
+ {aFZKai, "fzkai"},
+ {aFZSongYI, "fzsong"},
+ {aFZShuSong, "fzshusong"},
+ {aFZFangSong, "fzfangsong"},
+ {aMHei1, "mhei"},
+ {aMHei2, "mhei"},
+ {aMKai1, "mkai"},
+ {aMKai2, "mkai"},
+ {aMSong1, "msong"},
+ {aMSong2, "msong"},
+ {aCFangSong1, "cfangsong"},
+ {aCFangSong2, "cfangsong"},
+ {aMingLiU, "mingliu"},
+ {aPMingLiU, "pmingliu"},
+ {aHei, "hei"},
+ {aKai, "kai"},
+ {aMing, "ming"},
+ {aMSGothic, "msgothic"},
+ {aMSPGothic, "mspgothic"},
+ {aMSMincho, "msmincho"},
+ {aMSPMincho, "mspmincho"},
+ {aMSJhengHei, "microsoftjhenghei"},
+ {aMSYaHei, "microsoftyahei"},
+ {aMeiryo, "meiryo"},
+ {aHGMinchoL, "hgminchol"},
+ {aHGGothicB, "hggothicb"},
+ {aHGPMinchoL, "hgpminchol"},
+ {aHGPGothicB, "hgpgothicb"},
+ {aHGMinchoLSun, "hgmincholsun"},
+ {aHGGothicBSun, "hggothicbsun"},
+ {aHGPMinchoLSun, "hgpmincholsun"},
+ {aHGPGothicBSun, "hgpgothicbsun"},
+ {aHGHeiseiMin1, "hgheiseimin"},
+ {aHGHeiseiMin2, "hgheiseimin"},
+ {aIPAMincho, "ipamincho"},
+ {aIPAPMincho, "ipapmincho"},
+ {aIPAGothic, "ipagothic"},
+ {aIPAPGothic, "ipapgothic"},
+ {aIPAUIGothic, "ipauigothic"},
+ {aTakaoMincho, "takaomincho"},
+ {aTakaoPMincho, "takaopmincho"},
+ {aTakaoGothic, "takaogothic"},
+ {aTakaoPGothic, "takaopgothic"},
+ {aSazanamiMincho, "sazanamimincho"},
+ {aSazanamiGothic, "sazanamigothic"},
+ {aKochiMincho, "kochimincho"},
+ {aKochiGothic, "kochigothic"},
+ {aSunDotum, "sundotum"},
+ {aSunGulim, "sungulim"},
+ {aSunBatang, "sunbatang"},
+ {aBaekmukDotum, "baekmukdotum"},
+ {aBaekmukGulim, "baekmukgulim"},
+ {aBaekmukBatang, "baekmukbatang"},
+ {aFzHeiTiCN, "fzheiti"},
+ {aFzHeiTiTW, "fzheiti"},
+ {aFzKaiTiCN, "fzkaiti"},
+ {aFzKaiTiTW, "fzkaitib"},
+ {aFzMingTi, "fzmingtib"},
+ {aFzSongTi, "fzsongti"},
+ {aHYMyeongJoExtra, "hymyeongjoextra"},
+ {aHYSinMyeongJoMedium, "hysinmyeongjomedium"},
+ {aHYGothicMedium, "hygothicmedium"},
+ {aHYGraphicMedium, "hygraphicmedium"},
+ {aHYGraphic, "hygraphic"},
+ {aNewGulim, "newgulim"},
+ {aSunGungseo, "sungungseo"},
+ {aHYGungSoBold, "hygungsobold"},
+ {aHYGungSo, "hygungso"},
+ {aSunHeadLine, "sunheadline"},
+ {aHYHeadLineMedium, "hyheadlinemedium"},
+ {aHYHeadLine, "hyheadline"},
+ {aYetR, "yetr"},
+ {aHYGothicExtra, "hygothicextra"},
+ {aSunMokPan, "sunmokpan"},
+ {aSunYeopseo, "sunyeopseo"},
+ {aSunBaekSong, "sunbaeksong"},
+ {aHYPostLight, "hypostlight"},
+ {aHYPost, "hypost"},
+ {aMagicR, "magicr"},
+ {aSunCrystal, "suncrystal"},
+ {aSunSaemmul, "sunsaemmul"},
+ {aHYShortSamulMedium, "hyshortsamulmedium"},
+ {aHYShortSamul, "hyshortsamul"},
+ {aHaansoftBatang, "haansoftbatang"},
+ {aHaansoftDotum, "haansoftdotum"},
+ {aHyhaeseo, "hyhaeseo"},
+ {aMDSol, "mdsol"},
+ {aMDGaesung, "mdgaesung"},
+ {aMDArt, "mdart"},
+ {aMDAlong, "mdalong"},
+ {aMDEasop, "mdeasop"},
+ {aHGGothicE, "hggothice"},
+ {aHGPGothicE, "hgpgothice"},
+ {aHGSGothicE, "hgsgothice"},
+ {aHGGothicM, "hggothicm"},
+ {aHGPGothicM, "hgpgothicm"},
+ {aHGSGothicM, "hgsgothicm"},
+ {aHGGyoshotai, "hggyoshotai"},
+ {aHGPGyoshotai, "hgpgyoshotai"},
+ {aHGSGyoshotai, "hgsgyoshotai"},
+ {aHGKyokashotai, "hgkyokashotai"},
+ {aHGPKyokashotai, "hgpkyokashotai"},
+ {aHGSKyokashotai, "hgskyokashotai"},
+ {aHGMinchoB, "hgminchob"},
+ {aHGPMinchoB, "hgpminchob"},
+ {aHGSMinchoB, "hgsminchob"},
+ {aHGMinchoE, "hgminchoe"},
+ {aHGPMinchoE, "hgpminchoe"},
+ {aHGSMinchoE, "hgsminchoe"},
+ {aHGSoeiKakupoptai, "hgsoeikakupoptai"},
+ {aHGPSoeiKakupoptai, "hgpsoeikakupopta"},
+ {aHGSSoeiKakupoptai, "hgssoeikakupopta"},
+ {aHGSoeiPresenceEB, "hgsoeipresenceeb"},
+ {aHGPSoeiPresenceEB, "hgpsoeipresenceeb"},
+ {aHGSSoeiPresenceEB, "hgssoeipresenceeb"},
+ {aHGSoeiKakugothicUB, "hgsoeikakugothicub"},
+ {aHGPSoeiKakugothicUB, "hgpsoeikakugothicub"},
+ {aHGSSoeiKakugothicUB, "hgssoeikakugothicub"},
+ {aHGSeikaishotaiPRO, "hgseikaishotaipro"},
+ {aHGMaruGothicMPRO, "hgmarugothicmpro"},
+ {aHiraginoMinchoPro, "hiraginominchopro"},
+ {aHiraginoMinchoProN, "hiraginominchopron"},
+ {aHiraginoKakuGothic, "hiraginosans"},
+ {aHiraginoKakuGothicPro, "hiraginokakugothicpro"},
+ {aHiraginoKakuGothicProN, "hiraginokakugothicpron"},
+ {aHiraginoMaruGothicPro, "hiraginomarugothicpro"},
+ {aHiraginoMaruGothicProN, "hiraginomarugothicpron"},
+ {aHiraginoMaruGothicProN, "hiraginomarugothicpron"},
+ {aYuGothic, "yugothic"},
+ {aYuGothicTai, "yugothictai"},
+ {aYuMincho, "yumincho"},
+ {aYuMinchoTai, "yuminchotai"},
+ {aGennoKakuGothic, "sourcehansans"},
+ {aGennoKakuGothicJP, "sourcehansansjp"},
+ {aGennoKakuGothicHW, "sourcehansanshw"},
+ {aGennoMincho, "sourcehanserif"},
+ {aGennoMinchoJP, "sourcehanserifjp"},
+ {aIPAmjMincho, "ipamjmincho"},
+ {aIPAexGothic, "ipaexgothic"},
+ {aIPAexMincho, "ipaexmimcho"}};
+
+ FontNameDictionary::const_iterator it = aDictionary.find( rNameStr );
+ if( it != aDictionary.end() )
+ rNameStr = it->second;
+ }
+
+ return rNameStr;
+}
+
+std::u16string_view GetNextFontToken( std::u16string_view rTokenStr, sal_Int32& rIndex )
+{
+ // check for valid start index
+ size_t nStringLen = rTokenStr.size();
+ if( o3tl::make_unsigned(rIndex) >= nStringLen )
+ {
+ rIndex = -1;
+ return {};
+ }
+
+ // find the next token delimiter and return the token substring
+ const sal_Unicode* pStr = rTokenStr.data() + rIndex;
+ const sal_Unicode* pEnd = rTokenStr.data() + nStringLen;
+ for(; pStr < pEnd; ++pStr )
+ if( (*pStr == ';') || (*pStr == ',') )
+ break;
+
+ sal_Int32 nTokenStart = rIndex;
+ sal_Int32 nTokenLen;
+ if( pStr < pEnd )
+ {
+ rIndex = sal::static_int_cast<sal_Int32>(pStr - rTokenStr.data());
+ nTokenLen = rIndex - nTokenStart;
+ ++rIndex; // skip over token separator
+ }
+ else
+ {
+ // no token delimiter found => handle last token
+ rIndex = -1;
+
+ // optimize if the token string consists of just one token
+ if( !nTokenStart )
+ {
+ return rTokenStr;
+ }
+ else
+ {
+ nTokenLen = nStringLen - nTokenStart;
+ }
+ }
+
+ return rTokenStr.substr( nTokenStart, nTokenLen );
+}
+
+static bool ImplIsFontToken( std::u16string_view rName, std::u16string_view rToken )
+{
+ OUString aTempName;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aTempName = GetNextFontToken( rName, nIndex );
+ if ( rToken == aTempName )
+ return true;
+ }
+ while ( nIndex != -1 );
+
+ return false;
+}
+
+static void ImplAppendFontToken( OUString& rName, std::u16string_view rNewToken )
+{
+ if ( !rName.isEmpty() )
+ {
+ rName += ";";
+ }
+ rName += rNewToken;
+}
+
+void AddTokenFontName( OUString& rName, std::u16string_view rNewToken )
+{
+ if ( !ImplIsFontToken( rName, rNewToken ) )
+ ImplAppendFontToken( rName, rNewToken );
+}
+
+OUString GetSubsFontName( std::u16string_view rName, SubsFontFlags nFlags )
+{
+ OUString aName;
+
+ sal_Int32 nIndex = 0;
+ OUString aOrgName = GetEnglishSearchFontName(
+ GetNextFontToken( rName, nIndex ) );
+
+ // #93662# do not try to replace StarSymbol with MS only font
+ if( nFlags == (SubsFontFlags::MS|SubsFontFlags::ONLYONE)
+ && ( aOrgName == "starsymbol"
+ || aOrgName == "opensymbol" ) )
+ return aName;
+
+ if (nFlags & SubsFontFlags::MS)
+ {
+ const utl::FontNameAttr* pAttr = utl::FontSubstConfiguration::get().getSubstInfo( aOrgName );
+ if (pAttr)
+ for( const auto& rSubstitution : pAttr->MSSubstitutions )
+ if( ! ImplIsFontToken( rName, rSubstitution ) )
+ {
+ ImplAppendFontToken( aName, rSubstitution );
+ if( nFlags & SubsFontFlags::ONLYONE )
+ {
+ break;
+ }
+ }
+ }
+
+ return aName;
+}
+
+bool IsStarSymbol(std::u16string_view rFontName)
+{
+ sal_Int32 nIndex = 0;
+ OUString sFamilyNm(GetNextFontToken(rFontName, nIndex));
+ return (sFamilyNm.equalsIgnoreAsciiCase("starsymbol") ||
+ sFamilyNm.equalsIgnoreAsciiCase("opensymbol"));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */