Skip to content

Commit c8f2697

Browse files
committed
Canvas::draw_text functions now return a Rectf of the drawn text area
1 parent b7f9a47 commit c8f2697

File tree

7 files changed

+61
-47
lines changed

7 files changed

+61
-47
lines changed

src/video/bitmap_font.cpp

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -356,41 +356,47 @@ BitmapFont::wrap_to_width(const std::string& s_, float width, std::string* overf
356356
}
357357

358358

359-
void
359+
Rectf
360360
BitmapFont::draw_text(Canvas& canvas, const std::string& text,
361-
const Vector& pos_, FontAlignment alignment, int layer, const Color& color)
361+
const Vector& pos, FontAlignment alignment, int layer, const Color& color)
362362
{
363-
float x = pos_.x;
364-
float y = pos_.y;
363+
float min_x = pos.x;
364+
float last_y = pos.y;
365+
float max_width = 0.f;
365366

366367
std::string::size_type last = 0;
367-
for (std::string::size_type i = 0;; ++i)
368+
for (std::string::size_type i = 0; i <= text.size(); ++i)
368369
{
369-
if (text[i] == '\n' || i == text.size())
370-
{
371-
std::string temp = text.substr(last, i - last);
370+
if (i != text.size() && text[i] != '\n')
371+
continue;
372372

373-
// Calculate X positions based on the alignment type.
374-
Vector pos = Vector(x, y);
373+
const std::string temp = text.substr(last, i - last);
374+
const float width = get_text_width(temp);
375375

376-
if (alignment == ALIGN_CENTER)
377-
pos.x -= get_text_width(temp) / 2;
378-
else if (alignment == ALIGN_RIGHT)
379-
pos.x -= get_text_width(temp);
376+
// Calculate X positions based on the alignment type.
377+
Vector new_pos = Vector(pos.x, last_y);
380378

381-
// Cast font position to integer to get a clean drawing result and
382-
// no blurring as we would get with subpixel positions.
383-
pos.x = std::truncf(pos.x);
379+
if (alignment == ALIGN_CENTER)
380+
new_pos.x -= width / 2.0f;
381+
else if (alignment == ALIGN_RIGHT)
382+
new_pos.x -= width;
384383

385-
draw_text(canvas, temp, pos, layer, color);
384+
// Cast font position to integer to get a clean drawing result and
385+
// no blurring as we would get with subpixel positions.
386+
new_pos.x = std::truncf(new_pos.x);
386387

387-
if (i == text.size())
388-
break;
388+
if (new_pos.x < min_x)
389+
min_x = new_pos.x;
390+
if (width > max_width)
391+
max_width = width;
389392

390-
y += static_cast<float>(char_height) + 2.0f;
391-
last = i + 1;
392-
}
393+
draw_text(canvas, temp, new_pos, layer, color);
394+
395+
last_y += static_cast<float>(char_height) + 2.0f;
396+
last = i + 1;
393397
}
398+
399+
return Rectf(min_x, pos.y, min_x + max_width, last_y);
394400
}
395401

396402
void

src/video/bitmap_font.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ class BitmapFont final : public Font
7272
*/
7373
virtual std::string wrap_to_width(const std::string& text, float width, std::string* overflow) override;
7474

75-
virtual void draw_text(Canvas& canvas, const std::string& text,
76-
const Vector& pos, FontAlignment alignment, int layer, const Color& color) override;
75+
virtual Rectf draw_text(Canvas& canvas, const std::string& text,
76+
const Vector& pos, FontAlignment alignment, int layer, const Color& color) override;
7777

7878
private:
7979
friend class DrawingContext;

src/video/canvas.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,20 +227,20 @@ Canvas::draw_surface_batch(const SurfacePtr& surface,
227227
m_requests.push_back(request);
228228
}
229229

230-
void
230+
Rectf
231231
Canvas::draw_text(const FontPtr& font, const std::string& text,
232232
const Vector& pos, FontAlignment alignment, int layer, const Color& color)
233233
{
234234
// FIXME: Font viewport.
235-
font->draw_text(*this, text, pos, alignment, layer, color);
235+
return font->draw_text(*this, text, pos, alignment, layer, color);
236236
}
237237

238-
void
238+
Rectf
239239
Canvas::draw_center_text(const FontPtr& font, const std::string& text,
240240
const Vector& position, int layer, const Color& color)
241241
{
242-
draw_text(font, text, Vector(position.x + static_cast<float>(m_context.get_width()) / 2.0f, position.y),
243-
ALIGN_CENTER, layer, color);
242+
return draw_text(font, text, Vector(position.x + static_cast<float>(m_context.get_width()) / 2.0f, position.y),
243+
ALIGN_CENTER, layer, color);
244244
}
245245

246246
void

src/video/canvas.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ class Canvas final
6767
std::vector<float> angles,
6868
const Color& color,
6969
int layer);
70-
void draw_text(const FontPtr& font, const std::string& text,
71-
const Vector& position, FontAlignment alignment, int layer, const Color& color = Color(1.0,1.0,1.0));
70+
Rectf draw_text(const FontPtr& font, const std::string& text,
71+
const Vector& position, FontAlignment alignment, int layer, const Color& color = Color(1.0,1.0,1.0));
7272
/** Draw text to the center of the screen */
73-
void draw_center_text(const FontPtr& font, const std::string& text,
74-
const Vector& position, int layer, const Color& color = Color(1.0,1.0,1.0));
73+
Rectf draw_center_text(const FontPtr& font, const std::string& text,
74+
const Vector& position, int layer, const Color& color = Color(1.0,1.0,1.0));
7575
void draw_gradient(const Color& from, const Color& to, int layer, const GradientDirection& direction,
7676
const Rectf& region, const Blend& blend = Blend());
7777
void draw_filled_rect(const Rectf& rect, const Color& color, int layer);

src/video/font.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ class Font
5252

5353
virtual std::string wrap_to_width(const std::string& text, float width, std::string* overflow) = 0;
5454

55-
virtual void draw_text(Canvas& canvas, const std::string& text,
56-
const Vector& pos, FontAlignment alignment, int layer, const Color& color) = 0;
55+
virtual Rectf draw_text(Canvas& canvas, const std::string& text,
56+
const Vector& pos, FontAlignment alignment, int layer, const Color& color) = 0;
5757
};
5858

5959
#endif

src/video/ttf_font.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,14 @@ TTFFont::get_text_height(const std::string& text) const
9898
});
9999
}
100100

101-
void
101+
Rectf
102102
TTFFont::draw_text(Canvas& canvas, const std::string& text,
103103
const Vector& pos, FontAlignment alignment, int layer, const Color& color)
104104

105105
{
106+
float min_x = pos.x;
106107
float last_y = pos.y - (static_cast<float>(TTF_FontHeight(m_font)) - get_height()) / 2.0f;
108+
float max_width = 0.f;
107109

108110
LineIterator iter(text);
109111
while (iter.next())
@@ -113,24 +115,30 @@ TTFFont::draw_text(Canvas& canvas, const std::string& text,
113115
if (!line.empty())
114116
{
115117
TTFSurfacePtr ttf_surface = TTFSurfaceManager::current()->create_surface(*this, line);
118+
const float width = static_cast<float>(ttf_surface->get_width());
116119

117120
Vector new_pos(pos.x, last_y);
118121

119122
if (alignment == ALIGN_CENTER)
120-
{
121-
new_pos.x -= static_cast<float>(ttf_surface->get_width()) / 2.0f;
122-
}
123+
new_pos.x -= width / 2.0f;
123124
else if (alignment == ALIGN_RIGHT)
124-
{
125-
new_pos.x -= static_cast<float>(ttf_surface->get_width());
126-
}
125+
new_pos.x -= width;
126+
127+
new_pos = glm::floor(new_pos);
127128

128-
// draw text
129-
canvas.draw_surface(ttf_surface->get_surface(), glm::floor(new_pos), 0.0f, color, Blend(), layer);
129+
if (new_pos.x < min_x)
130+
min_x = new_pos.x;
131+
if (width > max_width)
132+
max_width = width;
133+
134+
// Draw text surface
135+
canvas.draw_surface(ttf_surface->get_surface(), new_pos, 0.0f, color, Blend(), layer);
130136
}
131137

132138
last_y += get_height();
133139
}
140+
141+
return Rectf(min_x, pos.y, min_x + max_width, last_y);
134142
}
135143

136144
std::string

src/video/ttf_font.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ class TTFFont final : public Font
4646

4747
virtual std::string wrap_to_width(const std::string& text, float width, std::string* overflow) override;
4848

49-
virtual void draw_text(Canvas& canvas, const std::string& text,
50-
const Vector& pos, FontAlignment alignment, int layer, const Color& color) override;
49+
virtual Rectf draw_text(Canvas& canvas, const std::string& text,
50+
const Vector& pos, FontAlignment alignment, int layer, const Color& color) override;
5151

5252
int get_shadow_size() const { return m_shadow_size; }
5353
int get_border() const { return m_border; }

0 commit comments

Comments
 (0)