Changeset - r28511:2d7264916867
[Not reviewed]
master
0 8 0
Peter Nelson - 3 months ago 2024-01-18 21:06:43
peter1138@openttd.org
Codechange: Store text run positions in vector of points.

This simplifies the interlaced vector of x/y positions.
8 files changed with 46 insertions and 53 deletions:
0 comments (0 inline, 0 general)
src/core/geometry_type.hpp
Show inline comments
 
@@ -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 */
src/gfx.cpp
Show inline comments
 
@@ -599,9 +599,9 @@ static int DrawLayoutLine(const Paragrap
 
			/* 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;
src/gfx_layout.cpp
Show inline comments
 
@@ -260,8 +260,7 @@ Point Layouter::GetCharPosition(std::str
 
		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(in
 
			/* 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. */
src/gfx_layout.h
Show inline comments
 
@@ -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;
 
	};
src/gfx_layout_fallback.cpp
Show inline comments
 
@@ -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::FallbackVisualR
 
	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::FallbackLin
 
	 * 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;
 
}
 

	
 
/**
src/gfx_layout_icu.cpp
Show inline comments
 
@@ -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::ICUVis
 
	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 b
 
	/* 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 b
 
			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 b
 
		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;
src/os/macosx/string_osx.cpp
Show inline comments
 
@@ -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::CoreTextVisualR
 

	
 
	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::CoreTextVisualR
 
		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);
 
}
 

	
 
/**
src/os/windows/string_uniscribe.cpp
Show inline comments
 
@@ -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::UniscribeL
 
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
0 comments (0 inline, 0 general)