mirror of https://github.com/OpenTTD/OpenTTD.git
Codechange: Store text run positions in vector of points.
This simplifies the interlaced vector of x/y positions.
This commit is contained in:
parent
f7cc88f370
commit
ae575a7a5b
|
@ -21,6 +21,9 @@
|
|||
struct Point {
|
||||
int x;
|
||||
int y;
|
||||
|
||||
constexpr Point() : x(0), y(0) {}
|
||||
constexpr Point(int x, int y) : x(x), y(y) {}
|
||||
};
|
||||
|
||||
/** Dimensions (a width and height) of a rectangle in 2D */
|
||||
|
|
|
@ -599,9 +599,9 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
|||
/* Not a valid glyph (empty) */
|
||||
if (glyph == 0xFFFF) continue;
|
||||
|
||||
int begin_x = (int)positions[i * 2] + left - offset_x;
|
||||
int end_x = (int)positions[i * 2 + 2] + left - offset_x - 1;
|
||||
int top = (int)positions[i * 2 + 1] + y;
|
||||
int begin_x = positions[i].x + left - offset_x;
|
||||
int end_x = positions[i + 1].x + left - offset_x - 1;
|
||||
int top = positions[i].y + y;
|
||||
|
||||
/* Truncated away. */
|
||||
if (truncation && (begin_x < min_x || end_x > max_x)) continue;
|
||||
|
|
|
@ -260,8 +260,7 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
|
|||
for (int i = 0; i < run.GetGlyphCount(); i++) {
|
||||
/* Matching glyph? Return position. */
|
||||
if ((size_t)charmap[i] == index) {
|
||||
Point p = { (int)positions[i * 2], (int)positions[i * 2 + 1] };
|
||||
return p;
|
||||
return positions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -291,8 +290,8 @@ ptrdiff_t Layouter::GetCharAtPosition(int x, size_t line_index) const
|
|||
/* Not a valid glyph (empty). */
|
||||
if (glyphs[i] == 0xFFFF) continue;
|
||||
|
||||
int begin_x = (int)positions[i * 2];
|
||||
int end_x = (int)positions[i * 2 + 2];
|
||||
int begin_x = positions[i].x;
|
||||
int end_x = positions[i + 1].x;
|
||||
|
||||
if (IsInsideMM(x, begin_x, end_x)) {
|
||||
/* Found our glyph, now convert to UTF-8 string index. */
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
virtual const Font *GetFont() const = 0;
|
||||
virtual int GetGlyphCount() const = 0;
|
||||
virtual const std::vector<GlyphID> &GetGlyphs() const = 0;
|
||||
virtual const std::vector<float> &GetPositions() const = 0;
|
||||
virtual const std::vector<Point> &GetPositions() const = 0;
|
||||
virtual int GetLeading() const = 0;
|
||||
virtual const std::vector<int> &GetGlyphToCharMap() const = 0;
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
/** Visual run contains data about the bit of text with the same font. */
|
||||
class FallbackVisualRun : public ParagraphLayouter::VisualRun {
|
||||
std::vector<GlyphID> glyphs; ///< The glyphs we're drawing.
|
||||
std::vector<float> positions; ///< The positions of the glyphs.
|
||||
std::vector<Point> positions; ///< The positions of the glyphs.
|
||||
std::vector<int> glyph_to_char; ///< The char index of the glyphs.
|
||||
|
||||
Font *font; ///< The font used to layout these.
|
||||
|
@ -50,7 +50,7 @@ public:
|
|||
const Font *GetFont() const override { return this->font; }
|
||||
int GetGlyphCount() const override { return static_cast<int>(this->glyphs.size()); }
|
||||
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
|
||||
const std::vector<float> &GetPositions() const override { return this->positions; }
|
||||
const std::vector<Point> &GetPositions() const override { return this->positions; }
|
||||
int GetLeading() const override { return this->GetFont()->fc->GetHeight(); }
|
||||
const std::vector<int> &GetGlyphToCharMap() const override { return this->glyph_to_char; }
|
||||
};
|
||||
|
@ -118,21 +118,23 @@ FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const
|
|||
this->glyph_to_char.reserve(char_count);
|
||||
|
||||
/* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */
|
||||
this->positions.resize(char_count * 2 + 2);
|
||||
this->positions[0] = x;
|
||||
this->positions.reserve(char_count + 1);
|
||||
|
||||
int advance = x;
|
||||
for (int i = 0; i < char_count; i++) {
|
||||
const GlyphID &glyph_id = this->glyphs.emplace_back(font->fc->MapCharToGlyph(chars[i]));
|
||||
if (isbuiltin) {
|
||||
this->positions[2 * i + 1] = font->fc->GetAscender(); // Apply sprite font's ascender.
|
||||
this->positions.emplace_back(advance, font->fc->GetAscender()); // Apply sprite font's ascender.
|
||||
} else if (chars[i] >= SCC_SPRITE_START && chars[i] <= SCC_SPRITE_END) {
|
||||
this->positions[2 * i + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre
|
||||
this->positions.emplace_back(advance, (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2); // Align sprite font to centre
|
||||
} else {
|
||||
this->positions[2 * i + 1] = 0; // No ascender adjustment.
|
||||
this->positions.emplace_back(advance, 0); // No ascender adjustment.
|
||||
}
|
||||
this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(glyph_id);
|
||||
advance += font->fc->GetGlyphWidth(glyph_id);
|
||||
this->glyph_to_char.push_back(char_offset + i);
|
||||
}
|
||||
/* End-of-run position. */
|
||||
this->positions.emplace_back(advance, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,7 +165,7 @@ int FallbackParagraphLayout::FallbackLine::GetWidth() const
|
|||
* the last run gives us the end of the line and thus the width.
|
||||
*/
|
||||
const auto &run = this->GetVisualRun(this->CountRuns() - 1);
|
||||
return (int)run.GetPositions()[run.GetGlyphCount() * 2];
|
||||
return run.GetPositions().back().x;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
std::vector<GlyphID> glyphs; ///< The glyphs of the run. Valid after Shape() is called.
|
||||
std::vector<int> advance; ///< The advance (width) of the glyphs. Valid after Shape() is called.
|
||||
std::vector<int> glyph_to_char; ///< The mapping from glyphs to characters. Valid after Shape() is called.
|
||||
std::vector<float> positions; ///< The positions of the glyphs. Valid after Shape() is called.
|
||||
std::vector<Point> positions; ///< The positions of the glyphs. Valid after Shape() is called.
|
||||
int total_advance = 0; ///< The total advance of the run. Valid after Shape() is called.
|
||||
|
||||
ICURun(int start, int length, UBiDiLevel level, UScriptCode script = USCRIPT_UNKNOWN, Font *font = nullptr) : start(start), length(length), level(level), script(script), font(font) {}
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
class ICUVisualRun : public ParagraphLayouter::VisualRun {
|
||||
private:
|
||||
std::vector<GlyphID> glyphs;
|
||||
std::vector<float> positions;
|
||||
std::vector<Point> positions;
|
||||
std::vector<int> glyph_to_char;
|
||||
|
||||
int total_advance;
|
||||
|
@ -72,7 +72,7 @@ public:
|
|||
ICUVisualRun(const ICURun &run, int x);
|
||||
|
||||
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
|
||||
const std::vector<float> &GetPositions() const override { return this->positions; }
|
||||
const std::vector<Point> &GetPositions() const override { return this->positions; }
|
||||
const std::vector<int> &GetGlyphToCharMap() const override { return this->glyph_to_char; }
|
||||
|
||||
const Font *GetFont() const override { return this->font; }
|
||||
|
@ -135,16 +135,9 @@ ICUParagraphLayout::ICUVisualRun::ICUVisualRun(const ICURun &run, int x) :
|
|||
assert(!run.positions.empty());
|
||||
this->positions.reserve(run.positions.size());
|
||||
|
||||
/* "positions" is an array of x/y. So we need to alternate. */
|
||||
bool is_x = true;
|
||||
for (auto &position : run.positions) {
|
||||
if (is_x) {
|
||||
this->positions.push_back(position + x);
|
||||
} else {
|
||||
this->positions.push_back(position);
|
||||
}
|
||||
|
||||
is_x = !is_x;
|
||||
/* Copy positions, moving x coordinate by x offset. */
|
||||
for (const Point &pt : run.positions) {
|
||||
this->positions.emplace_back(pt.x + x, pt.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +179,7 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
|
|||
/* Reserve space, as we already know the size. */
|
||||
this->glyphs.reserve(glyph_count);
|
||||
this->glyph_to_char.reserve(glyph_count);
|
||||
this->positions.reserve(glyph_count * 2 + 2);
|
||||
this->positions.reserve(glyph_count + 1);
|
||||
this->advance.reserve(glyph_count);
|
||||
|
||||
/* Prepare the glyphs/position. ICUVisualRun will give the position an offset if needed. */
|
||||
|
@ -198,13 +191,11 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
|
|||
auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]);
|
||||
|
||||
this->glyphs.push_back(glyph);
|
||||
this->positions.push_back(advance);
|
||||
this->positions.push_back((this->font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->font->fc->GetSize()))) / 2); // Align sprite font to centre
|
||||
this->positions.emplace_back(advance, (this->font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->font->fc->GetSize()))) / 2); // Align sprite font to centre
|
||||
x_advance = this->font->fc->GetGlyphWidth(glyph);
|
||||
} else {
|
||||
this->glyphs.push_back(glyph_info[i].codepoint);
|
||||
this->positions.push_back(glyph_pos[i].x_offset / FONT_SCALE + advance);
|
||||
this->positions.push_back(glyph_pos[i].y_offset / FONT_SCALE);
|
||||
this->positions.emplace_back(glyph_pos[i].x_offset / FONT_SCALE + advance, glyph_pos[i].y_offset / FONT_SCALE);
|
||||
x_advance = glyph_pos[i].x_advance / FONT_SCALE;
|
||||
}
|
||||
|
||||
|
@ -213,9 +204,8 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
|
|||
advance += x_advance;
|
||||
}
|
||||
|
||||
/* Position has one more element to close off the array. */
|
||||
this->positions.push_back(advance);
|
||||
this->positions.push_back(0);
|
||||
/* End-of-run position. */
|
||||
this->positions.emplace_back(advance, 0);
|
||||
|
||||
/* Track the total advancement we made. */
|
||||
this->total_advance = advance;
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
class CoreTextVisualRun : public ParagraphLayouter::VisualRun {
|
||||
private:
|
||||
std::vector<GlyphID> glyphs;
|
||||
std::vector<float> positions;
|
||||
std::vector<Point> positions;
|
||||
std::vector<int> glyph_to_char;
|
||||
|
||||
int total_advance = 0;
|
||||
|
@ -82,7 +82,7 @@ public:
|
|||
CoreTextVisualRun(CoreTextVisualRun &&other) = default;
|
||||
|
||||
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
|
||||
const std::vector<float> &GetPositions() const override { return this->positions; }
|
||||
const std::vector<Point> &GetPositions() const override { return this->positions; }
|
||||
const std::vector<int> &GetGlyphToCharMap() const override { return this->glyph_to_char; }
|
||||
|
||||
const Font *GetFont() const override { return this->font; }
|
||||
|
@ -240,7 +240,7 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font
|
|||
|
||||
CGPoint pts[this->glyphs.size()];
|
||||
CTRunGetPositions(run, CFRangeMake(0, 0), pts);
|
||||
this->positions.resize(this->glyphs.size() * 2 + 2);
|
||||
this->positions.reserve(this->glyphs.size() + 1);
|
||||
|
||||
/* Convert glyph array to our data type. At the same time, substitute
|
||||
* the proper glyphs for our private sprite glyphs. */
|
||||
|
@ -250,16 +250,15 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font
|
|||
if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END && (gl[i] == 0 || gl[i] == 3)) {
|
||||
/* A glyph of 0 indidicates not found, while apparently 3 is what char 0xFFFC maps to. */
|
||||
this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]);
|
||||
this->positions[i * 2 + 0] = pts[i].x;
|
||||
this->positions[i * 2 + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre
|
||||
this->positions.emplace_back(pts[i].x, (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2); // Align sprite font to centre
|
||||
} else {
|
||||
this->glyphs[i] = gl[i];
|
||||
this->positions[i * 2 + 0] = pts[i].x;
|
||||
this->positions[i * 2 + 1] = pts[i].y;
|
||||
this->positions.emplace_back(pts[i].x, pts[i].y);
|
||||
}
|
||||
}
|
||||
this->total_advance = (int)std::ceil(CTRunGetTypographicBounds(run, CFRangeMake(0, 0), nullptr, nullptr, nullptr));
|
||||
this->positions[this->glyphs.size() * 2] = this->positions[0] + this->total_advance;
|
||||
/* End-of-run position. */
|
||||
this->positions.emplace_back(this->positions.front().x + this->total_advance, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
class UniscribeVisualRun : public ParagraphLayouter::VisualRun {
|
||||
private:
|
||||
std::vector<GlyphID> glyphs;
|
||||
std::vector<float> positions;
|
||||
std::vector<Point> positions;
|
||||
std::vector<WORD> char_to_glyph;
|
||||
|
||||
int start_pos;
|
||||
|
@ -89,7 +89,7 @@ public:
|
|||
UniscribeVisualRun(UniscribeVisualRun &&other) noexcept;
|
||||
|
||||
const std::vector<GlyphID> &GetGlyphs() const override { return this->glyphs; }
|
||||
const std::vector<float> &GetPositions() const override { return this->positions; }
|
||||
const std::vector<Point> &GetPositions() const override { return this->positions; }
|
||||
const std::vector<int> &GetGlyphToCharMap() const override;
|
||||
|
||||
const Font *GetFont() const override { return this->font; }
|
||||
|
@ -474,16 +474,16 @@ int UniscribeParagraphLayout::UniscribeLine::GetWidth() const
|
|||
UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(const UniscribeRun &range, int x) : glyphs(range.ft_glyphs), char_to_glyph(range.char_to_glyph), start_pos(range.pos), total_advance(range.total_advance), font(range.font)
|
||||
{
|
||||
this->num_glyphs = (int)glyphs.size();
|
||||
this->positions.resize(this->num_glyphs * 2 + 2);
|
||||
this->positions.reserve(this->num_glyphs + 1);
|
||||
|
||||
int advance = 0;
|
||||
int advance = x;
|
||||
for (int i = 0; i < this->num_glyphs; i++) {
|
||||
this->positions[i * 2 + 0] = range.offsets[i].du + advance + x;
|
||||
this->positions[i * 2 + 1] = range.offsets[i].dv;
|
||||
this->positions.emplace_back(range.offsets[i].du + advance, range.offsets[i].dv);
|
||||
|
||||
advance += range.advances[i];
|
||||
}
|
||||
this->positions[this->num_glyphs * 2] = advance + x;
|
||||
/* End-of-run position. */
|
||||
this->positions.emplace_back(advance, 0);
|
||||
}
|
||||
|
||||
UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(UniscribeVisualRun&& other) noexcept
|
||||
|
|
Loading…
Reference in New Issue