diff options
-rw-r--r-- | Repository.mk | 5 | ||||
-rw-r--r-- | include/tools/fontenum.hxx | 374 | ||||
-rw-r--r-- | vcl/Executable_listfonts.mk | 36 | ||||
-rw-r--r-- | vcl/Module_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/workben/listfonts.cxx | 541 |
5 files changed, 955 insertions, 2 deletions
diff --git a/Repository.mk b/Repository.mk index 6e3834a24259..c6210625338a 100644 --- a/Repository.mk +++ b/Repository.mk @@ -74,8 +74,9 @@ $(eval $(call gb_Helper_register_executables,NONE, \ $(if $(filter LINUX MACOSX SOLARIS WNT %BSD,$(OS)),icontest) \ vcldemo \ tiledrendering \ - mtfdemo \ - visualbackendtest \ + mtfdemo \ + visualbackendtest \ + listfonts \ $(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), gtktiledviewer) \ )) diff --git a/include/tools/fontenum.hxx b/include/tools/fontenum.hxx index eeb35be1985c..c09ef0838336 100644 --- a/include/tools/fontenum.hxx +++ b/include/tools/fontenum.hxx @@ -20,28 +20,223 @@ #define INCLUDED_TOOLS_FONTENUM_HXX #include <sal/types.h> +#include <sal/log.hxx> #include <o3tl/typed_flags_set.hxx> +#include <ostream> + enum FontFamily { FAMILY_DONTKNOW, FAMILY_DECORATIVE, FAMILY_MODERN, FAMILY_ROMAN, FAMILY_SCRIPT, FAMILY_SWISS, FAMILY_SYSTEM, FontFamily_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontFamily const& family) +{ + switch (family) + { + case FAMILY_DONTKNOW: + return stream << "unknown"; + + case FAMILY_DECORATIVE: + return stream << "decorative"; + + case FAMILY_MODERN: + return stream << "modern"; + + case FAMILY_ROMAN: + return stream << "roman"; + + case FAMILY_SCRIPT: + return stream << "script"; + + case FAMILY_SWISS: + return stream << "swiss"; + + case FAMILY_SYSTEM: + return stream << "system"; + + default: + SAL_WARN("vcl.gdi", "FontFamily out of bounds"); + assert(false && "FontFamily out of bounds"); + return stream << "unknown"; + } +} + enum FontPitch { PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, FontPitch_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontPitch const& pitch) +{ + switch (pitch) + { + case PITCH_DONTKNOW: + return stream << "unknown"; + + case PITCH_FIXED: + return stream << "fixed"; + + case PITCH_VARIABLE: + return stream << "variable"; + + default: + SAL_WARN("vcl.gdi", "FontPitch out of bounds"); + assert(false && "FontPitch out of bounds"); + return stream << "unknown"; + } +} + enum TextAlign { ALIGN_TOP, ALIGN_BASELINE, ALIGN_BOTTOM, TextAlign_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, TextAlign const& align) +{ + switch (align) + { + case ALIGN_TOP: + return stream << "top"; + + case ALIGN_BASELINE: + return stream << "baseline"; + + case ALIGN_BOTTOM: + return stream << "bottom"; + + default: + SAL_WARN("vcl.gdi", "TextAlign out of bounds"); + assert(false && "TextAlign out of bounds"); + return stream << "unknown"; + } +} + enum FontWeight { WEIGHT_DONTKNOW, WEIGHT_THIN, WEIGHT_ULTRALIGHT, WEIGHT_LIGHT, WEIGHT_SEMILIGHT, WEIGHT_NORMAL, WEIGHT_MEDIUM, WEIGHT_SEMIBOLD, WEIGHT_BOLD, WEIGHT_ULTRABOLD, WEIGHT_BLACK, FontWeight_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontWeight const& weight) +{ + switch (weight) + { + case WEIGHT_DONTKNOW: + return stream << "unknown"; + + case WEIGHT_THIN: + return stream << "thin"; + + case WEIGHT_ULTRALIGHT: + return stream << "ultralight"; + + case WEIGHT_LIGHT: + return stream << "light"; + + case WEIGHT_SEMILIGHT: + return stream << "semilight"; + + case WEIGHT_NORMAL: + return stream << "normal"; + + case WEIGHT_MEDIUM: + return stream << "medium"; + + case WEIGHT_SEMIBOLD: + return stream << "semibold"; + + case WEIGHT_BOLD: + return stream << "bold"; + + case WEIGHT_ULTRABOLD: + return stream << "ultrabold"; + + case WEIGHT_BLACK: + return stream << "black"; + + default: + SAL_WARN("vcl.gdi", "FontWeight out of bounds"); + assert(false && "FontWeight out of bounds"); + return stream << "unknown"; + } +} + enum FontWidth { WIDTH_DONTKNOW, WIDTH_ULTRA_CONDENSED, WIDTH_EXTRA_CONDENSED, WIDTH_CONDENSED, WIDTH_SEMI_CONDENSED, WIDTH_NORMAL, WIDTH_SEMI_EXPANDED, WIDTH_EXPANDED, WIDTH_EXTRA_EXPANDED, WIDTH_ULTRA_EXPANDED, FontWidth_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontWidth const& width) +{ + switch (width) + { + case WIDTH_DONTKNOW: + return stream << "unknown"; + + case WIDTH_ULTRA_CONDENSED: + return stream << "ultra condensed"; + + case WIDTH_EXTRA_CONDENSED: + return stream << "extra ultra condensed"; + + case WIDTH_CONDENSED: + return stream << "condensed"; + + case WIDTH_SEMI_CONDENSED: + return stream << "semi condensed"; + + case WIDTH_NORMAL: + return stream << "normal"; + + case WIDTH_SEMI_EXPANDED: + return stream << "semi expanded"; + + case WIDTH_EXPANDED: + return stream << "expanded"; + + case WIDTH_EXTRA_EXPANDED: + return stream << "extra expanded"; + + case WIDTH_ULTRA_EXPANDED: + return stream << "ultra expanded"; + + default: + SAL_WARN("vcl.gdi", "FontWidth out of bounds"); + assert(false && "FontWidth out of bounds"); + return stream << "unknown"; + } +} + enum FontItalic { ITALIC_NONE, ITALIC_OBLIQUE, ITALIC_NORMAL, ITALIC_DONTKNOW, FontItalic_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontItalic const& italic) +{ + switch (italic) + { + case ITALIC_DONTKNOW: + return stream << "unknown"; + + case ITALIC_OBLIQUE: + return stream << "oblique"; + + case ITALIC_NORMAL: + return stream << "normal"; + + case ITALIC_NONE: + return stream << "none"; + + default: + SAL_WARN("vcl.gdi", "FontItalic out of bounds"); + assert(false && "FontItalic out of bounds"); + return stream << "unknown"; + } +} + enum FontLineStyle { LINESTYLE_NONE, LINESTYLE_SINGLE, LINESTYLE_DOUBLE, LINESTYLE_DOTTED, LINESTYLE_DONTKNOW, LINESTYLE_DASH, LINESTYLE_LONGDASH, @@ -54,11 +249,116 @@ enum FontLineStyle { LINESTYLE_NONE, LINESTYLE_SINGLE, LINESTYLE_DOUBLE, LINESTYLE_BOLDWAVE, FontLineStyle_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontLineStyle const& linestyle) +{ + switch (linestyle) + { + case LINESTYLE_NONE: + return stream << "none"; + + case LINESTYLE_SINGLE: + return stream << "single"; + + case LINESTYLE_DOUBLE: + return stream << "double"; + + case LINESTYLE_DOTTED: + return stream << "dotted"; + + case LINESTYLE_DONTKNOW: + return stream << "unknown"; + + case LINESTYLE_DASH: + return stream << "dash"; + + case LINESTYLE_LONGDASH: + return stream << "long dash"; + break; + + case LINESTYLE_DASHDOT: + return stream << "dash dot"; + + case LINESTYLE_DASHDOTDOT: + return stream << "dash dot dot"; + + case LINESTYLE_SMALLWAVE: + return stream << "small wave"; + + case LINESTYLE_WAVE: + return stream << "wave"; + + case LINESTYLE_DOUBLEWAVE: + return stream << "double wave"; + + case LINESTYLE_BOLD: + return stream << "bold"; + + case LINESTYLE_BOLDDOTTED: + return stream << "bold dotted"; + + case LINESTYLE_BOLDDASH: + return stream << "bold dash"; + + case LINESTYLE_BOLDLONGDASH: + return stream << "bold long dash"; + + case LINESTYLE_BOLDDASHDOT: + return stream << "bold dash dot"; + + case LINESTYLE_BOLDDASHDOTDOT: + return stream << "bold dash dot dot"; + + case LINESTYLE_BOLDWAVE: + return stream << "bold wave"; + + default: + SAL_WARN("vcl.gdi", "FontLineStyle out of bounds"); + assert(false && "FontLineStyle out of bounds"); + return stream << "unknown"; + } +} + enum FontStrikeout { STRIKEOUT_NONE, STRIKEOUT_SINGLE, STRIKEOUT_DOUBLE, STRIKEOUT_DONTKNOW, STRIKEOUT_BOLD, STRIKEOUT_SLASH, STRIKEOUT_X, FontStrikeout_FORCE_EQUAL_SIZE=SAL_MAX_ENUM }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontStrikeout const& strikeout) +{ + switch (strikeout) + { + case STRIKEOUT_NONE: + return stream << "none"; + + case STRIKEOUT_SINGLE: + return stream << "single"; + + case STRIKEOUT_DOUBLE: + return stream << "double"; + + case STRIKEOUT_DONTKNOW: + return stream << "unknown"; + + case STRIKEOUT_BOLD: + return stream << "bold"; + + case STRIKEOUT_SLASH: + return stream << "slash"; + + case STRIKEOUT_X: + return stream << "x"; + + default: + SAL_WARN("vcl.gdi", "FontStrikeout out of bounds"); + assert(false && "FontStrikeout out of bounds"); + return stream << "unknown"; + } +} + enum class FontEmphasisMark { NONE = 0x0000, // capitalisation to avoid conflict with X11 macro Dot = 0x0001, @@ -74,11 +374,85 @@ namespace o3tl template<> struct typed_flags<FontEmphasisMark> : is_typed_flags<FontEmphasisMark, 0x300f> {}; } +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontEmphasisMark const& emphasismark) +{ + switch (emphasismark) + { + case FontEmphasisMark::NONE: + return stream << "none"; + + case FontEmphasisMark::Dot: + return stream << "Dot"; + + case FontEmphasisMark::Circle: + return stream << "Circle"; + + case FontEmphasisMark::Disc: + return stream << "Disc"; + + case FontEmphasisMark::Accent: + return stream << "Accent"; + + case FontEmphasisMark::Style: + return stream << "Style"; + + case FontEmphasisMark::PosAbove: + return stream << "PosAbove"; + + case FontEmphasisMark::PosBelow: + return stream << "PosBelow"; + + default: + SAL_WARN("vcl.gdi", "FontEmphasisMark out of bounds"); + assert(false && "FontEmphasisMark out of bounds"); + return stream << "unknown"; + } +} enum FontEmbeddedBitmap { EMBEDDEDBITMAP_DONTKNOW, EMBEDDEDBITMAP_FALSE, EMBEDDEDBITMAP_TRUE }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontEmbeddedBitmap const& embeddedbitmap) +{ + switch (embeddedbitmap) + { + case EMBEDDEDBITMAP_DONTKNOW: + return stream << "unknown"; + + case EMBEDDEDBITMAP_FALSE: + return stream << "false"; + + case EMBEDDEDBITMAP_TRUE: + return stream << "true"; + } + + return stream << "unknown"; +} + enum FontAntiAlias { ANTIALIAS_DONTKNOW, ANTIALIAS_FALSE, ANTIALIAS_TRUE }; +template< typename charT, typename traits > +inline std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, FontAntiAlias const& antialias) +{ + switch (antialias) + { + case ANTIALIAS_DONTKNOW: + return stream << "unknown"; + + case ANTIALIAS_FALSE: + return stream << "false"; + + case ANTIALIAS_TRUE: + return stream << "true"; + } + + return stream << "unknown"; +} + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/Executable_listfonts.mk b/vcl/Executable_listfonts.mk new file mode 100644 index 000000000000..94ed8bd11e27 --- /dev/null +++ b/vcl/Executable_listfonts.mk @@ -0,0 +1,36 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# 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/. +# + +$(eval $(call gb_Executable_Executable,listfonts)) + +$(eval $(call gb_Executable_use_api,listfonts,\ + offapi \ + udkapi \ +)) + +$(eval $(call gb_Executable_set_include,listfonts,\ + $$(INCLUDE) \ + -I$(SRCDIR)/vcl/inc \ +)) + +$(eval $(call gb_Executable_use_libraries,listfonts,\ + tl \ + sal \ + vcl \ + cppu \ + cppuhelper \ + comphelper \ + i18nlangtag \ +)) + +$(eval $(call gb_Executable_add_exception_objects,listfonts,\ + vcl/workben/listfonts \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk index 1c3c5902c7d4..bdd7bd91f5a4 100644 --- a/vcl/Module_vcl.mk +++ b/vcl/Module_vcl.mk @@ -49,6 +49,7 @@ $(eval $(call gb_Module_add_targets,vcl,\ Executable_minvcl \ Executable_fftester \ Executable_svptest \ + Executable_listfonts \ Executable_svpclient) \ )) diff --git a/vcl/workben/listfonts.cxx b/vcl/workben/listfonts.cxx new file mode 100644 index 000000000000..60b3209683e2 --- /dev/null +++ b/vcl/workben/listfonts.cxx @@ -0,0 +1,541 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include <osl/file.hxx> +#include <osl/process.h> +#include <rtl/textenc.h> +#include <sal/main.h> +#include <comphelper/processfactory.hxx> +#include <cppuhelper/bootstrap.hxx> +#include <tools/diagnose_ex.h> +#include <tools/degree.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <i18nlangtag/mslangid.hxx> + +#include <vcl/font/Feature.hxx> +#include <vcl/metric.hxx> +#include <vcl/svapp.hxx> +#include <vcl/vclmain.hxx> +#include <vcl/wrkwin.hxx> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> + +#include <iostream> +#include <fstream> +#include <string> +#include <string_view> + +namespace +{ +OUString GetOctetTextEncodingName(sal_uInt16 encoding) +{ + switch (encoding) + { + case RTL_TEXTENCODING_APPLE_ARABIC: + return "Arabic (Apple Macintosh)"; + + case RTL_TEXTENCODING_IBM_864: + return "Arabic (DOS/OS2-864)"; + + case RTL_TEXTENCODING_ISO_8859_6: + return "Arabic (ISO-8859-6)"; + + case RTL_TEXTENCODING_MS_1256: + return "Arabic (Windows-1256)"; + + case RTL_TEXTENCODING_IBM_775: + return "Baltic (DOS/OS2-775)"; + + case RTL_TEXTENCODING_ISO_8859_4: + return "Baltic (ISO-8859-4)"; + + case RTL_TEXTENCODING_MS_1257: + return "Baltic (Windows-1257)"; + + case RTL_TEXTENCODING_APPLE_CENTEURO: + return "Central European (Apple Macintosh)"; + + case RTL_TEXTENCODING_APPLE_CROATIAN: + return "Central European (Apple Macintosh/Croatian)"; + + case RTL_TEXTENCODING_APPLE_ROMANIAN: + return "Central European (Apple Macintosh/Romanian)"; + + case RTL_TEXTENCODING_IBM_852: + return "Central European (DOS/OS2-852)"; + + case RTL_TEXTENCODING_ISO_8859_2: + return "Central European (ISO-8859-2)"; + + case RTL_TEXTENCODING_ISO_8859_10: + return "Central European (ISO-8859-10)"; + + case RTL_TEXTENCODING_ISO_8859_13: + return "Central European (ISO-8859-13)"; + + case RTL_TEXTENCODING_MS_1250: + return "Central European (Windows-1250/WinLatin 2)"; + + case RTL_TEXTENCODING_APPLE_CHINSIMP: + return "Chinese Simplified (Apple Macintosh)"; + + case RTL_TEXTENCODING_EUC_CN: + return "Chinese Simplified (EUC-CN)"; + + case RTL_TEXTENCODING_GB_2312: + return "Chinese Simplified (GB-2312)"; + + case RTL_TEXTENCODING_GBK: + return "Chinese Simplified (GBK/GB-2312-80)"; + + case RTL_TEXTENCODING_ISO_2022_CN: + return "Chinese Simplified (ISO-2022-CN)"; + + case RTL_TEXTENCODING_MS_936: + return "Chinese Simplified (Windows-936)"; + + case RTL_TEXTENCODING_GB_18030: + return "Chinese Simplified (GB-18030)"; + + case RTL_TEXTENCODING_APPLE_CHINTRAD: + return "Chinese Traditional (Apple Macintosh)"; + + case RTL_TEXTENCODING_BIG5: + return "Chinese Traditional (BIG5)"; + + case RTL_TEXTENCODING_EUC_TW: + return "Chinese Traditional (EUC-TW)"; + + case RTL_TEXTENCODING_GBT_12345: + return "Chinese Traditional (GBT-12345)"; + + case RTL_TEXTENCODING_MS_950: + return "Chinese Traditional (Windows-950)"; + + case RTL_TEXTENCODING_BIG5_HKSCS: + return "Chinese Traditional (BIG5-HKSCS)"; + + case RTL_TEXTENCODING_APPLE_CYRILLIC: + return "Cyrillic (Apple Macintosh)"; + + case RTL_TEXTENCODING_APPLE_UKRAINIAN: + return "Cyrillic (Apple Macintosh/Ukrainian)"; + + case RTL_TEXTENCODING_IBM_855: + return "Cyrillic (DOS/OS2-855)"; + + case RTL_TEXTENCODING_IBM_866: + return "Cyrillic (DOS/OS2-866/Russian)"; + + case RTL_TEXTENCODING_ISO_8859_5: + return "Cyrillic (ISO-8859-5)"; + + case RTL_TEXTENCODING_KOI8_R: + return "Cyrillic (KOI8-R)"; + + case RTL_TEXTENCODING_KOI8_U: + return "Cyrillic (KOI8-U)"; + + case RTL_TEXTENCODING_MS_1251: + return "Cyrillic (Windows-1251)"; + + case RTL_TEXTENCODING_APPLE_GREEK: + return "Greek (Apple Macintosh)"; + + case RTL_TEXTENCODING_IBM_737: + return "Greek (DOS/OS2-737)"; + + case RTL_TEXTENCODING_IBM_869: + return "Greek (DOS/OS2-869/Modern)"; + + case RTL_TEXTENCODING_ISO_8859_7: + return "Greek (ISO-8859-7)"; + + case RTL_TEXTENCODING_MS_1253: + return "Greek (Windows-1253)"; + + case RTL_TEXTENCODING_APPLE_HEBREW: + return "Hebrew (Apple Macintosh)"; + + case RTL_TEXTENCODING_IBM_862: + return "Hebrew (DOS/OS2-862)"; + + case RTL_TEXTENCODING_ISO_8859_8: + return "Hebrew (ISO-8859-8)"; + + case RTL_TEXTENCODING_MS_1255: + return "Hebrew (Windows-1255)"; + + case RTL_TEXTENCODING_APPLE_KOREAN: + return "Korean (Apple Macintosh)"; + + case RTL_TEXTENCODING_EUC_KR: + return "Korean (EUC-KR)"; + + case RTL_TEXTENCODING_ISO_2022_KR: + return "Korean (ISO-2022-KR)"; + + case RTL_TEXTENCODING_MS_949: + return "Korean (Windows-Wansung-949)"; + + case RTL_TEXTENCODING_MS_1361: + return "Korean (Windows-Johab-1361)"; + + case RTL_TEXTENCODING_ISO_8859_3: + return "Latin 3 (ISO-8859-3)"; + + case RTL_TEXTENCODING_ISCII_DEVANAGARI: + return "Indian (ISCII Devanagari)"; + + case RTL_TEXTENCODING_APPLE_JAPANESE: + return "Japanese (Apple Macintosh)"; + + case RTL_TEXTENCODING_EUC_JP: + return "Japanese (EUC-JP)"; + + case RTL_TEXTENCODING_ISO_2022_JP: + return "Japanese (ISO-2022-JP)"; + + case RTL_TEXTENCODING_SHIFT_JIS: + return "Japanese (Shift-JIS)"; + + case RTL_TEXTENCODING_MS_932: + return "Japanese (Windows-932)"; + + case RTL_TEXTENCODING_SYMBOL: + return "Symbol"; + + case RTL_TEXTENCODING_APPLE_THAI: + return "Thai (Apple Macintosh)"; + + case RTL_TEXTENCODING_MS_874: + return "Thai (Dos/Windows-874)"; + + case RTL_TEXTENCODING_TIS_620: + return "Thai (TIS 620)"; + + case RTL_TEXTENCODING_APPLE_TURKISH: + return "Turkish (Apple Macintosh)"; + + case RTL_TEXTENCODING_IBM_857: + return "Turkish (DOS/OS2-857)"; + + case RTL_TEXTENCODING_ISO_8859_9: + return "Turkish (ISO-8859-9)"; + + case RTL_TEXTENCODING_MS_1254: + return "Turkish (Windows-1254)"; + + case RTL_TEXTENCODING_UTF7: + return "Unicode (UTF-7)"; + + case RTL_TEXTENCODING_UTF8: + return "Unicode (UTF-8)"; + + case RTL_TEXTENCODING_JAVA_UTF8: + return "Unicode (Java's modified UTF-8)"; + + case RTL_TEXTENCODING_MS_1258: + return "Vietnamese (Windows-1258)"; + + case RTL_TEXTENCODING_APPLE_ROMAN: + return "Western (Apple Macintosh)"; + + case RTL_TEXTENCODING_APPLE_ICELAND: + return "Western (Apple Macintosh/Icelandic)"; + + case RTL_TEXTENCODING_ASCII_US: + return "Western (ASCII/US)"; + + case RTL_TEXTENCODING_IBM_437: + return "Western (DOS/OS2-437/US)"; + + case RTL_TEXTENCODING_IBM_850: + return "Western (DOS/OS2-850/International)"; + + case RTL_TEXTENCODING_IBM_860: + return "Western (DOS/OS2-860/Portuguese)"; + + case RTL_TEXTENCODING_IBM_861: + return "Western (DOS/OS2-861/Icelandic)"; + + case RTL_TEXTENCODING_IBM_863: + return "Western (DOS/OS2-863/Canadian-French)"; + + case RTL_TEXTENCODING_IBM_865: + return "Western (DOS/OS2-865/Nordic)"; + + case RTL_TEXTENCODING_ISO_8859_1: + return "Western (ISO-8859-1)"; + + case RTL_TEXTENCODING_ISO_8859_14: + return "Western (ISO-8859-14)"; + + case RTL_TEXTENCODING_ISO_8859_15: + return "Western (ISO-8859-15/EURO)"; + + case RTL_TEXTENCODING_MS_1252: + return "Western (Window-1252/WinLatin 1)"; + + case RTL_TEXTENCODING_UCS4: + return "UCS4"; + + case RTL_TEXTENCODING_UCS2: + return "UCS2 (aka Unicode)"; + + default: + { + OUString sUnknown = "Unknown (0x" + OUString::number(encoding, 16) + ")"; + return sUnknown; + } + } +} + +class ListFontsWin : public WorkWindow +{ +public: + explicit ListFontsWin() + : WorkWindow(nullptr, WB_HIDE) + { + } +}; + +class ListFonts : public Application +{ +public: + virtual int Main() override; + +private: + static void showHelp() + { + std::cerr << "Usage: listfonts --help | FILE | -v FILE\n"; + std::cerr << "Lists the current fonts installed on the system.\n"; + std::cerr << "To show the font features of each font, use -v before FILE.\n"; + std::cerr << "If outputting to stdout, use -- for FILE.\n"; + std::exit(0); + } + + void Init() override; + void DeInit() override; + + css::uno::Reference<css::lang::XMultiServiceFactory> xServiceManager; + bool mbStdOut = false; + bool mbShowFeatures = false; + OUString maFilename; +}; + +int ListFonts::Main() +{ + try + { + VclPtrInstance<ListFontsWin> pWin; + OutputDevice* pOutDev = pWin->GetOutDev(); + + std::streambuf* coutbuf = nullptr; + std::fstream out; + + if (!mbStdOut) + { + std::u16string_view filenamev = maFilename; + std::string filename(filenamev.begin(), filenamev.end()); + + out.open(filename, std::ios::out | std::ios::trunc); + + coutbuf = std::cout.rdbuf(); + std::cout.rdbuf(out.rdbuf()); + } + + for (int i = 0; i < pOutDev->GetFontFaceCollectionCount(); i++) + { + // note: to get the correct font metrics, you actually have to get the font metric from the + // system, and *then* you must set it as the current font of OutputDevice... then you need + // to get the font metric (which corrects a variety of things like the orientation, line + // height, slant, etc. - including converting from logical coords to device coords) + + FontMetric aSystemFont = pOutDev->GetFontMetricFromCollection(i); + pOutDev->SetFont(aSystemFont); + + FontMetric aFont = pOutDev->GetFontMetric(); + + std::cout << aFont.GetFamilyName() << "\n\tFamily type: " << aFont.GetFamilyType() + << "\n\tStyle name: " << aFont.GetStyleName() + << "\n\tWeight: " << aFont.GetWeight() << "\n\tItalic: " << aFont.GetItalic() + << "\n\tPitch: " << aFont.GetPitch() + << "\n\tWidth type: " << aFont.GetWidthType() + << "\n\tAlignment: " << aFont.GetAlignment() + << "\n\tCharset: " << GetOctetTextEncodingName(aFont.GetCharSet()) + << "\n\tSymbol font? " << (aFont.IsSymbolFont() ? "yes" : "no") + << "\n\tAscent: " << aFont.GetAscent() + << "\n\tDescent: " << aFont.GetDescent() + << "\n\tInternal leading: " << aFont.GetInternalLeading() + << "\n\tExternal leading: " << aFont.GetExternalLeading() + << "\n\tLine height: " << aFont.GetLineHeight() + << "\n\tSlant: " << aFont.GetSlant() + << "\n\tBullet offset: " << aFont.GetBulletOffset() + << "\n\tFullstop centered? " << (aFont.IsFullstopCentered() ? "yes" : "no") + << "\n\tOrientation: " << toDegrees(aFont.GetOrientation()) + << " degrees\n\tQuality: " << aFont.GetQuality() << "\n"; + + if (mbShowFeatures) + { + std::vector<vcl::font::Feature> features; + pOutDev->GetFontFeatures(features); + + for (auto const& feature : features) + { + std::ios init(nullptr); + init.copyfmt(std::cout); + + std::cout << "\t" + << (feature.m_eType == vcl::font::FeatureType::OpenType ? "OpenType" + : "Graphite") + << " Feature:\n\t\tId = { feature code = " + << vcl::font::featureCodeAsString(feature.m_aID.m_aFeatureCode) + << ", script code = " + << vcl::font::featureCodeAsString(feature.m_aID.m_aScriptCode) + << ", language code = " + << vcl::font::featureCodeAsString(feature.m_aID.m_aLanguageCode) + << " }\n"; + + std::cout << "\t\tDescription: " << feature.m_aDefinition.getDescription() + << "\n"; + std::cout << "\t\tType: " + << (feature.m_aDefinition.getType() + == vcl::font::FeatureParameterType::BOOL + ? "BOOL" + : "ENUM") + << "\n"; + + std::cout.copyfmt(init); + + if (feature.m_aDefinition.getType() == vcl::font::FeatureParameterType::ENUM) + { + for (auto const& param : feature.m_aDefinition.getEnumParameters()) + { + std::cout << "\t\t\t" << param.getDescription() << ": " + << param.getCode() << "\n"; + } + } + + std::cout << "\t\tDefault: 0x" << std::hex << feature.m_aDefinition.getDefault() + << "\n"; + + std::cout.copyfmt(init); + } + } + } + + std::cout << std::flush; + + if (!mbStdOut) + { + std::cout.rdbuf(coutbuf); + out.close(); + } + + std::exit(0); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION("vcl.app", "Fatal"); + return 1; + } + catch (const std::exception& e) + { + SAL_WARN("vcl.app", "Fatal: " << e.what()); + return 1; + } + return 0; +} +} + +void ListFonts::Init() +{ + const sal_uInt16 nCmdParams = GetCommandLineParamCount(); + OUString aArg; + + if (nCmdParams == 0) + { + showHelp(); + std::exit(1); + } + else + { + aArg = GetCommandLineParam(0); + + if (aArg == "--help" || aArg == "-h") + { + showHelp(); + std::exit(0); + } + else if (nCmdParams == 2 && (aArg == "--verbose" || aArg == "-v")) + { + aArg = GetCommandLineParam(1); + mbShowFeatures = true; + + if (aArg == "--") + mbStdOut = true; + } + else if (nCmdParams == 1) + { + if (aArg == "--") + mbStdOut = true; + } + else + { + std::cerr << "invalid arguments\n"; + showHelp(); + std::exit(1); + } + } + + if (!mbStdOut) + { + maFilename = aArg; + + osl::File aFile(maFilename); + + if (!aFile.open(osl_File_OpenFlag_Create)) + throw css::uno::RuntimeException("Can not create file: " + aArg); + + aFile.close(); + } + + auto xContext = cppu::defaultBootstrap_InitialComponentContext(); + xServiceManager.set(xContext->getServiceManager(), css::uno::UNO_QUERY); + + if (!xServiceManager.is()) + Application::Abort("Bootstrap failure - no service manager"); + + comphelper::setProcessServiceFactory(xServiceManager); + + LanguageTag::setConfiguredSystemLanguage(MsLangId::getSystemLanguage()); +} + +void ListFonts::DeInit() +{ + auto xContext = css::uno::Reference<css::lang::XComponent>( + comphelper::getProcessComponentContext(), css::uno::UNO_QUERY_THROW); + xContext->dispose(); + ::comphelper::setProcessServiceFactory(nullptr); +} + +SAL_IMPLEMENT_MAIN() +{ + ListFonts aApp; + InitVCL(); + int ret = aApp.Main(); + DeInitVCL(); + + return ret; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |