OpenTTD Source
12.0-beta2
|
Go to the documentation of this file.
19 #include <unicode/ustring.h>
48 assert(size < FS_END);
54 le_int32 Font::getUnitsPerEM()
const
56 return this->fc->GetUnitsPerEM();
59 le_int32 Font::getAscent()
const
61 return this->fc->GetAscender();
64 le_int32 Font::getDescent()
const
66 return -this->fc->GetDescender();
69 le_int32 Font::getLeading()
const
71 return this->fc->GetHeight();
74 float Font::getXPixelsPerEm()
const
76 return (
float)this->fc->GetHeight();
79 float Font::getYPixelsPerEm()
const
81 return (
float)this->fc->GetHeight();
84 float Font::getScaleFactorX()
const
89 float Font::getScaleFactorY()
const
94 const void *Font::getFontTable(LETag tableTag)
const
97 return this->getFontTable(tableTag, length);
100 const void *Font::getFontTable(LETag tableTag,
size_t &length)
const
102 return this->fc->GetFontTable(tableTag, length);
105 LEGlyphID Font::mapCharToGlyph(LEUnicode32 ch)
const
108 return this->fc->MapCharToGlyph(ch);
111 void Font::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance)
const
113 advance.fX = glyph == 0xFFFF ? 0 : this->fc->GetGlyphWidth(glyph);
117 le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point)
const
126 icu::ParagraphLayout *
p;
130 const icu::ParagraphLayout::VisualRun *
vr;
135 const Font *GetFont()
const override {
return (
const Font*)
vr->getFont(); }
136 int GetGlyphCount()
const override {
return vr->getGlyphCount(); }
137 const GlyphID *GetGlyphs()
const override {
return vr->getGlyphs(); }
138 const float *GetPositions()
const override {
return vr->getPositions(); }
139 int GetLeading()
const override {
return vr->getLeading(); }
140 const int *GetGlyphToCharMap()
const override {
return vr->getGlyphToCharMap(); }
145 icu::ParagraphLayout::Line *
l;
150 for (
int i = 0; i <
l->countRuns(); i++) {
151 this->emplace_back(
l->getVisualRun(i));
156 int GetLeading()
const override {
return l->getLeading(); }
157 int GetWidth()
const override {
return l->getWidth(); }
158 int CountRuns()
const override {
return l->countRuns(); }
161 int GetInternalCharLength(
WChar c)
const override
170 void Reflow()
override {
p->reflow(); }
172 std::unique_ptr<const Line> NextLine(
int max_width)
override
174 icu::ParagraphLayout::Line *l =
p->nextLine(max_width);
175 return std::unique_ptr<const Line>(l ==
nullptr ?
nullptr :
new ICULine(l));
191 int32 length = buff_end - buff;
197 fontMapping.back().first++;
201 icu::FontRuns runs(fontMapping.size());
202 for (
auto &pair : fontMapping) {
203 runs.add(pair.second, pair.first);
206 LEErrorCode status = LE_NO_ERROR;
209 icu::ParagraphLayout *p =
new icu::ParagraphLayout(buff, length, &runs,
nullptr,
nullptr,
nullptr,
_current_text_dir ==
TD_RTL ? 1 : 0,
false, status);
210 if (status != LE_NO_ERROR) {
218 static size_t AppendToBuffer(UChar *buff,
const UChar *buffer_last,
WChar c)
222 UErrorCode err = U_ZERO_ERROR;
223 u_strFromUTF32(buff, buffer_last - buff, &length, (UChar32*)&c, 1, &err);
262 const Font *
GetFont()
const override;
278 int GetInternalCharLength(
WChar c)
const override {
return 1; }
287 std::unique_ptr<const Line>
NextLine(
int max_width)
override;
334 font(font), glyph_count(char_count)
345 this->
glyphs[i] =
font->fc->MapCharToGlyph(chars[i]);
355 this->positions = other.positions;
356 this->glyph_to_char = other.glyph_to_char;
357 this->glyphs = other.glyphs;
359 other.positions =
nullptr;
360 other.glyph_to_char =
nullptr;
361 other.glyphs =
nullptr;
367 free(this->positions);
368 free(this->glyph_to_char);
387 return this->glyph_count;
405 return this->positions;
414 return this->glyph_to_char;
423 return this->GetFont()->fc->GetHeight();
433 for (
const auto &run : *
this) {
434 leading = std::max(leading, run.GetLeading());
446 if (this->size() == 0)
return 0;
453 const auto &run = this->GetVisualRun(this->CountRuns() - 1);
454 return (
int)run.GetPositions()[run.GetGlyphCount() * 2];
463 return (uint)this->size();
472 return this->at(run);
483 assert(
runs.End()[-1].first == length);
505 if (this->
buffer ==
nullptr)
return nullptr;
509 if (*this->
buffer ==
'\0') {
512 l->emplace_back(this->
runs.front().second, this->buffer, 0, 0);
517 FontMap::iterator iter = this->
runs.data();
518 while (iter->first <= offset) {
520 assert(iter != this->
runs.End());
524 const WChar *next_run = this->buffer_begin + iter->first;
527 const WChar *last_space =
nullptr;
528 const WChar *last_char;
539 if (this->
buffer == next_run) {
540 int w = l->GetWidth();
541 l->emplace_back(iter->second, begin, this->buffer - begin, w);
543 assert(iter != this->
runs.End());
545 next_run = this->buffer_begin + iter->first;
548 last_space =
nullptr;
556 if (width > max_width) {
559 if (width == char_width) {
566 if (last_space ==
nullptr) {
576 this->
buffer = last_space + 1;
577 last_char = last_space;
586 if (l->size() == 0 || last_char - begin != 0) {
587 int w = l->GetWidth();
588 l->emplace_back(iter->second, begin, last_char - begin, w);
602 template <
typename T>
609 typename T::CharType *buff = buff_begin;
621 for (; buff < buffer_last;) {
622 WChar c = Utf8Consume(
const_cast<const char **
>(&str));
623 if (c ==
'\0' || c ==
'\n') {
625 }
else if (c >= SCC_BLUE && c <= SCC_BLACK) {
627 }
else if (c == SCC_PUSH_COLOUR) {
629 }
else if (c == SCC_POP_COLOUR) {
631 }
else if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) {
635 if (!IsPrintable(c))
continue;
640 buff += T::AppendToBuffer(buff, buffer_last, c);
644 if (!fontMapping.
Contains(buff - buff_begin)) {
645 fontMapping.
Insert(buff - buff_begin, f);
653 if (!fontMapping.
Contains(buff - buff_begin)) {
654 fontMapping.
Insert(buff - buff_begin, f);
656 line.
layout = T::GetParagraphLayout(buff_begin, buff, fontMapping);
674 const char *lineend = str;
677 if (c ==
'\0' || c ==
'\n')
break;
682 if (line.
layout !=
nullptr) {
690 #if defined(WITH_ICU_LX) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA)
691 const char *old_str = str;
695 GetLayouter<ICUParagraphLayoutFactory>(line, str, state);
696 if (line.
layout ==
nullptr) {
697 static bool warned =
false;
699 Debug(misc, 0,
"ICU layouter bailed on the font. Falling back to the fallback layouter");
708 #ifdef WITH_UNISCRIBE
709 if (line.
layout ==
nullptr) {
710 GetLayouter<UniscribeParagraphLayoutFactory>(line, str, state);
711 if (line.
layout ==
nullptr) {
719 if (line.
layout ==
nullptr) {
720 GetLayouter<CoreTextParagraphLayoutFactory>(line, str, state);
721 if (line.
layout ==
nullptr) {
728 if (line.
layout ==
nullptr) {
729 GetLayouter<FallbackParagraphLayoutFactory>(line, str, state);
735 auto l = line.
layout->NextLine(maxw);
736 if (l ==
nullptr)
break;
737 this->push_back(std::move(l));
749 for (
const auto &l : *
this) {
750 d.width = std::max<uint>(d.width, l->GetWidth());
751 d.height += l->GetLeading();
767 const char *str = this->
string;
771 if (c ==
'\0' || c ==
'\n')
break;
773 index += this->front()->GetInternalCharLength(c);
778 const auto &line = this->front();
781 if (*ch ==
'\0' || *ch ==
'\n') {
782 Point p = { line->GetWidth(), 0 };
787 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
790 for (
int i = 0; i < run.GetGlyphCount(); i++) {
792 if ((
size_t)run.GetGlyphToCharMap()[i] == index) {
793 Point p = { (int)run.GetPositions()[i * 2], (int)run.GetPositions()[i * 2 + 1] };
811 const auto &line = this->front();
813 for (
int run_index = 0; run_index < line->CountRuns(); run_index++) {
816 for (
int i = 0; i < run.GetGlyphCount(); i++) {
818 if (run.GetGlyphs()[i] == 0xFFFF)
continue;
820 int begin_x = (int)run.GetPositions()[i * 2];
821 int end_x = (int)run.GetPositions()[i * 2 + 2];
825 size_t index = run.GetGlyphToCharMap()[i];
828 for (
const char *str = this->
string; *str !=
'\0'; ) {
829 if (cur_idx == index)
return str;
831 WChar c = Utf8Consume(&str);
832 cur_idx += line->GetInternalCharLength(c);
846 FontColourMap::iterator it =
fonts[size].
Find(colour);
847 if (it !=
fonts[size].End())
return it->second;
849 Font *f =
new Font(size, colour);
850 fonts[size].emplace_back(colour, f);
860 for (
auto &pair :
fonts[size]) {
868 #if defined(WITH_UNISCRIBE)
869 UniscribeResetScriptCache(size);
871 #if defined(WITH_COCOA)
892 match != linecache->end()) {
893 return match->second;
898 key.state_before = state;
899 key.str.assign(str, len);
900 return (*linecache)[key];
uint32 GlyphID
Glyphs are characters from a font.
char32_t WChar
Type for wide characters, i.e.
FontSize GetSize() const
Get the FontSize of the font.
Dimensions (a width and height) of a rectangle in 2D.
const icu::ParagraphLayout::VisualRun * vr
The actual ICU vr.
void PopColour()
Switch to and pop the last saved colour on the stack.
static const bool SUPPORTS_RTL
Helper for GetLayouter, to get whether the layouter supports RTL.
static int8 Utf8CharLen(WChar c)
Return the length of a UTF-8 encoded character.
const char * string
Pointer to the original string.
static LineCache * linecache
Cache of ParagraphLayout lines.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Point GetCharPosition(const char *ch) const
Get the position of a character in the layout.
static void ResetFontCache(FontSize size)
Reset cached font information.
Helper class to construct a new FallbackParagraphLayout.
FallbackVisualRun(Font *font, const WChar *chars, int glyph_count, int x)
Create the visual run.
bool Insert(const T &key, const U &data)
Adds new item to this map.
FontMap & runs
The fonts we have to use for this paragraph.
Visual run contains data about the bit of text with the same font.
Interface to glue fallback and normal layouter into one.
Implementation of simple mapping class.
ParagraphLayouter * layout
Layout of the line.
static bool IsInsideMM(const T x, const size_t min, const size_t max)
Checks if a value is in an interval.
const WChar * buffer_begin
Begin of the buffer.
A single line worth of VisualRuns.
UChar CharType
Helper for GetLayouter, to get the right type.
int GetWidth() const override
Get the width of this line.
static const int DRAW_STRING_BUFFER
Size of the buffer used for drawing strings.
static FontColourMap fonts[FS_END]
Cache of Font instances.
const float * GetPositions() const override
Get the positions of this run.
void Reflow() override
Reset the position to the start of the paragraph.
static void GetLayouter(Layouter::LineCacheItem &line, const char *&str, FontState &state)
Helper for getting a ParagraphLayouter of the given type.
FontMap runs
Accessed by our ParagraphLayout::nextLine.
Visual run contains data about the bit of text with the same font.
FontSize fontsize
Current font size.
Dimension GetBounds()
Get the boundaries of this paragraph.
Layouter(const char *str, int maxw=INT32_MAX, TextColour colour=TC_FROMSTRING, FontSize fontsize=FS_NORMAL)
Create a new layouter.
GlyphID * glyphs
The glyphs we're drawing.
float * positions
The positions of the glyphs.
static Font * GetFont(FontSize size, TextColour colour)
Get a static font instance.
int GetGlyphCount() const override
Get the number of glyphs in this run.
int CountRuns() const override
Get the number of runs in this line.
static const bool SUPPORTS_RTL
Helper for GetLayouter, to get whether the layouter supports RTL.
~FallbackVisualRun() override
Free all data.
int GetLeading() const override
Get the height of this font.
Coordinates of a point in 2D.
const ParagraphLayouter::VisualRun & GetVisualRun(int run) const override
Get a specific visual run.
static size_t AppendToBuffer(WChar *buff, const WChar *buffer_last, WChar c)
Append a wide character to the internal buffer.
Class handling the splitting of a paragraph of text into lines and visual runs.
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
static void ReduceLineCache()
Reduce the size of linecache if necessary to prevent infinite growth.
Visual run contains data about the bit of text with the same font.
const int * GetGlyphToCharMap() const override
Get the glyph-to-character map for this visual run.
TextColour cur_colour
Current text colour.
Font cache for basic fonts.
const GlyphID * GetGlyphs() const override
Get the glyphs of this run.
int GetLeading() const override
Get the height of the line.
const char * GetCharAtPosition(int x) const
Get the character that is at a position.
int glyph_count
The number of glyphs.
void SetColour(TextColour c)
Switch to new colour c.
FontState state_after
Font state after the line.
icu::ParagraphLayout * p
The actual ICU paragraph layout.
static ParagraphLayouter * GetParagraphLayout(WChar *buff, WChar *buff_end, FontMap &fontMapping)
Get the actual ParagraphLayout for the given buffer.
static LineCacheItem & GetCachedParagraphLayout(const char *str, size_t len, const FontState &state)
Get reference to cache item.
A single line worth of VisualRuns.
Helper class to construct a new ICUParagraphLayout.
byte GetCharacterWidth(FontSize size, WChar key)
Return width of character glyph.
std::vector< Pair >::const_iterator Find(const T &key) const
Finds given key in this map.
#define Debug(name, level, format_string,...)
Ouptut a line of debugging information.
void SetFontSize(FontSize f)
Switch to using a new font f.
WChar CharType
Helper for GetLayouter, to get the right type.
Text drawing parameters, which can change while drawing a line, but are kept between multiple parts o...
Wrapper for doing layouts with ICU.
static void ResetLineCache()
Clear line cache.
static bool IsWhitespace(WChar c)
Check whether UNICODE character is whitespace or not, i.e.
void MacOSResetScriptCache(FontSize size)
Delete CoreText font reference for a specific font size.
FontSize
Available font sizes.
icu::ParagraphLayout::Line * l
The actual ICU line.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
A single line worth of VisualRuns.
const WChar * buffer
The current location in the buffer.
void PushColour()
Push the current colour on to the stack.
int * glyph_to_char
The char index of the glyphs.
@ TD_RTL
Text is written right-to-left by default.
TextDirection _current_text_dir
Text direction of the currently selected language.
void * buffer
Accessed by both ICU's and our ParagraphLayout::nextLine.
Font * font
The font used to layout these.
static bool IsTextDirectionChar(WChar c)
Is the given character a text direction character.
std::unique_ptr< const Line > NextLine(int max_width) override
Construct a new line with a maximum width.
FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs)
Create a new paragraph layouter.
const Font * GetFont() const override
Get the font associated with this run.
bool Contains(const T &key) const
Tests whether a key is assigned in this map.