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