Browse Source

Text: don't use std::u32string on MinGW.

MinGW (or Windows at general?!) somehow doesn't expect four-byte
characters in a string and this class fails miserably when freeing
memory. Replaced with std::vector<char32_t>, it's horrendously ugly
solution, but I hope this will be resolved soon with newer MinGW GCC
(4.7.2 fails).
pull/277/head
Vladimír Vondruš 13 years ago
parent
commit
d2bdc9d28f
  1. 7
      src/Text/AbstractFont.cpp
  2. 7
      src/Text/AbstractFont.h
  3. 32
      src/Text/AbstractFontConverter.cpp
  4. 30
      src/Text/AbstractFontConverter.h
  5. 39
      src/Text/Test/AbstractFontConverterTest.cpp

7
src/Text/AbstractFont.cpp

@ -124,7 +124,12 @@ void AbstractFont::fillGlyphCache(GlyphCache& cache, const std::string& characte
doFillGlyphCache(cache, Utility::Unicode::utf32(characters));
}
void AbstractFont::doFillGlyphCache(GlyphCache&, const std::u32string&) {
#ifndef _WIN32
void AbstractFont::doFillGlyphCache(GlyphCache&, const std::u32string&)
#else
void AbstractFont::doFillGlyphCache(GlyphCache&, const std::vector<char32_t>&)
#endif
{
CORRADE_ASSERT(false, "Text::AbstractFont::fillGlyphCache(): feature advertised but not implemented", );
}

7
src/Text/AbstractFont.h

@ -250,8 +250,15 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin {
*
* The string is converted from UTF-8 to UTF-32, unique characters are
* *not* removed.
* @note On Windows uses `std::vector<char32_t>` instead of
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
virtual void doFillGlyphCache(GlyphCache& cache, const std::u32string& characters);
#else
virtual void doFillGlyphCache(GlyphCache& cache, const std::vector<char32_t>& characters);
#endif
/**
* @brief Implementation for createGlyphCache()

32
src/Text/AbstractFontConverter.cpp

@ -43,7 +43,12 @@ std::vector<std::pair<std::string, Containers::Array<unsigned char>>> AbstractFo
return doExportFontToData(font, cache, filename, uniqueUnicode(characters));
}
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const {
#ifndef _WIN32
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const
#else
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> AbstractFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const
#endif
{
CORRADE_ASSERT(!(features() & Feature::MultiFile),
"Text::AbstractFontConverter::exportFontToData(): feature advertised but not implemented", {});
@ -61,7 +66,12 @@ Containers::Array<unsigned char> AbstractFontConverter::exportFontToSingleData(A
return doExportFontToSingleData(font, cache, uniqueUnicode(characters));
}
Containers::Array<unsigned char> AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const {
#ifndef _WIN32
Containers::Array<unsigned char> AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const
#else
Containers::Array<unsigned char> AbstractFontConverter::doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector<char32_t>&) const
#endif
{
CORRADE_ASSERT(false,
"Text::AbstractFontConverter::exportFontToSingleData(): feature advertised but not implemented", nullptr);
}
@ -73,7 +83,12 @@ bool AbstractFontConverter::exportFontToFile(AbstractFont& font, GlyphCache& cac
return doExportFontToFile(font, cache, filename, uniqueUnicode(characters));
}
bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const {
#ifndef _WIN32
bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const
#else
bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const
#endif
{
CORRADE_ASSERT(features() & Feature::ConvertData,
"Text::AbstractFontConverter::exportFontToFile(): not implemented", false);
@ -214,9 +229,18 @@ GlyphCache* AbstractFontConverter::doImportGlyphCacheFromFile(const std::string&
return doImportGlyphCacheFromSingleData(data);
}
std::u32string AbstractFontConverter::uniqueUnicode(const std::string& characters) {
#ifndef _WIN32
std::u32string AbstractFontConverter::uniqueUnicode(const std::string& characters)
#else
std::vector<char32_t> AbstractFontConverter::uniqueUnicode(const std::string& characters)
#endif
{
/* Convert UTF-8 to UTF-32 */
#ifndef _WIN32
std::u32string result = Utility::Unicode::utf32(characters);
#else
std::vector<char32_t> result = Utility::Unicode::utf32(characters);
#endif
/* Remove duplicate glyphs */
std::sort(result.begin(), result.end());

30
src/Text/AbstractFontConverter.h

@ -250,11 +250,28 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
*
* If the plugin doesn't have @ref Feature "Feature::MultiFile",
* default implementation calls doExportFontToSingleData().
* @note On Windows uses `std::vector<char32_t>` instead of
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
virtual std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const;
#else
virtual std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const;
#endif
/** @brief Implementation for exportFontToSingleData() */
/**
* @brief Implementation for exportFontToSingleData()
*
* @note On Windows uses `std::vector<char32_t>` instead of
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
virtual Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::u32string& characters) const;
#else
virtual Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont& font, GlyphCache& cache, const std::vector<char32_t>& characters) const;
#endif
/**
* @brief Implementation for exportFontToFile()
@ -262,8 +279,15 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
* If @ref Feature "Feature::ConvertData" is supported, default
* implementation calls doExportFontToData() and saves the result to
* given file(s).
* @note On Windows uses `std::vector<char32_t>` instead of
* `std::u32string`. See @ref Corrade::Utility::Unicode::utf32()
* for more information.
*/
#ifndef _WIN32
virtual bool doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const;
#else
virtual bool doExportFontToFile(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const;
#endif
/**
* @brief Implementation for exportGlyphCacheToData()
@ -307,7 +331,11 @@ class MAGNUM_TEXT_EXPORT AbstractFontConverter: public PluginManager::AbstractPl
virtual GlyphCache* doImportGlyphCacheFromFile(const std::string& filename) const;
private:
#ifndef _WIN32
MAGNUM_TEXT_LOCAL static std::u32string uniqueUnicode(const std::string& characters);
#else
MAGNUM_TEXT_LOCAL static std::vector<char32_t> uniqueUnicode(const std::string& characters);
#endif
};
CORRADE_ENUMSET_OPERATORS(AbstractFontConverter::Features)

39
src/Text/Test/AbstractFontConverterTest.cpp

@ -65,24 +65,45 @@ AbstractFontConverterTest::AbstractFontConverterTest() {
void AbstractFontConverterTest::convertGlyphs() {
class GlyphExporter: public AbstractFontConverter {
public:
#ifndef _WIN32
GlyphExporter(std::u32string& characters): characters(characters) {}
#else
GlyphExporter(std::vector<char32_t>& characters): characters(characters) {}
#endif
private:
Features doFeatures() const override { return Feature::ConvertData|Feature::ExportFont; }
Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string& characters) const override {
#ifndef _WIN32
Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string& characters) const override
#else
Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector<char32_t>& characters) const override
#endif
{
this->characters = characters;
return nullptr;
}
#ifndef _WIN32
std::u32string& characters;
#else
std::vector<char32_t>& characters;
#endif
};
#ifndef _WIN32
std::u32string characters;
#else
std::vector<char32_t> characters;
#endif
GlyphExporter exporter(characters);
exporter.exportFontToSingleData(*static_cast<AbstractFont*>(nullptr), *static_cast<GlyphCache*>(nullptr), "abC01a0 ");
CORRADE_COMPARE(characters, (std::u32string{
#ifndef _WIN32
CORRADE_COMPARE(characters, U" 01Cab");
#else
CORRADE_COMPARE(characters, (std::vector<char32_t>{
U' ', U'0', U'1', U'C', U'a', U'b'}));
#endif
}
void AbstractFontConverterTest::exportFontToSingleData() {
@ -90,7 +111,12 @@ void AbstractFontConverterTest::exportFontToSingleData() {
private:
Features doFeatures() const override { return Feature::ConvertData|Feature::ExportFont; }
Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const override {
#ifndef _WIN32
Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::u32string&) const override
#else
Containers::Array<unsigned char> doExportFontToSingleData(AbstractFont&, GlyphCache&, const std::vector<char32_t>&) const override
#endif
{
Containers::Array<unsigned char> data(1);
data[0] = 0xee;
return std::move(data);
@ -111,7 +137,12 @@ void AbstractFontConverterTest::exportFontToFile() {
private:
Features doFeatures() const override { return Feature::ConvertData|Feature::ExportFont|Feature::MultiFile; }
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont&, GlyphCache&, const std::string& filename, const std::u32string&) const override {
#ifndef _WIN32
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont&, GlyphCache&, const std::string& filename, const std::u32string&) const override
#else
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont&, GlyphCache&, const std::string& filename, const std::vector<char32_t>&) const override
#endif
{
Containers::Array<unsigned char> file(1);
file[0] = 0xf0;

Loading…
Cancel
Save