20 #ifdef WITH_ICU_LAYOUT 21 #include <unicode/ustring.h> 50 assert(size < FS_END);
53 #ifdef WITH_ICU_LAYOUT 56 le_int32 Font::getUnitsPerEM()
const 58 return this->fc->GetUnitsPerEM();
61 le_int32 Font::getAscent()
const 63 return this->fc->GetAscender();
66 le_int32 Font::getDescent()
const 68 return -this->fc->GetDescender();
71 le_int32 Font::getLeading()
const 73 return this->fc->GetHeight();
76 float Font::getXPixelsPerEm()
const 78 return (
float)this->fc->GetHeight();
81 float Font::getYPixelsPerEm()
const 83 return (
float)this->fc->GetHeight();
86 float Font::getScaleFactorX()
const 91 float Font::getScaleFactorY()
const 96 const void *Font::getFontTable(LETag tableTag)
const 99 return this->getFontTable(tableTag, length);
102 const void *Font::getFontTable(LETag tableTag,
size_t &length)
const 104 return this->fc->GetFontTable(tableTag, length);
107 LEGlyphID Font::mapCharToGlyph(LEUnicode32 ch)
const 110 return this->fc->MapCharToGlyph(ch);
113 void Font::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance)
const 115 advance.fX = glyph == 0xFFFF ? 0 : this->fc->GetGlyphWidth(glyph);
119 le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point)
const 128 icu::ParagraphLayout *
p;
132 const icu::ParagraphLayout::VisualRun *
vr;
135 ICUVisualRun(
const icu::ParagraphLayout::VisualRun *vr) : vr(vr) { }
137 const Font *GetFont()
const {
return (
const Font*)vr->getFont(); }
138 int GetGlyphCount()
const {
return vr->getGlyphCount(); }
139 const GlyphID *GetGlyphs()
const {
return vr->getGlyphs(); }
140 const float *GetPositions()
const {
return vr->getPositions(); }
141 int GetLeading()
const {
return vr->getLeading(); }
142 const int *GetGlyphToCharMap()
const {
return vr->getGlyphToCharMap(); }
147 icu::ParagraphLayout::Line *
l;
150 ICULine(icu::ParagraphLayout::Line *l) : l(l)
152 for (
int i = 0; i < l->countRuns(); i++) {
158 int GetLeading()
const {
return l->getLeading(); }
159 int GetWidth()
const {
return l->getWidth(); }
160 int CountRuns()
const {
return l->countRuns(); }
163 int GetInternalCharLength(
WChar c)
const 172 void Reflow() { p->reflow(); }
176 icu::ParagraphLayout::Line *l = p->nextLine(max_width);
177 return l == NULL ? NULL :
new ICULine(l);
189 static const bool SUPPORTS_RTL =
true;
193 int32 length = buff_end - buff;
199 fontMapping.
End()[-1].first++;
203 icu::FontRuns runs(fontMapping.
Length());
205 runs.add(iter->second, iter->first);
208 LEErrorCode status = LE_NO_ERROR;
211 icu::ParagraphLayout *
p =
new icu::ParagraphLayout(buff, length, &runs, NULL, NULL, NULL,
_current_text_dir ==
TD_RTL ? 1 : 0,
false, status);
212 if (status != LE_NO_ERROR) {
220 static size_t AppendToBuffer(UChar *buff,
const UChar *buffer_last,
WChar c)
224 UErrorCode err = U_ZERO_ERROR;
225 u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err);
263 const Font *GetFont()
const;
264 int GetGlyphCount()
const;
265 const GlyphID *GetGlyphs()
const;
266 const float *GetPositions()
const;
267 int GetLeading()
const;
268 const int *GetGlyphToCharMap()
const;
274 int GetLeading()
const;
275 int GetWidth()
const;
276 int CountRuns()
const;
279 int GetInternalCharLength(
WChar c)
const {
return 1; }
299 static const bool SUPPORTS_RTL =
false;
335 font(font), glyph_count(char_count)
342 this->positions[0] = x;
343 this->positions[1] = 0;
346 this->
glyphs[i] = font->fc->MapCharToGlyph(chars[i]);
347 this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->
glyphs[i]);
348 this->positions[2 * i + 3] = 0;
349 this->glyph_to_char[i] = i;
412 return this->
GetFont()->fc->GetHeight();
422 for (
const FallbackVisualRun *
const *run = this->Begin(); run != this->End(); run++) {
423 leading =
max(leading, (*run)->GetLeading());
435 if (this->Length() == 0)
return 0;
443 return (
int)run->GetPositions()[run->GetGlyphCount() * 2];
452 return this->Length();
461 return *this->Get(run);
472 assert(runs.
End()[-1].first == length);
494 if (this->
buffer == NULL)
return NULL;
498 if (*this->
buffer ==
'\0') {
507 while (iter->first <= offset) {
509 assert(iter != this->
runs.
End());
513 const WChar *next_run = this->buffer_begin + iter->first;
516 const WChar *last_space = NULL;
517 const WChar *last_char;
528 if (this->
buffer == next_run) {
532 assert(iter != this->
runs.
End());
534 next_run = this->buffer_begin + iter->first;
545 if (width > max_width) {
548 if (width == char_width) {
555 if (last_space == NULL) {
565 this->
buffer = last_space + 1;
566 last_char = last_space;
575 if (l->
Length() == 0 || last_char - begin != 0) {
591 template <
typename T>
598 typename T::CharType *buff = buff_begin;
610 for (; buff < buffer_last;) {
611 WChar c = Utf8Consume(const_cast<const char **>(&str));
612 if (c ==
'\0' || c ==
'\n') {
614 }
else if (c >= SCC_BLUE && c <= SCC_BLACK) {
616 }
else if (c == SCC_PUSH_COLOUR) {
618 }
else if (c == SCC_POP_COLOUR) {
620 }
else if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) {
627 buff += T::AppendToBuffer(buff, buffer_last, c);
631 if (!fontMapping.
Contains(buff - buff_begin)) {
632 fontMapping.
Insert(buff - buff_begin, f);
640 if (!fontMapping.
Contains(buff - buff_begin)) {
641 fontMapping.
Insert(buff - buff_begin, f);
643 line.
layout = T::GetParagraphLayout(buff_begin, buff, fontMapping);
661 const char *lineend = str;
664 if (c ==
'\0' || c ==
'\n')
break;
669 if (line.
layout != NULL) {
677 #if defined(WITH_ICU_LAYOUT) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA) 678 const char *old_str = str;
681 #ifdef WITH_ICU_LAYOUT 682 GetLayouter<ICUParagraphLayoutFactory>(line, str, state);
683 if (line.layout == NULL) {
684 static bool warned =
false;
686 DEBUG(misc, 0,
"ICU layouter bailed on the font. Falling back to the fallback layouter");
695 #ifdef WITH_UNISCRIBE 696 if (line.layout == NULL) {
697 GetLayouter<UniscribeParagraphLayoutFactory>(line, str, state);
698 if (line.layout == NULL) {
706 if (line.layout == NULL) {
707 GetLayouter<CoreTextParagraphLayoutFactory>(line, str, state);
708 if (line.layout == NULL) {
715 if (line.layout == NULL) {
716 GetLayouter<FallbackParagraphLayoutFactory>(line, str, state);
722 while ((l = line.
layout->NextLine(maxw)) != NULL) {
737 d.width = max<uint>(d.width, (*l)->GetWidth());
738 d.height += (*l)->GetLeading();
754 const char *str = this->
string;
758 if (c ==
'\0' || c ==
'\n')
break;
760 index += (*this->
Begin())->GetInternalCharLength(c);
768 if (*ch ==
'\0' || *ch ==
'\n') {
769 Point p = { line->GetWidth(), 0 };
774 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
777 for (
int i = 0; i < run->GetGlyphCount(); i++) {
779 if ((
size_t)run->GetGlyphToCharMap()[i] == index) {
780 Point p = { (int)run->GetPositions()[i * 2], (int)run->GetPositions()[i * 2 + 1] };
800 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
803 for (
int i = 0; i < run->GetGlyphCount(); i++) {
805 if (run->GetGlyphs()[i] == 0xFFFF)
continue;
807 int begin_x = (int)run->GetPositions()[i * 2];
808 int end_x = (int)run->GetPositions()[i * 2 + 2];
812 size_t index = run->GetGlyphToCharMap()[i];
815 for (
const char *str = this->
string; *str !=
'\0'; ) {
816 if (cur_idx == index)
return str;
818 WChar c = Utf8Consume(&str);
819 cur_idx += line->GetInternalCharLength(c);
834 if (it !=
fonts[size].
End())
return it->second;
836 Font *f =
new Font(size, colour);
855 #if defined(WITH_UNISCRIBE) 856 UniscribeResetScriptCache(size);
858 #if defined(WITH_COCOA) 880 key.
str.assign(str, len);
Functions related to OTTD's strings.
Functions related to laying out text on Win32.
UChar CharType
Helper for GetLayouter, to get the right type.
~FallbackVisualRun()
Free all data.
const ParagraphLayouter::Line * NextLine(int max_width)
Construct a new line with a maximum width.
bool Contains(const T &key) const
Tests whether a key is assigned in this map.
Control codes that are embedded in the translation strings.
const Pair * Find(const T &key) const
Finds given key in this map.
FallbackVisualRun(Font *font, const WChar *chars, int glyph_count, int x)
Create the visual run.
static bool IsInsideMM(const T x, const uint min, const uint max)
Checks if a value is in an interval.
Helper class to construct a new FallbackParagraphLayout.
static void GetLayouter(Layouter::LineCacheItem &line, const char *&str, FontState &state)
Helper for getting a ParagraphLayouter of the given type.
const icu::ParagraphLayout::VisualRun * vr
The actual ICU vr.
Functions related to debugging.
void * buffer
Accessed by both ICU's and our ParagraphLayout::nextLine.
FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs)
Create a new paragraph layouter.
static LineCache * linecache
Cache of ParagraphLayout lines.
const WChar * buffer_begin
Begin of the buffer.
static bool IsWhitespace(WChar c)
Check whether UNICODE character is whitespace or not, i.e.
Implementation of simple mapping class.
std::string str
Source string of the line (including colour and font size codes).
int GetWidth() const
Get the width of this line.
void Clear()
Remove all items from the list.
int * glyph_to_char
The char index of the glyphs.
byte GetCharacterWidth(FontSize size, WChar key)
Return width of character glyph.
const T * Begin() const
Get the pointer to the first item (const)
int GetLeading() const
Get the height of this font.
static bool IsTextDirectionChar(WChar c)
Is the given character a text direction character.
bool Insert(const T &key, const U &data)
Adds new item to this map.
static const int DRAW_STRING_BUFFER
Size of the buffer used for drawing strings.
const char * GetCharAtPosition(int x) const
Get the character that is at a position.
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
const int * GetGlyphToCharMap() const
Get the glyph-to-character map for this visual run.
int glyph_count
The number of glyphs.
Visual run contains data about the bit of text with the same font.
void MacOSResetScriptCache(FontSize size)
Delete CoreText font reference for a specific font size.
static T max(const T a, const T b)
Returns the maximum of two values.
Functions related to laying out the texts.
FontMap runs
Accessed by our ParagraphLayout::nextLine.
const T * End() const
Get the pointer behind the last valid item (const)
static Font * GetFont(FontSize size, TextColour colour)
Get a static font instance.
void SetFontSize(FontSize f)
Switch to using a new font f.
ParagraphLayouter::Line * * Append(uint to_add=1)
Append an item and return it.
icu::ParagraphLayout::Line * l
The actual ICU line.
Font * font
The font used to layout these.
Functions related to low-level strings.
A single line worth of VisualRuns.
uint Length() const
Get the number of items in the list.
Visual run contains data about the bit of text with the same font.
Interface to glue fallback and normal layouter into one.
FontMap & runs
The fonts we have to use for this paragraph.
Simple vector template class, with automatic delete.
Definition of base types and functions in a cross-platform compatible way.
A number of safeguards to prevent using unsafe methods.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
const ParagraphLayouter::VisualRun * GetVisualRun(int run) const
Get a specific visual run.
WChar CharType
Helper for GetLayouter, to get the right type.
void Reflow()
Reset the position to the start of the paragraph.
Functions related to localized text support on OSX.
void SetColour(TextColour c)
Switch to new colour c.
const float * GetPositions() const
Get the positions of this run.
static int8 Utf8CharLen(WChar c)
Return the length of a UTF-8 encoded character.
Class handling the splitting of a paragraph of text into lines and visual runs.
static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c)
Append a wide character to the internal buffer.
int GetLeading() const
Get the height of the line.
GlyphID * glyphs
The glyphs we're drawing.
static void ResetFontCache(FontSize size)
Reset cached font information.
Font cache for basic fonts.
Dimension GetBounds()
Get the boundaries of this paragraph.
#define DEBUG(name, level,...)
Output a line of debugging information.
float * positions
The positions of the glyphs.
Text drawing parameters, which can change while drawing a line, but are kept between multiple parts o...
void PopColour()
Switch to and pop the last saved colour on the stack.
int CountRuns() const
Get the number of runs in this line.
TextColour cur_colour
Current text colour.
TextDirection _current_text_dir
Text direction of the currently selected language.
FontSize fontsize
Current font size.
static FontColourMap fonts[FS_END]
Cache of Font instances.
FontSize
Available font sizes.
FontState state_after
Font state after the line.
A single line worth of VisualRuns.
Wrapper for doing layouts with ICU.
void PushColour()
Push the current colour on to the stack.
FontState state_before
Font state at the beginning of the line.
Coordinates of a point in 2D.
static void ReduceLineCache()
Reduce the size of linecache if necessary to prevent infinite growth.
static void ResetLineCache()
Clear line cache.
A single line worth of VisualRuns.
static LineCacheItem & GetCachedParagraphLayout(const char *str, size_t len, const FontState &state)
Get reference to cache item.
Visual run contains data about the bit of text with the same font.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
icu::ParagraphLayout * p
The actual ICU paragraph layout.
const ParagraphLayouter::Line * * Get(uint index) const
Get the pointer to item "number" (const)
const Font * GetFont() const
Get the font associated with this run.
Text is written right-to-left by default.
uint32 GlyphID
Glyphs are characters from a font.
Helper class to construct a new ICUParagraphLayout.
ParagraphLayouter * layout
Layout of the line.
uint32 WChar
Type for wide characters, i.e.
int GetGlyphCount() const
Get the number of glyphs in this run.
const WChar * buffer
The current location in the buffer.
Layouter(const char *str, int maxw=INT32_MAX, TextColour colour=TC_FROMSTRING, FontSize fontsize=FS_NORMAL)
Create a new layouter.
Dimensions (a width and height) of a rectangle in 2D.
Point GetCharPosition(const char *ch) const
Get the position of a character in the layout.
const char * string
Pointer to the original string.
const GlyphID * GetGlyphs() const
Get the glyphs of this run.
static ParagraphLayouter * GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping)
Get the actual ParagraphLayout for the given buffer.