tdf#81880 Search the Gallery
[LibreOffice.git] / vcl / workben / listfonts.cxx
blob49380c03bcbc31d1383be489e12ddff9bd0200ff
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
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/.
8 */
10 #include <osl/file.hxx>
11 #include <osl/process.h>
12 #include <rtl/textenc.h>
13 #include <sal/main.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>
31 #include <iostream>
32 #include <fstream>
33 #include <string>
34 #include <string_view>
36 namespace
38 OUString GetOctetTextEncodingName(sal_uInt16 encoding)
40 switch (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:
214 return "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:
289 return "UCS4";
291 case RTL_TEXTENCODING_UCS2:
292 return "UCS2 (aka Unicode)";
294 default:
296 OUString sUnknown = "Unknown (0x" + OUString::number(encoding, 16) + ")";
297 return sUnknown;
302 class ListFontsWin : public WorkWindow
304 public:
305 explicit ListFontsWin()
306 : WorkWindow(nullptr, WB_HIDE)
311 class ListFonts : public Application
313 public:
314 virtual int Main() override;
316 private:
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";
323 std::exit(0);
326 void Init() override;
327 void DeInit() override;
329 css::uno::Reference<css::lang::XMultiServiceFactory> xServiceManager;
330 bool mbStdOut = false;
331 bool mbShowFeatures = false;
332 OUString maFilename;
335 int ListFonts::Main()
339 VclPtrInstance<ListFontsWin> pWin;
340 OutputDevice* pOutDev = pWin->GetOutDev();
342 std::streambuf* coutbuf = nullptr;
343 std::fstream out;
345 if (!mbStdOut)
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";
395 if (mbShowFeatures)
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);
405 std::cout << "\t"
406 << (feature.m_eType == vcl::font::FeatureType::OpenType ? "OpenType"
407 : "Graphite")
408 << " Feature:\n\t\t"
409 << vcl::font::featureCodeAsString(feature.m_nCode) << "\n";
411 std::cout << "\t\tDescription: " << feature.m_aDefinition.getDescription()
412 << "\n";
413 std::cout << "\t\tType: "
414 << (feature.m_aDefinition.getType()
415 == vcl::font::FeatureParameterType::BOOL
416 ? "BOOL"
417 : "ENUM")
418 << "\n";
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()
432 << "\n";
434 std::cout.copyfmt(init);
439 std::cout << std::flush;
441 if (!mbStdOut)
443 std::cout.rdbuf(coutbuf);
444 out.close();
447 std::exit(0);
449 catch (const css::uno::Exception&)
451 TOOLS_WARN_EXCEPTION("vcl.app", "Fatal");
452 return 1;
454 catch (const std::exception& e)
456 SAL_WARN("vcl.app", "Fatal: " << e.what());
457 return 1;
459 return 0;
463 void ListFonts::Init()
465 const sal_uInt16 nCmdParams = GetCommandLineParamCount();
466 OUString aArg;
468 if (nCmdParams == 0)
470 showHelp();
471 std::exit(1);
473 else
475 aArg = GetCommandLineParam(0);
477 if (aArg == "--help" || aArg == "-h")
479 showHelp();
480 std::exit(0);
482 else if (nCmdParams == 2 && (aArg == "--verbose" || aArg == "-v"))
484 aArg = GetCommandLineParam(1);
485 mbShowFeatures = true;
487 if (aArg == "--")
488 mbStdOut = true;
490 else if (nCmdParams == 1)
492 if (aArg == "--")
493 mbStdOut = true;
495 else
497 std::cerr << "invalid arguments\n";
498 showHelp();
499 std::exit(1);
503 if (!mbStdOut)
505 maFilename = aArg;
507 osl::File aFile(maFilename);
509 if (!aFile.open(osl_File_OpenFlag_Create))
510 throw css::uno::RuntimeException("Can not create file: " + aArg);
512 aFile.close();
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);
530 xContext->dispose();
531 ::comphelper::setProcessServiceFactory(nullptr);
534 SAL_IMPLEMENT_MAIN()
536 ListFonts aApp;
537 InitVCL();
538 int ret = aApp.Main();
539 DeInitVCL();
541 return ret;
544 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */