summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2013-06-25 20:40:58 +0000
committerrubidium <rubidium@openttd.org>2013-06-25 20:40:58 +0000
commit48c1e4f87ee264dd66b665e4ae3a3f299ae2f85b (patch)
tree298c5104beafad7e68999c6fc2d8916a08456906 /src
parent7b10e39bf104e9983548ee1b6d94e9dbb57fdb27 (diff)
downloadopenttd-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.cpp103
-rw-r--r--src/gfx_layout.h32
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);