20 #ifdef WITH_ICU_LAYOUT 21 #include <unicode/ustring.h> 42 assert(size < FS_END);
45 #ifdef WITH_ICU_LAYOUT 48 le_int32 Font::getUnitsPerEM()
const 50 return this->fc->GetUnitsPerEM();
53 le_int32 Font::getAscent()
const 55 return this->fc->GetAscender();
58 le_int32 Font::getDescent()
const 60 return -this->fc->GetDescender();
63 le_int32 Font::getLeading()
const 65 return this->fc->GetHeight();
68 float Font::getXPixelsPerEm()
const 70 return (
float)this->fc->GetHeight();
73 float Font::getYPixelsPerEm()
const 75 return (
float)this->fc->GetHeight();
78 float Font::getScaleFactorX()
const 83 float Font::getScaleFactorY()
const 88 const void *Font::getFontTable(LETag tableTag)
const 91 return this->getFontTable(tableTag, length);
94 const void *Font::getFontTable(LETag tableTag,
size_t &length)
const 96 return this->fc->GetFontTable(tableTag, length);
99 LEGlyphID Font::mapCharToGlyph(LEUnicode32 ch)
const 102 return this->fc->MapCharToGlyph(ch);
105 void Font::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance)
const 107 advance.fX = glyph == 0xFFFF ? 0 : this->fc->GetGlyphWidth(glyph);
111 le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point)
const 120 UErrorCode err = U_ZERO_ERROR;
121 u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err);
138 const ParagraphLayout::VisualRun *
vr;
141 ICUVisualRun(
const ParagraphLayout::VisualRun *vr) : vr(vr) { }
143 const Font *GetFont()
const {
return (
const Font*)vr->getFont(); }
144 int GetGlyphCount()
const {
return vr->getGlyphCount(); }
145 const GlyphID *GetGlyphs()
const {
return vr->getGlyphs(); }
146 const float *GetPositions()
const {
return vr->getPositions(); }
147 int GetLeading()
const {
return vr->getLeading(); }
148 const int *GetGlyphToCharMap()
const {
return vr->getGlyphToCharMap(); }
153 ParagraphLayout::Line *
l;
156 ICULine(ParagraphLayout::Line *l) : l(l)
158 for (
int i = 0; i < l->countRuns(); i++) {
164 int GetLeading()
const {
return l->getLeading(); }
165 int GetWidth()
const {
return l->getWidth(); }
166 int CountRuns()
const {
return l->countRuns(); }
169 int GetInternalCharLength(
WChar c)
const 178 void Reflow() { p->reflow(); }
182 ParagraphLayout::Line *l = p->nextLine(max_width);
183 return l == NULL ? NULL :
new ICULine(l);
189 int32 length = buff_end - buff;
195 fontMapping.
End()[-1].first++;
199 FontRuns runs(fontMapping.
Length());
201 runs.add(iter->second, iter->first);
204 LEErrorCode status = LE_NO_ERROR;
207 ParagraphLayout *
p =
new ParagraphLayout(buff, length, &runs, NULL, NULL, NULL,
_current_text_dir ==
TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR,
false, status);
208 if (status != LE_NO_ERROR) {
255 const Font *GetFont()
const;
256 int GetGlyphCount()
const;
257 const GlyphID *GetGlyphs()
const;
258 const float *GetPositions()
const;
259 int GetLeading()
const;
260 const int *GetGlyphToCharMap()
const;
266 int GetLeading()
const;
267 int GetWidth()
const;
268 int CountRuns()
const;
271 int GetInternalCharLength(
WChar c)
const {
return 1; }
291 font(font), glyph_count(char_count)
298 this->positions[0] = x;
299 this->positions[1] = 0;
302 this->
glyphs[i] = font->fc->MapCharToGlyph(chars[i]);
303 this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->
glyphs[i]);
304 this->positions[2 * i + 3] = 0;
305 this->glyph_to_char[i] = i;
368 return this->
GetFont()->fc->GetHeight();
378 for (
const FallbackVisualRun *
const *run = this->Begin(); run != this->End(); run++) {
379 leading =
max(leading, (*run)->GetLeading());
391 if (this->Length() == 0)
return 0;
399 return (
int)run->GetPositions()[run->GetGlyphCount() * 2];
408 return this->Length();
417 return *this->Get(run);
428 assert(runs.
End()[-1].first == length);
450 if (this->
buffer == NULL)
return NULL;
454 if (*this->
buffer ==
'\0') {
462 const WChar *last_space = NULL;
463 const WChar *last_char = begin;
468 while (iter->first <= offset) {
470 assert(iter != this->
runs.
End());
474 const WChar *next_run = this->buffer_begin + iter->first;
485 if (this->
buffer == next_run) {
489 assert(iter != this->
runs.
End());
491 next_run = this->buffer_begin + iter->first;
502 if (width > max_width) {
505 if (width == char_width) {
512 if (last_space == NULL) {
522 this->
buffer = last_space + 1;
523 last_char = last_space;
532 if (l->
Length() == 0 || last_char - begin != 0) {
573 template <
typename T>
580 typename T::CharType *buff = buff_begin;
591 for (; buff < buffer_last;) {
592 WChar c = Utf8Consume(const_cast<const char **>(&str));
593 if (c ==
'\0' || c ==
'\n') {
595 }
else if (c >= SCC_BLUE && c <= SCC_BLACK) {
597 }
else if (c == SCC_PREVIOUS_COLOUR) {
612 if (!fontMapping.
Contains(buff - buff_begin)) {
613 fontMapping.
Insert(buff - buff_begin, f);
621 if (!fontMapping.
Contains(buff - buff_begin)) {
622 fontMapping.
Insert(buff - buff_begin, f);
642 const char *lineend = str;
645 if (c ==
'\0' || c ==
'\n')
break;
650 if (line.
layout != NULL) {
657 #ifdef WITH_ICU_LAYOUT 659 const char *old_str = str;
661 GetLayouter<ICUParagraphLayout>(line, str, state);
662 if (line.layout == NULL) {
663 static bool warned =
false;
665 DEBUG(misc, 0,
"ICU layouter bailed on the font. Falling back to the fallback layouter");
671 GetLayouter<FallbackParagraphLayout>(line, str, state);
674 GetLayouter<FallbackParagraphLayout>(line, str, state);
680 while ((l = line.
layout->NextLine(maxw)) != NULL) {
695 d.width = max<uint>(d.width, (*l)->GetWidth());
696 d.height += (*l)->GetLeading();
712 const char *str = this->
string;
716 if (c ==
'\0' || c ==
'\n')
break;
718 index += (*this->
Begin())->GetInternalCharLength(c);
726 if (*ch ==
'\0' || *ch ==
'\n') {
727 Point p = { line->GetWidth(), 0 };
732 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
735 for (
int i = 0; i < run->GetGlyphCount(); i++) {
737 if ((
size_t)run->GetGlyphToCharMap()[i] == index) {
738 Point p = { (int)run->GetPositions()[i * 2], (int)run->GetPositions()[i * 2 + 1] };
758 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
761 for (
int i = 0; i < run->GetGlyphCount(); i++) {
763 if (run->GetGlyphs()[i] == 0xFFFF)
continue;
765 int begin_x = (int)run->GetPositions()[i * 2];
766 int end_x = (int)run->GetPositions()[i * 2 + 2];
770 size_t index = run->GetGlyphToCharMap()[i];
773 for (
const char *str = this->
string; *str !=
'\0'; ) {
774 if (cur_idx == index)
return str;
776 WChar c = Utf8Consume(&str);
777 cur_idx += line->GetInternalCharLength(c);
792 if (it !=
fonts[size].
End())
return it->second;
794 Font *f =
new Font(size, colour);
831 key.
str.assign(str, len);
Functions related to OTTD's strings.
~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.
static void GetLayouter(Layouter::LineCacheItem &line, const char *&str, FontState &state)
Helper for getting a ParagraphLayouter of the given type.
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 const bool SUPPORTS_RTL
Helper for GetLayouter, to get whether the layouter supports RTL.
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 SetPreviousColour()
Switch to previous colour.
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.
ParagraphLayout::Line * l
The actual ICU line.
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 size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c)
Appand a wide character to the internal buffer.
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.
ParagraphLayout * p
The actual ICU paragraph layout.
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.
void Reflow()
Reset the position to the start of the paragraph.
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.
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...
const ParagraphLayout::VisualRun * vr
The actual ICU vr.
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.
WChar CharType
Helper for GetLayouter, to get the right type.
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.
Index of the small font in the font tables.
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.
Index of the large font in the font tables.
static FallbackParagraphLayout * GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping)
Get the actual ParagraphLayout for the given buffer.
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.
UChar CharType
Helper for GetLayouter, to get the right type.
Text is written right-to-left by default.
uint32 GlyphID
Glyphs are characters from a font.
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.