From 20a9d9a374ebae45d7afc34ca54678ced7904618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 2 Nov 2013 21:26:55 +0100 Subject: [PATCH] Text: added magnum-fontconverter utility. Again borrowed from Push the Box, modified and made slightly more configurable. Will write proper docs for the utilities when I have some more time. --- CMakeLists.txt | 1 + doc/building.dox | 16 +++-- src/Text/CMakeLists.txt | 15 +++++ src/Text/configure.h.cmake | 25 +++++++ src/Text/fontconverter.cpp | 131 +++++++++++++++++++++++++++++++++++++ 5 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 src/Text/configure.h.cmake create mode 100644 src/Text/fontconverter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 34d503736..39eb2b647 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ if(UNIX OR CORRADE_TARGET_NACL) option(WITH_MAGNUMINFO "Build magnum-info utility" OFF) endif() if(UNIX) + cmake_dependent_option(WITH_FONTCONVERTER "Build magnum-fontconverter utility" OFF "NOT TARGET_GLES" OFF) cmake_dependent_option(WITH_DISTANCEFIELDCONVERTER "Build magnum-distancefieldconverter utility" OFF "NOT TARGET_GLES" OFF) endif() diff --git a/doc/building.dox b/doc/building.dox index 1f6570072..c0ee2f5e0 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -157,11 +157,6 @@ you can specify which parts will be built and which not: - `WITH_TEXT` - Text library. Enables also building of TextureTools library. - `WITH_TEXTURETOOLS` - TextureTools library. Enabled automatically if `WITH_TEXT` or `WITH_DISTANCEFIELDCONVERTER` is enabled. -- `WITH_MAGNUMINFO` - `magnum-info` executable, provides information about - the engine and OpenGL capabilities. -- `WITH_DISTANCEFIELDCONVERTER` - `magnum-distancefield` executable for - converting black&white images to distance field textures. Enables also - building of TextureTools library. None of the @ref Platform "application libraries" is built by default (and you need at least one). Choose the one which suits your requirements and your @@ -175,6 +170,17 @@ platform best: - `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" - `WITH_WINDOWLESSNACLAPPLICATION` - @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication" +There are also a few command-line utilities. They are currently available only +on Linux and are disabled by default: + +- `WITH_MAGNUMINFO` - `magnum-info` executable, provides information about + the engine and OpenGL capabilities. +- `WITH_FONTCONVERTER` - `magnum-fontconverter` executable for converting + fonts to raster ones. Enables also building of Text library. +- `WITH_DISTANCEFIELDCONVERTER` - `magnum-distancefieldconverter` executable + for converting black&white images to distance field textures. Enables also + building of TextureTools library. + Magnum also contains a set of dependency-less plugins for importing essential file formats. Additional plugins are provided in separate plugin repository, see @ref building-plugins for more information. None of the plugins is built by diff --git a/src/Text/CMakeLists.txt b/src/Text/CMakeLists.txt index b1176844e..b6937fdd5 100644 --- a/src/Text/CMakeLists.txt +++ b/src/Text/CMakeLists.txt @@ -51,6 +51,21 @@ install(TARGETS MagnumText ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumText_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Text) +if(WITH_FONTCONVERTER) + if(NOT UNIX OR TARGET_GLES) + message(FATAL_ERROR "magnum-fontconverter is not available on this platform. Set WITH_FONTCONVERTER to OFF to suppress this warning.") + endif() + + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + + add_executable(magnum-fontconverter fontconverter.cpp) + target_link_libraries(magnum-fontconverter MagnumText Magnum MagnumWindowlessGlxApplication ${X11_LIBRARIES}) + install(TARGETS magnum-fontconverter DESTINATION ${MAGNUM_BINARY_INSTALL_DIR}) +endif() + if(BUILD_TESTS) add_subdirectory(Test) endif() diff --git a/src/Text/configure.h.cmake b/src/Text/configure.h.cmake new file mode 100644 index 000000000..048adae7a --- /dev/null +++ b/src/Text/configure.h.cmake @@ -0,0 +1,25 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#define MAGNUM_PLUGINS_DIR "${MAGNUM_PLUGINS_DIR}" diff --git a/src/Text/fontconverter.cpp b/src/Text/fontconverter.cpp new file mode 100644 index 000000000..1db6bc542 --- /dev/null +++ b/src/Text/fontconverter.cpp @@ -0,0 +1,131 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include + +#include "Platform/WindowlessGlxApplication.h" +#include "Text/AbstractFont.h" +#include "Text/AbstractFontConverter.h" +#include "Text/DistanceFieldGlyphCache.h" +#include "Trade/AbstractImageConverter.h" + +#include "configure.h" + +namespace Magnum { namespace Text { + +class FontConverter: public Platform::WindowlessApplication { + public: + explicit FontConverter(const Arguments& arguments); + + int exec() override; + + private: + Utility::Arguments args; +}; + +FontConverter::FontConverter(const Arguments& arguments): Platform::WindowlessApplication(arguments, nullptr) { + args.addArgument("input").setHelp("input", "input font") + .addArgument("output").setHelp("output", "output filename prefix") + .addNamedArgument("font").setHelp("font", "plugin for opening the font") + .addNamedArgument("converter").setHelp("converter", "plugin for converting the font") + .addOption("plugin-dir", MAGNUM_PLUGINS_DIR).setHelpKey("plugin-dir", "DIR").setHelp("plugin-dir", "base plugin dir") + .addOption("characters", "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789?!:,. ").setHelp("characters", "characters to include in the output") + .addOption("font-size", "128").setHelpKey("font-size", "\"X Y\"").setHelp("font-size", "TTF font size") + .addOption("atlas-size", "2048 2048").setHelpKey("atlas-size", "\"X Y\"").setHelp("atlas-size", "glyph atlas size") + .addOption("output-size", "256 256").setHelpKey("output-size", "\"X Y\"").setHelp("output-size", "output atlas size. If set to zero size, distance field computation will not be used.") + .addOption("radius", "24").setHelpKey("radius", "N").setHelp("radius", "distance field computation radius") + .setHelp("Converts font to raster one of given atlas size.") + .parse(arguments.argc, arguments.argv); + + createContext({}); +} + +int FontConverter::exec() { + /* Font converter dependencies */ + PluginManager::Manager imageConverterManager(Utility::Directory::join(MAGNUM_PLUGINS_DIR, "imageconverters/")); + + /* Load font */ + PluginManager::Manager fontManager(Utility::Directory::join(MAGNUM_PLUGINS_DIR, "fonts/")); + std::unique_ptr font; + if(!(fontManager.load(args.value("font")) & PluginManager::LoadState::Loaded) || + !(font = fontManager.instance(args.value("font")))) { + Error() << "Cannot load plugin" << args.value("font") << "from" << fontManager.pluginDirectory(); + std::exit(1); + } + + /* Load font converter */ + PluginManager::Manager converterManager(Utility::Directory::join(MAGNUM_PLUGINS_DIR, "fontconverters/")); + std::unique_ptr converter; + if(!(converterManager.load(args.value("converter")) & PluginManager::LoadState::Loaded) || + !(converter = converterManager.instance(args.value("converter")))) { + Error() << "Cannot load plugin" << args.value("converter") << "from" << converterManager.pluginDirectory(); + std::exit(1); + } + + /* Open font */ + if(!font->openFile(args.value("input"), args.value("font-size"))) { + Error() << "Cannot open font" << args.value("input"); + std::exit(1); + } + + /* Create distance field glyph cache if radius is specified */ + std::unique_ptr cache; + if(!args.value("output-size").isZero()) { + Debug() << "Populating distance field glyph cache..."; + + cache.reset(new Text::DistanceFieldGlyphCache( + args.value("atlas-size"), + args.value("output-size"), + args.value("radius"))); + + /* Otherwise use normal cache */ + } else { + Debug() << "Zero-size distance field output specified, populating normal glyph cache..."; + + cache.reset(new Text::GlyphCache(args.value("atlas-size"))); + } + + /* Fill the cache */ + font->fillGlyphCache(*cache, args.value("characters")); + + Debug() << "Converting font..."; + + /* Convert the font */ + if(!converter->exportFontToFile(*font, *cache, args.value("output"), args.value("characters"))) { + Error() << "Cannot export font to" << args.value("output"); + std::exit(1); + } + + Debug() << "Done."; + + return 0; +} + +}} + +MAGNUM_WINDOWLESSAPPLICATION_MAIN(Magnum::Text::FontConverter)