1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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/.
10 #include <osl/file.hxx>
11 #include <osl/process.h>
12 #include <rtl/textenc.h>
14 #include <comphelper/processfactory.hxx>
15 #include <cppuhelper/bootstrap.hxx>
16 #include <comphelper/diagnose_ex.hxx>
17 #include <tools/degree.hxx>
18 #include <i18nlangtag/languagetag.hxx>
19 #include <i18nlangtag/mslangid.hxx>
21 #include <vcl/font/Feature.hxx>
22 #include <vcl/metric.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/vclmain.hxx>
25 #include <vcl/wrkwin.hxx>
27 #include <com/sun/star/lang/XComponent.hpp>
28 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
29 #include <com/sun/star/uno/XComponentContext.hpp>
34 #include <string_view>
38 OUString
GetOctetTextEncodingName(sal_uInt16 encoding
)
42 case RTL_TEXTENCODING_APPLE_ARABIC
:
43 return "Arabic (Apple Macintosh)";
45 case RTL_TEXTENCODING_IBM_864
:
46 return "Arabic (DOS/OS2-864)";
48 case RTL_TEXTENCODING_ISO_8859_6
:
49 return "Arabic (ISO-8859-6)";
51 case RTL_TEXTENCODING_MS_1256
:
52 return "Arabic (Windows-1256)";
54 case RTL_TEXTENCODING_IBM_775
:
55 return "Baltic (DOS/OS2-775)";
57 case RTL_TEXTENCODING_ISO_8859_4
:
58 return "Baltic (ISO-8859-4)";
60 case RTL_TEXTENCODING_MS_1257
:
61 return "Baltic (Windows-1257)";
63 case RTL_TEXTENCODING_APPLE_CENTEURO
:
64 return "Central European (Apple Macintosh)";
66 case RTL_TEXTENCODING_APPLE_CROATIAN
:
67 return "Central European (Apple Macintosh/Croatian)";
69 case RTL_TEXTENCODING_APPLE_ROMANIAN
:
70 return "Central European (Apple Macintosh/Romanian)";
72 case RTL_TEXTENCODING_IBM_852
:
73 return "Central European (DOS/OS2-852)";
75 case RTL_TEXTENCODING_ISO_8859_2
:
76 return "Central European (ISO-8859-2)";
78 case RTL_TEXTENCODING_ISO_8859_10
:
79 return "Central European (ISO-8859-10)";
81 case RTL_TEXTENCODING_ISO_8859_13
:
82 return "Central European (ISO-8859-13)";
84 case RTL_TEXTENCODING_MS_1250
:
85 return "Central European (Windows-1250/WinLatin 2)";
87 case RTL_TEXTENCODING_APPLE_CHINSIMP
:
88 return "Chinese Simplified (Apple Macintosh)";
90 case RTL_TEXTENCODING_EUC_CN
:
91 return "Chinese Simplified (EUC-CN)";
93 case RTL_TEXTENCODING_GB_2312
:
94 return "Chinese Simplified (GB-2312)";
96 case RTL_TEXTENCODING_GBK
:
97 return "Chinese Simplified (GBK/GB-2312-80)";
99 case RTL_TEXTENCODING_ISO_2022_CN
:
100 return "Chinese Simplified (ISO-2022-CN)";
102 case RTL_TEXTENCODING_MS_936
:
103 return "Chinese Simplified (Windows-936)";
105 case RTL_TEXTENCODING_GB_18030
:
106 return "Chinese Simplified (GB-18030)";
108 case RTL_TEXTENCODING_APPLE_CHINTRAD
:
109 return "Chinese Traditional (Apple Macintosh)";
111 case RTL_TEXTENCODING_BIG5
:
112 return "Chinese Traditional (BIG5)";
114 case RTL_TEXTENCODING_EUC_TW
:
115 return "Chinese Traditional (EUC-TW)";
117 case RTL_TEXTENCODING_GBT_12345
:
118 return "Chinese Traditional (GBT-12345)";
120 case RTL_TEXTENCODING_MS_950
:
121 return "Chinese Traditional (Windows-950)";
123 case RTL_TEXTENCODING_BIG5_HKSCS
:
124 return "Chinese Traditional (BIG5-HKSCS)";
126 case RTL_TEXTENCODING_APPLE_CYRILLIC
:
127 return "Cyrillic (Apple Macintosh)";
129 case RTL_TEXTENCODING_APPLE_UKRAINIAN
:
130 return "Cyrillic (Apple Macintosh/Ukrainian)";
132 case RTL_TEXTENCODING_IBM_855
:
133 return "Cyrillic (DOS/OS2-855)";
135 case RTL_TEXTENCODING_IBM_866
:
136 return "Cyrillic (DOS/OS2-866/Russian)";
138 case RTL_TEXTENCODING_ISO_8859_5
:
139 return "Cyrillic (ISO-8859-5)";
141 case RTL_TEXTENCODING_KOI8_R
:
142 return "Cyrillic (KOI8-R)";
144 case RTL_TEXTENCODING_KOI8_U
:
145 return "Cyrillic (KOI8-U)";
147 case RTL_TEXTENCODING_MS_1251
:
148 return "Cyrillic (Windows-1251)";
150 case RTL_TEXTENCODING_APPLE_GREEK
:
151 return "Greek (Apple Macintosh)";
153 case RTL_TEXTENCODING_IBM_737
:
154 return "Greek (DOS/OS2-737)";
156 case RTL_TEXTENCODING_IBM_869
:
157 return "Greek (DOS/OS2-869/Modern)";
159 case RTL_TEXTENCODING_ISO_8859_7
:
160 return "Greek (ISO-8859-7)";
162 case RTL_TEXTENCODING_MS_1253
:
163 return "Greek (Windows-1253)";
165 case RTL_TEXTENCODING_APPLE_HEBREW
:
166 return "Hebrew (Apple Macintosh)";
168 case RTL_TEXTENCODING_IBM_862
:
169 return "Hebrew (DOS/OS2-862)";
171 case RTL_TEXTENCODING_ISO_8859_8
:
172 return "Hebrew (ISO-8859-8)";
174 case RTL_TEXTENCODING_MS_1255
:
175 return "Hebrew (Windows-1255)";
177 case RTL_TEXTENCODING_APPLE_KOREAN
:
178 return "Korean (Apple Macintosh)";
180 case RTL_TEXTENCODING_EUC_KR
:
181 return "Korean (EUC-KR)";
183 case RTL_TEXTENCODING_ISO_2022_KR
:
184 return "Korean (ISO-2022-KR)";
186 case RTL_TEXTENCODING_MS_949
:
187 return "Korean (Windows-Wansung-949)";
189 case RTL_TEXTENCODING_MS_1361
:
190 return "Korean (Windows-Johab-1361)";
192 case RTL_TEXTENCODING_ISO_8859_3
:
193 return "Latin 3 (ISO-8859-3)";
195 case RTL_TEXTENCODING_ISCII_DEVANAGARI
:
196 return "Indian (ISCII Devanagari)";
198 case RTL_TEXTENCODING_APPLE_JAPANESE
:
199 return "Japanese (Apple Macintosh)";
201 case RTL_TEXTENCODING_EUC_JP
:
202 return "Japanese (EUC-JP)";
204 case RTL_TEXTENCODING_ISO_2022_JP
:
205 return "Japanese (ISO-2022-JP)";
207 case RTL_TEXTENCODING_SHIFT_JIS
:
208 return "Japanese (Shift-JIS)";
210 case RTL_TEXTENCODING_MS_932
:
211 return "Japanese (Windows-932)";
213 case RTL_TEXTENCODING_SYMBOL
:
216 case RTL_TEXTENCODING_APPLE_THAI
:
217 return "Thai (Apple Macintosh)";
219 case RTL_TEXTENCODING_MS_874
:
220 return "Thai (Dos/Windows-874)";
222 case RTL_TEXTENCODING_TIS_620
:
223 return "Thai (TIS 620)";
225 case RTL_TEXTENCODING_APPLE_TURKISH
:
226 return "Turkish (Apple Macintosh)";
228 case RTL_TEXTENCODING_IBM_857
:
229 return "Turkish (DOS/OS2-857)";
231 case RTL_TEXTENCODING_ISO_8859_9
:
232 return "Turkish (ISO-8859-9)";
234 case RTL_TEXTENCODING_MS_1254
:
235 return "Turkish (Windows-1254)";
237 case RTL_TEXTENCODING_UTF7
:
238 return "Unicode (UTF-7)";
240 case RTL_TEXTENCODING_UTF8
:
241 return "Unicode (UTF-8)";
243 case RTL_TEXTENCODING_JAVA_UTF8
:
244 return "Unicode (Java's modified UTF-8)";
246 case RTL_TEXTENCODING_MS_1258
:
247 return "Vietnamese (Windows-1258)";
249 case RTL_TEXTENCODING_APPLE_ROMAN
:
250 return "Western (Apple Macintosh)";
252 case RTL_TEXTENCODING_APPLE_ICELAND
:
253 return "Western (Apple Macintosh/Icelandic)";
255 case RTL_TEXTENCODING_ASCII_US
:
256 return "Western (ASCII/US)";
258 case RTL_TEXTENCODING_IBM_437
:
259 return "Western (DOS/OS2-437/US)";
261 case RTL_TEXTENCODING_IBM_850
:
262 return "Western (DOS/OS2-850/International)";
264 case RTL_TEXTENCODING_IBM_860
:
265 return "Western (DOS/OS2-860/Portuguese)";
267 case RTL_TEXTENCODING_IBM_861
:
268 return "Western (DOS/OS2-861/Icelandic)";
270 case RTL_TEXTENCODING_IBM_863
:
271 return "Western (DOS/OS2-863/Canadian-French)";
273 case RTL_TEXTENCODING_IBM_865
:
274 return "Western (DOS/OS2-865/Nordic)";
276 case RTL_TEXTENCODING_ISO_8859_1
:
277 return "Western (ISO-8859-1)";
279 case RTL_TEXTENCODING_ISO_8859_14
:
280 return "Western (ISO-8859-14)";
282 case RTL_TEXTENCODING_ISO_8859_15
:
283 return "Western (ISO-8859-15/EURO)";
285 case RTL_TEXTENCODING_MS_1252
:
286 return "Western (Window-1252/WinLatin 1)";
288 case RTL_TEXTENCODING_UCS4
:
291 case RTL_TEXTENCODING_UCS2
:
292 return "UCS2 (aka Unicode)";
296 OUString sUnknown
= "Unknown (0x" + OUString::number(encoding
, 16) + ")";
302 class ListFontsWin
: public WorkWindow
305 explicit ListFontsWin()
306 : WorkWindow(nullptr, WB_HIDE
)
311 class ListFonts
: public Application
314 virtual int Main() override
;
317 static void showHelp()
319 std::cerr
<< "Usage: listfonts --help | FILE | -v FILE\n";
320 std::cerr
<< "Lists the current fonts installed on the system.\n";
321 std::cerr
<< "To show the font features of each font, use -v before FILE.\n";
322 std::cerr
<< "If outputting to stdout, use -- for FILE.\n";
326 void Init() override
;
327 void DeInit() override
;
329 css::uno::Reference
<css::lang::XMultiServiceFactory
> xServiceManager
;
330 bool mbStdOut
= false;
331 bool mbShowFeatures
= false;
335 int ListFonts::Main()
339 VclPtrInstance
<ListFontsWin
> pWin
;
340 OutputDevice
* pOutDev
= pWin
->GetOutDev();
342 std::streambuf
* coutbuf
= nullptr;
347 std::u16string_view filenamev
= maFilename
;
348 std::string
filename(filenamev
.begin(), filenamev
.end());
350 out
.open(filename
, std::ios::out
| std::ios::trunc
);
352 coutbuf
= std::cout
.rdbuf();
353 std::cout
.rdbuf(out
.rdbuf());
356 std::vector
<int> aIndices
;
357 for (int i
= 0; i
< pOutDev
->GetFontFaceCollectionCount(); i
++)
358 aIndices
.push_back(i
);
360 std::sort(aIndices
.begin(), aIndices
.end(), [&](int a
, int b
) {
361 return pOutDev
->GetFontMetricFromCollection(a
).GetHashValueIgnoreColor()
362 > pOutDev
->GetFontMetricFromCollection(b
).GetHashValueIgnoreColor();
365 for (const auto& i
: aIndices
)
367 // note: to get the correct font metrics, you actually have to get the font metric from the
368 // system, and *then* you must set it as the current font of OutputDevice... then you need
369 // to get the font metric (which corrects a variety of things like the orientation, line
370 // height, slant, etc. - including converting from logical coords to device coords)
372 FontMetric aSystemFont
= pOutDev
->GetFontMetricFromCollection(i
);
373 pOutDev
->SetFont(aSystemFont
);
375 FontMetric aFont
= pOutDev
->GetFontMetric();
377 std::cout
<< aFont
.GetFamilyName() << "\n\tFamily type: " << aFont
.GetFamilyType()
378 << "\n\tStyle name: " << aFont
.GetStyleName()
379 << "\n\tWeight: " << aFont
.GetWeight() << "\n\tItalic: " << aFont
.GetItalic()
380 << "\n\tPitch: " << aFont
.GetPitch()
381 << "\n\tWidth type: " << aFont
.GetWidthType()
382 << "\n\tAlignment: " << aFont
.GetAlignment()
383 << "\n\tCharset: " << GetOctetTextEncodingName(aFont
.GetCharSet())
384 << "\n\tAscent: " << aFont
.GetAscent()
385 << "\n\tDescent: " << aFont
.GetDescent()
386 << "\n\tInternal leading: " << aFont
.GetInternalLeading()
387 << "\n\tExternal leading: " << aFont
.GetExternalLeading()
388 << "\n\tLine height: " << aFont
.GetLineHeight()
389 << "\n\tSlant: " << aFont
.GetSlant()
390 << "\n\tBullet offset: " << aFont
.GetBulletOffset()
391 << "\n\tFullstop centered? " << (aFont
.IsFullstopCentered() ? "yes" : "no")
392 << "\n\tOrientation: " << toDegrees(aFont
.GetOrientation())
393 << " degrees\n\tQuality: " << aFont
.GetQuality() << "\n";
397 std::vector
<vcl::font::Feature
> features
;
398 pOutDev
->GetFontFeatures(features
);
400 for (auto const& feature
: features
)
402 std::ios
init(nullptr);
403 init
.copyfmt(std::cout
);
406 << (feature
.m_eType
== vcl::font::FeatureType::OpenType
? "OpenType"
409 << vcl::font::featureCodeAsString(feature
.m_nCode
) << "\n";
411 std::cout
<< "\t\tDescription: " << feature
.m_aDefinition
.getDescription()
413 std::cout
<< "\t\tType: "
414 << (feature
.m_aDefinition
.getType()
415 == vcl::font::FeatureParameterType::BOOL
420 std::cout
.copyfmt(init
);
422 if (feature
.m_aDefinition
.getType() == vcl::font::FeatureParameterType::ENUM
)
424 for (auto const& param
: feature
.m_aDefinition
.getEnumParameters())
426 std::cout
<< "\t\t\t" << param
.getDescription() << ": "
427 << param
.getCode() << "\n";
431 std::cout
<< "\t\tDefault: 0x" << std::hex
<< feature
.m_aDefinition
.getDefault()
434 std::cout
.copyfmt(init
);
439 std::cout
<< std::flush
;
443 std::cout
.rdbuf(coutbuf
);
449 catch (const css::uno::Exception
&)
451 TOOLS_WARN_EXCEPTION("vcl.app", "Fatal");
454 catch (const std::exception
& e
)
456 SAL_WARN("vcl.app", "Fatal: " << e
.what());
463 void ListFonts::Init()
465 const sal_uInt16 nCmdParams
= GetCommandLineParamCount();
475 aArg
= GetCommandLineParam(0);
477 if (aArg
== "--help" || aArg
== "-h")
482 else if (nCmdParams
== 2 && (aArg
== "--verbose" || aArg
== "-v"))
484 aArg
= GetCommandLineParam(1);
485 mbShowFeatures
= true;
490 else if (nCmdParams
== 1)
497 std::cerr
<< "invalid arguments\n";
507 osl::File
aFile(maFilename
);
509 if (!aFile
.open(osl_File_OpenFlag_Create
))
510 throw css::uno::RuntimeException("Can not create file: " + aArg
);
515 auto xContext
= cppu::defaultBootstrap_InitialComponentContext();
516 xServiceManager
.set(xContext
->getServiceManager(), css::uno::UNO_QUERY
);
518 if (!xServiceManager
.is())
519 Application::Abort("Bootstrap failure - no service manager");
521 comphelper::setProcessServiceFactory(xServiceManager
);
523 LanguageTag::setConfiguredSystemLanguage(MsLangId::getSystemLanguage());
526 void ListFonts::DeInit()
528 auto xContext
= css::uno::Reference
<css::lang::XComponent
>(
529 comphelper::getProcessComponentContext(), css::uno::UNO_QUERY_THROW
);
531 ::comphelper::setProcessServiceFactory(nullptr);
538 int ret
= aApp
.Main();
544 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */