diff options
author | rubidium <rubidium@openttd.org> | 2013-06-25 20:40:58 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2013-06-25 20:40:58 +0000 |
commit | 48c1e4f87ee264dd66b665e4ae3a3f299ae2f85b (patch) | |
tree | 298c5104beafad7e68999c6fc2d8916a08456906 /src | |
parent | 7b10e39bf104e9983548ee1b6d94e9dbb57fdb27 (diff) | |
download | openttd-48c1e4f87ee264dd66b665e4ae3a3f299ae2f85b.tar.xz |
(svn r25470) -Feature-ish: use ICU's layout engine when that's available
Diffstat (limited to 'src')
-rw-r--r-- | src/gfx_layout.cpp | 103 | ||||
-rw-r--r-- | src/gfx_layout.h | 32 |
2 files changed, 134 insertions, 1 deletions
diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index caa06fc29..861f390a9 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -12,9 +12,14 @@ #include "stdafx.h" #include "gfx_layout.h" #include "string_func.h" +#include "strings_func.h" #include "table/control_codes.h" +#ifdef WITH_ICU +#include <unicode/ustring.h> +#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 colour) : 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::GetParagraphLayout(WChar *buff_end) { 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 index 7960bf2a2..f66559e22 100644 --- 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<int, Font *> 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<ParagraphLayout::Line *, 4> { +#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); |