Skip to content

Commit 6a63a40

Browse files
authored
Don't skip whitespace on single-line text (defold#5916)
* Don't skip whitespace on single-line text * Fix failing tests
1 parent 0ca6128 commit 6a63a40

File tree

3 files changed

+40
-20
lines changed

3 files changed

+40
-20
lines changed

Diff for: engine/render/src/render/font_renderer.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,11 @@ namespace dmRender
679679

680680
LayoutMetrics lm(font_map, tracking);
681681
float layout_width;
682-
int line_count = Layout(text, width, lines, max_lines, &layout_width, lm);
682+
// Whitespace characters should be ignored when rendering multiline text.
683+
// For single line text we still want to include whitespaces when the
684+
// text layout is calculated (https://github.com/defold/defold/issues/5911)
685+
bool skip_whitespace = te.m_LineBreak;
686+
int line_count = Layout(text, width, lines, max_lines, &layout_width, lm, skip_whitespace);
683687
float x_offset = OffsetX(te.m_Align, te.m_Width);
684688
float y_offset = OffsetY(te.m_VAlign, te.m_Height, font_map->m_MaxAscent, font_map->m_MaxDescent, te.m_Leading, line_count);
685689

@@ -1158,7 +1162,11 @@ namespace dmRender
11581162

11591163
LayoutMetrics lm(font_map, tracking * line_height);
11601164
float layout_width;
1161-
uint32_t num_lines = Layout(text, width, lines, max_lines, &layout_width, lm);
1165+
// Whitespace characters should be ignored for multiline text.
1166+
// For single line text we still want to include whitespaces in text
1167+
// metrics calculations (https://github.com/defold/defold/issues/5911)
1168+
bool skip_whitepace = line_break;
1169+
uint32_t num_lines = Layout(text, width, lines, max_lines, &layout_width, lm, skip_whitepace);
11621170
metrics->m_Width = layout_width;
11631171
metrics->m_Height = num_lines * (line_height * leading) - line_height * (leading - 1.0f);
11641172
}

Diff for: engine/render/src/render/font_renderer_private.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright 2020 The Defold Foundation
22
// Licensed under the Defold License version 1.0 (the "License"); you may not use
33
// this file except in compliance with the License.
4-
//
4+
//
55
// You may obtain a copy of the License, together with FAQs at
66
// https://www.defold.com/license
7-
//
7+
//
88
// Unless required by applicable law or agreed to in writing, software distributed
99
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
1010
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
@@ -64,7 +64,8 @@ namespace dmRender
6464
float width,
6565
TextLine* lines, uint16_t lines_count,
6666
float* text_width,
67-
Metric metrics)
67+
Metric metrics,
68+
bool skip_whitespace)
6869
{
6970
const char* cursor = str;
7071

@@ -90,7 +91,7 @@ namespace dmRender
9091
last_n = n-trim;
9192
last_w = w;
9293
last_cursor = cursor;
93-
if (c != '\n')
94+
if (c != '\n' && skip_whitespace)
9495
c = SkipWS(&cursor, &n);
9596
}
9697
else if (last_n != 0)

Diff for: engine/render/src/test/test_render.cpp

+25-14
Original file line numberDiff line numberDiff line change
@@ -474,85 +474,86 @@ static float Metric(const char* text, int n)
474474
TEST(dmFontRenderer, Layout)
475475
{
476476
const uint32_t lines_count = 256;
477+
const bool skip_whitespace = true;
477478
dmRender::TextLine lines[lines_count];
478479
int total_lines;
479480
const float char_width = 4;
480481
float w;
481-
total_lines = dmRender::Layout("", 100, lines, lines_count, &w, Metric);
482+
total_lines = dmRender::Layout("", 100, lines, lines_count, &w, Metric, skip_whitespace);
482483
ASSERT_EQ(0, total_lines);
483484
ASSERT_EQ(0, w);
484485

485-
total_lines = dmRender::Layout("x", 100, lines, lines_count, &w, Metric);
486+
total_lines = dmRender::Layout("x", 100, lines, lines_count, &w, Metric, skip_whitespace);
486487
ASSERT_EQ(1, total_lines);
487488
ASSERT_LINE(0, 1, lines, 0);
488489
ASSERT_EQ(char_width * 1, w);
489490

490-
total_lines = dmRender::Layout("x\x00 123", 100, lines, lines_count, &w, Metric);
491+
total_lines = dmRender::Layout("x\x00 123", 100, lines, lines_count, &w, Metric, skip_whitespace);
491492
ASSERT_EQ(1, total_lines);
492493
ASSERT_LINE(0, 1, lines, 0);
493494
ASSERT_EQ(char_width * 1, w);
494495

495-
total_lines = dmRender::Layout("x", 0, lines, lines_count, &w, Metric);
496+
total_lines = dmRender::Layout("x", 0, lines, lines_count, &w, Metric, skip_whitespace);
496497
ASSERT_EQ(1, total_lines);
497498
ASSERT_LINE(0, 1, lines, 0);
498499
ASSERT_EQ(char_width * 1, w);
499500

500-
total_lines = dmRender::Layout("foo", 3 * char_width, lines, lines_count, &w, Metric);
501+
total_lines = dmRender::Layout("foo", 3 * char_width, lines, lines_count, &w, Metric, skip_whitespace);
501502
ASSERT_EQ(1, total_lines);
502503
ASSERT_LINE(0, 3, lines, 0);
503504
ASSERT_EQ(char_width * 3, w);
504505

505-
total_lines = dmRender::Layout("foo", 3 * char_width - 1, lines, lines_count, &w, Metric);
506+
total_lines = dmRender::Layout("foo", 3 * char_width - 1, lines, lines_count, &w, Metric, skip_whitespace);
506507
ASSERT_EQ(1, total_lines);
507508
ASSERT_LINE(0, 3, lines, 0);
508509
ASSERT_EQ(char_width * 3, w);
509510

510-
total_lines = dmRender::Layout("foo bar", 3 * char_width, lines, lines_count, &w, Metric);
511+
total_lines = dmRender::Layout("foo bar", 3 * char_width, lines, lines_count, &w, Metric, skip_whitespace);
511512
ASSERT_EQ(2, total_lines);
512513
ASSERT_LINE(0, 3, lines, 0);
513514
ASSERT_LINE(4, 3, lines, 1);
514515
ASSERT_EQ(char_width * 3, w);
515516

516-
total_lines = dmRender::Layout("foo bar", 1000, lines, lines_count, &w, Metric);
517+
total_lines = dmRender::Layout("foo bar", 1000, lines, lines_count, &w, Metric, skip_whitespace);
517518
ASSERT_EQ(1, total_lines);
518519
ASSERT_LINE(0, 7, lines, 0);
519520
ASSERT_EQ(char_width * 7, w);
520521

521-
total_lines = dmRender::Layout("foo bar", 1000, lines, lines_count, &w, Metric);
522+
total_lines = dmRender::Layout("foo bar", 1000, lines, lines_count, &w, Metric, skip_whitespace);
522523
ASSERT_EQ(1, total_lines);
523524
ASSERT_LINE(0, 8, lines, 0);
524525
ASSERT_EQ(char_width * 8, w);
525526

526-
total_lines = dmRender::Layout("foo\n\nbar", 3 * char_width, lines, lines_count, &w, Metric);
527+
total_lines = dmRender::Layout("foo\n\nbar", 3 * char_width, lines, lines_count, &w, Metric, skip_whitespace);
527528
ASSERT_EQ(3, total_lines);
528529
ASSERT_LINE(0, 3, lines, 0);
529530
ASSERT_LINE(4, 0, lines, 1);
530531
ASSERT_LINE(5, 3, lines, 2);
531532
ASSERT_EQ(char_width * 3, w);
532533

533534
// 0x200B = Unicode "zero width space", UTF8 representation: E2 80 8B
534-
total_lines = dmRender::Layout("foo" "\xe2\x80\x8b" "bar", 3 * char_width, lines, lines_count, &w, Metric);
535+
total_lines = dmRender::Layout("foo" "\xe2\x80\x8b" "bar", 3 * char_width, lines, lines_count, &w, Metric, skip_whitespace);
535536
ASSERT_EQ(2, total_lines);
536537
ASSERT_LINE(0, 3, lines, 0);
537538
ASSERT_LINE(6, 3, lines, 1);
538539
ASSERT_EQ(char_width * 3, w);
539540

540541
// Note that second line would include a "zero width space" as first
541542
// character since we don't trim whitespace currently.
542-
total_lines = dmRender::Layout("foo" "\xe2\x80\x8b\xe2\x80\x8b" "bar", 3 * char_width, lines, lines_count, &w, Metric);
543+
total_lines = dmRender::Layout("foo" "\xe2\x80\x8b\xe2\x80\x8b" "bar", 3 * char_width, lines, lines_count, &w, Metric, skip_whitespace);
543544
ASSERT_EQ(2, total_lines);
544545
ASSERT_LINE(0, 3, lines, 0);
545546
ASSERT_LINE(6, 4, lines, 1);
546547
ASSERT_EQ(char_width * 4, w);
547548

548549
// åäö
549-
total_lines = dmRender::Layout("\xc3\xa5\xc3\xa4\xc3\xb6", 3 * char_width, lines, lines_count, &w, Metric);
550+
total_lines = dmRender::Layout("\xc3\xa5\xc3\xa4\xc3\xb6", 3 * char_width, lines, lines_count, &w, Metric, skip_whitespace);
550551
ASSERT_EQ(1, total_lines);
551552
ASSERT_EQ(char_width * 3, lines[0].m_Width);
552553
ASSERT_LINE(0, 3, lines, 0);
553554
ASSERT_EQ(char_width * 3, w);
554555

555-
total_lines = dmRender::Layout("Welcome to the Kingdom of Games...", 0, lines, lines_count, &w, Metric);
556+
total_lines = dmRender::Layout("Welcome to the Kingdom of Games...", 0, lines, lines_count, &w, Metric, skip_whitespace);
556557
ASSERT_EQ(6, total_lines);
557558
ASSERT_LINE(0, 7, lines, 0);
558559
ASSERT_LINE(8, 2, lines, 1);
@@ -621,6 +622,16 @@ TEST_F(dmRenderTest, GetTextMetrics)
621622
ASSERT_EQ(ExpectedHeight(lineheight, numlines, leading), metrics.m_Height);
622623
}
623624

625+
TEST_F(dmRenderTest, GetTextMetricsSkipWhitespace)
626+
{
627+
dmRender::TextMetrics metricsSingleLine;
628+
dmRender::TextMetrics metricsMultiLine;
629+
630+
dmRender::GetTextMetrics(m_SystemFontMap, "Hello ", 0, false, 1.0f, 0.0f, &metricsSingleLine);
631+
dmRender::GetTextMetrics(m_SystemFontMap, "Hello ", 0, true, 1.0f, 0.0f, &metricsMultiLine);
632+
ASSERT_NE(metricsMultiLine.m_Width, metricsSingleLine.m_Width);
633+
}
634+
624635
TEST_F(dmRenderTest, TextAlignment)
625636
{
626637
dmRender::TextMetrics metrics;

0 commit comments

Comments
 (0)