# HG changeset patch # User rubidium # Date 2013-06-25 20:40:58 # Node ID 4851057db176f9d36486cc6a95b2cabe6348ce44 # Parent 35a010f0c655f63da0016b4f861dc5b2b657a57f (svn r25470) -Feature-ish: use ICU's layout engine when that's available diff --git a/config.lib b/config.lib --- a/config.lib +++ b/config.lib @@ -1718,9 +1718,9 @@ make_cflags_and_ldflags() { # Some icu-configs have the 'feature' of not adding a space where others do add the space if [ "$static_icu" != "0" ]; then - LIBS="$LIBS `$icu_config --ldflags-searchpath` `$icu_config --ldflags-libsonly | tr '\n\r' ' ' | sed s/licu/lsicu/g`" + LIBS="$LIBS `$icu_config --ldflags-searchpath` `$icu_config --ldflags-libsonly --ldflags-layout | tr '\n\r' ' ' | sed s/licu/lsicu/g`" else - LIBS="$LIBS `$icu_config --ldflags-searchpath` `$icu_config --ldflags-libsonly | tr '\n\r' ' '`" + LIBS="$LIBS `$icu_config --ldflags-searchpath` `$icu_config --ldflags-libsonly --ldflags-layout | tr '\n\r' ' '`" fi fi diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -131,7 +131,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -176,7 +176,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -233,7 +233,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -280,7 +280,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true diff --git a/projects/openttd_vs100.vcxproj.in b/projects/openttd_vs100.vcxproj.in --- a/projects/openttd_vs100.vcxproj.in +++ b/projects/openttd_vs100.vcxproj.in @@ -131,7 +131,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -176,7 +176,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true @@ -233,7 +233,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true %(IgnoreSpecificDefaultLibraries) true @@ -280,7 +280,7 @@ 0x0809 - winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;%(AdditionalDependencies) + winmm.lib;ws2_32.lib;libpng.lib;zlibstat.lib;lzo2.lib;liblzma.lib;libfreetype2.lib;icuuc.lib;icuin.lib;icudt.lib;icule.lib;iculx.lib;%(AdditionalDependencies) true LIBCMT.lib;%(IgnoreSpecificDefaultLibraries) true diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -87,7 +87,7 @@ /> +#endif /* WITH_ICU */ + /** * Construct a new font. * @param size The font size to use for this font. @@ -26,6 +31,103 @@ Font::Font(FontSize size, TextColour col assert(size < FS_END); } +#ifdef WITH_ICU +/* Implementation details of LEFontInstance */ + +le_int32 Font::getUnitsPerEM() const +{ + return this->fc->GetUnitsPerEM(); +} + +le_int32 Font::getAscent() const +{ + return this->fc->GetAscender(); +} + +le_int32 Font::getDescent() const +{ + return -this->fc->GetDescender(); +} + +le_int32 Font::getLeading() const +{ + return this->fc->GetHeight(); +} + +float Font::getXPixelsPerEm() const +{ + return (float)this->fc->GetHeight(); +} + +float Font::getYPixelsPerEm() const +{ + return (float)this->fc->GetHeight(); +} + +float Font::getScaleFactorX() const +{ + return 1.0f; +} + +float Font::getScaleFactorY() const +{ + return 1.0f; +} + +const void *Font::getFontTable(LETag tableTag) const +{ + return this->fc->GetFontTable(tableTag); +} + +LEGlyphID Font::mapCharToGlyph(LEUnicode32 ch) const +{ + if (IsTextDirectionChar(ch)) return 0; + return this->fc->MapCharToGlyph(ch); +} + +void Font::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const +{ + advance.fX = glyph == 0xFFFF ? 0 : this->fc->GetGlyphWidth(glyph); + advance.fY = 0; +} + +le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const +{ + return FALSE; +} + +size_t Layouter::AppendToBuffer(UChar *buff, const UChar *buffer_last, WChar c) +{ + /* Transform from UTF-32 to internal ICU format of UTF-16. */ + int32 length = 0; + UErrorCode err = U_ZERO_ERROR; + u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err); + return length; +} + +ParagraphLayout *Layouter::GetParagraphLayout(UChar *buff) +{ + int32 length = buff - this->buffer; + + if (length == 0) { + /* ICU's ParagraphLayout cannot handle empty strings, so fake one. */ + this->buffer[0] = ' '; + length = 1; + this->fonts.End()[-1].first++; + } + + /* Fill ICU's FontRuns with the right data. */ + FontRuns runs(this->fonts.Length()); + for (FontMap::iterator iter = this->fonts.Begin(); iter != this->fonts.End(); iter++) { + runs.add(iter->second, iter->first); + } + + LEErrorCode status = LE_NO_ERROR; + return new ParagraphLayout(this->buffer, length, &runs, NULL, NULL, NULL, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, false, status); +} + +#else /* WITH_ICU */ + /*** Paragraph layout ***/ /** @@ -276,6 +378,7 @@ ParagraphLayout *Layouter::GetParagraphL { return new ParagraphLayout(this->buffer, buff_end - this->buffer, this->fonts); } +#endif /* !WITH_ICU */ /** * Create a new layouter. diff --git a/src/gfx_layout.h b/src/gfx_layout.h --- a/src/gfx_layout.h +++ b/src/gfx_layout.h @@ -16,20 +16,45 @@ #include "gfx_func.h" #include "core/smallmap_type.hpp" +#ifdef WITH_ICU +#include "layout/ParagraphLayout.h" +#define ICU_FONTINSTANCE : public LEFontInstance +#else /* WITH_ICU */ +#define ICU_FONTINSTANCE +#endif /* WITH_ICU */ + /** * Container with information about a font. */ -class Font { +class Font ICU_FONTINSTANCE { public: FontCache *fc; ///< The font we are using. TextColour colour; ///< The colour this font has to be. Font(FontSize size, TextColour colour); + +#ifdef WITH_ICU + /* Implementation details of LEFontInstance */ + + le_int32 getUnitsPerEM() const; + le_int32 getAscent() const; + le_int32 getDescent() const; + le_int32 getLeading() const; + float getXPixelsPerEm() const; + float getYPixelsPerEm() const; + float getScaleFactorX() const; + float getScaleFactorY() const; + const void *getFontTable(LETag tableTag) const; + LEGlyphID mapCharToGlyph(LEUnicode32 ch) const; + void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const; + le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const; +#endif /* WITH_ICU */ }; /** Mapping from index to font. */ typedef SmallMap FontMap; +#ifndef WITH_ICU /** * Class handling the splitting of a paragraph of text into lines and * visual runs. @@ -85,6 +110,7 @@ public: ParagraphLayout(WChar *buffer, int length, FontMap &runs); Line *nextLine(int max_width); }; +#endif /* !WITH_ICU */ /** * The layouter performs all the layout work. @@ -92,7 +118,11 @@ public: * It also accounts for the memory allocations and frees. */ class Layouter : public AutoDeleteSmallVector { +#ifdef WITH_ICU + typedef UChar CharType; ///< The type of character used within the layouter. +#else /* WITH_ICU */ typedef WChar CharType; ///< The type of character used within the layouter. +#endif /* WITH_ICU */ size_t AppendToBuffer(CharType *buff, const CharType *buffer_last, WChar c); ParagraphLayout *GetParagraphLayout(CharType *buff);