Add Chromium-only Blender WebEngine parity work
This commit is contained in:
468
blender-5.2.0/source/blender/blenfont/tests/BLF_tests.cc
Normal file
468
blender-5.2.0/source/blender/blenfont/tests/BLF_tests.cc
Normal file
@@ -0,0 +1,468 @@
|
||||
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#include "BLF_api.hh"
|
||||
|
||||
#include "BLI_path_utils.hh"
|
||||
|
||||
#include "BKE_gtest_base.hh"
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
namespace blender::tests {
|
||||
|
||||
static std::string font_path(std::string font_name)
|
||||
{
|
||||
char path[FILE_MAX];
|
||||
BLI_path_join(
|
||||
path, sizeof(path), tests::flags_test_asset_dir().c_str(), "blenfont", font_name.c_str());
|
||||
return std::string(path);
|
||||
}
|
||||
|
||||
static int open_font(std::string font_name)
|
||||
{
|
||||
BLF_init();
|
||||
return BLF_load(font_path(font_name).c_str());
|
||||
}
|
||||
|
||||
static void close_font(int id)
|
||||
{
|
||||
BLF_unload_id(id);
|
||||
BLF_exit();
|
||||
}
|
||||
|
||||
class BlfLoadTest : public bke::BlenderGTestBase {};
|
||||
|
||||
TEST_F(BlfLoadTest, load)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
EXPECT_TRUE(id != -1);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfLoadTest, font_is_loaded_path)
|
||||
{
|
||||
BLF_init();
|
||||
std::string path = font_path("Ahem.ttf");
|
||||
const int id = BLF_load(path.c_str());
|
||||
EXPECT_TRUE(BLF_is_loaded(path.c_str()));
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfLoadTest, font_is_loaded_id)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
EXPECT_TRUE(BLF_is_loaded_id(id));
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfLoadTest, display_name_from_file)
|
||||
{
|
||||
std::string path = font_path("Ahem.ttf");
|
||||
const char *name = BLF_display_name_from_file(path.c_str());
|
||||
EXPECT_TRUE(STREQ(name, "Ahem Regular"));
|
||||
/* BLF_display_name result must be freed. */
|
||||
MEM_delete(name);
|
||||
}
|
||||
|
||||
TEST_F(BlfLoadTest, display_name_from_id)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
const char *name = BLF_display_name_from_id(id);
|
||||
EXPECT_TRUE(STREQ(name, "Ahem Regular"));
|
||||
/* BLF_display_name result must be freed. */
|
||||
MEM_delete(name);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfLoadTest, has_glyph)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
const bool has_glyph = BLF_has_glyph(id, 0x0058); /* 'X' */
|
||||
EXPECT_TRUE(has_glyph);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
class BlfMetricsTest : public bke::BlenderGTestBase {};
|
||||
|
||||
TEST_F(BlfMetricsTest, get_vfont_metrics)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
float ascend_ratio = 0.0f;
|
||||
float em_ratio = 0.0f;
|
||||
float scale = 0.0f;
|
||||
const bool has_metrics = BLF_get_vfont_metrics(id, &ascend_ratio, &em_ratio, &scale);
|
||||
EXPECT_TRUE(has_metrics);
|
||||
EXPECT_TRUE(ascend_ratio == 0.8f);
|
||||
EXPECT_TRUE(em_ratio == 1.0f);
|
||||
EXPECT_TRUE(scale == 0.001f);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfMetricsTest, default_weight)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
const int weight = BLF_default_weight(id);
|
||||
EXPECT_TRUE(weight == 400);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfMetricsTest, has_variable_weight)
|
||||
{
|
||||
const int id = open_font("Roboto.ttf");
|
||||
const bool has_variable_weight = BLF_has_variable_weight(id);
|
||||
EXPECT_TRUE(has_variable_weight);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfMetricsTest, variable_weight)
|
||||
{
|
||||
const int id = open_font("Roboto.ttf");
|
||||
const char sample[] = "MM";
|
||||
BLF_size(id, 100.0f);
|
||||
BLF_character_weight(id, 300);
|
||||
const float width_thin = BLF_width(id, sample, sizeof(sample));
|
||||
BLF_character_weight(id, 600);
|
||||
const float width_wide = BLF_width(id, sample, sizeof(sample));
|
||||
EXPECT_TRUE(width_wide > width_thin);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
class BlfDimensionsTest : public bke::BlenderGTestBase {};
|
||||
|
||||
TEST_F(BlfDimensionsTest, width_max)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const int width = BLF_width_max(id);
|
||||
EXPECT_TRUE(width == 100.0f);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfDimensionsTest, height_max)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const int height = BLF_height_max(id);
|
||||
EXPECT_TRUE(height == 100.0f);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfDimensionsTest, descender)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const int descender = BLF_descender(id);
|
||||
EXPECT_TRUE(descender == -20);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfDimensionsTest, ascender)
|
||||
{
|
||||
const int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const int ascender = BLF_ascender(id);
|
||||
EXPECT_TRUE(ascender == 80);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfDimensionsTest, fixed_width)
|
||||
{
|
||||
/* Ahem does not have all the characters needed for calculation. */
|
||||
const int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const float width = BLF_fixed_width(id);
|
||||
EXPECT_TRUE(width == 56.0f);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfDimensionsTest, width_em)
|
||||
{
|
||||
/* In this test font, 'X' is exactly one em wide. */
|
||||
const char sample[] = "XX";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
EXPECT_TRUE(width == 200.0f);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfDimensionsTest, height_em)
|
||||
{
|
||||
/* In this test font, 'X' is exactly one em high. */
|
||||
const char sample[] = "X";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const float width = BLF_height(id, sample, sizeof(sample));
|
||||
EXPECT_TRUE(width == 100.0f);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfDimensionsTest, advance)
|
||||
{
|
||||
/* In this test font, 'X' has advance of exactly one em. */
|
||||
const char sample[] = "X";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 100.0f);
|
||||
const float width = BLF_glyph_advance(id, sample);
|
||||
EXPECT_NEAR(width, 100.0f, 0.000001f);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
class BlfWrappingMinimalTest : public bke::BlenderGTestBase {};
|
||||
|
||||
TEST_F(BlfWrappingMinimalTest, wrap_overflow_ascii)
|
||||
{
|
||||
/* Do not break, even though over the wrap limit. */
|
||||
const char sample[] =
|
||||
"xxxxxxxxxxxxxxxxxxx!\"#$%&\'()*+,-./"
|
||||
"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
/* Ahem does not contain all the characters included in above string. */
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(id, sample, int(float(width) * 0.05f));
|
||||
EXPECT_TRUE(wrapped.size() == 1);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingMinimalTest, wrap_space)
|
||||
{
|
||||
/* Must break at the center spaces into two, one space trailing, one leading. */
|
||||
const char sample[] = "x xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx ";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(id, sample, int(float(width) * 0.7f));
|
||||
EXPECT_TRUE(wrapped.size() == 2 && wrapped[0].back() == ' ' && wrapped[1].substr(0, 1) != " ");
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingMinimalTest, wrap_linefeed)
|
||||
{
|
||||
/* Must break on every line feed except at end of string. */
|
||||
const char sample[] = "x\nxxxxxxxxxxxxxxxx\n\nxxxxxxxxxxxxxxxxxxx\n";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(id, sample, int(float(width) * 0.7f));
|
||||
EXPECT_TRUE(wrapped.size() == 4 && wrapped[2].is_empty());
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingMinimalTest, wrap_hardlimit)
|
||||
{
|
||||
/* Must break at limit. */
|
||||
const char sample[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::HardLimit);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
class BlfWrappingPathTest : public bke::BlenderGTestBase {};
|
||||
|
||||
TEST_F(BlfWrappingPathTest, wrap_path_overflow_ascii)
|
||||
{
|
||||
/* Do not break, even though over the wrap limit. */
|
||||
const char sample[] =
|
||||
"xxxxxxxxxxxxxxxxxxx!\"#$\'()*+,"
|
||||
"0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^`abcdefghijklmnopqrstuvwxyz{|}~";
|
||||
/* Ahem does not contain all the characters included in above string. */
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.05f), BLFWrapMode::Path);
|
||||
EXPECT_TRUE(wrapped.size() == 1);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingPathTest, wrap_path_space)
|
||||
{
|
||||
/* Must break at the center space. */
|
||||
const char sample[] = "x xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx ";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Path);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingPathTest, wrap_path_separators_underscore)
|
||||
{
|
||||
/* Must break at middle underscore. */
|
||||
int id = open_font("Roboto.ttf");
|
||||
/* Ahem does not contain all the characters included in tested string. */
|
||||
BLF_size(id, 10.0f);
|
||||
const char sample[] = "x_xx_xxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxx_";
|
||||
float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Path);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingPathTest, wrap_path_separators_slash)
|
||||
{
|
||||
/* Wrap at backslash path separators. */
|
||||
int id = open_font("Roboto.ttf");
|
||||
/* Ahem does not contain all the characters included in tested string. */
|
||||
BLF_size(id, 10.0f);
|
||||
const char sample[] = "xxxxxxxxxx" SEP_STR "xxxxxxxxxxxxxxxxxxxxxx";
|
||||
float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Path);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingPathTest, wrap_path_hardlimit)
|
||||
{
|
||||
/* Must break at limit. */
|
||||
const char sample[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Path | BLFWrapMode::HardLimit);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
class BlfWrappingTypographicalTest : public bke::BlenderGTestBase {};
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_thinspace)
|
||||
{
|
||||
/* Must break at thinspace. */
|
||||
const char sample[] = "xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_backslash)
|
||||
{
|
||||
/* Optional break at any backslash. */
|
||||
const char sample[] = "xxxxxxxxxxx\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_underscore)
|
||||
{
|
||||
/* Optional break at any underscore. */
|
||||
const char sample[] = "xxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_forward_slash)
|
||||
{
|
||||
/* Do not break on solidus if previous is a number. */
|
||||
const char sample[] = "xxxxxxxxxxxxxx/xx3/xxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical);
|
||||
EXPECT_TRUE(wrapped.size() == 2 && wrapped[0].back() != '3');
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_dash)
|
||||
{
|
||||
/* Do not break on dash, hyphen, em dash if previous is space. */
|
||||
const char sample[] = "xxxxxxxxxxxxxx-xx /xxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical);
|
||||
EXPECT_TRUE(wrapped.size() == 2 && wrapped[0].back() != ' ');
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_CJK)
|
||||
{
|
||||
/* Do not break on dash, hyphen, em dash if previous is space. */
|
||||
const char sample[] =
|
||||
"xxxxxxxxxxxxxx"
|
||||
"断"
|
||||
"xxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_Tibetan)
|
||||
{
|
||||
/* Do not break on dash, hyphen, em dash if previous is space. */
|
||||
const char sample[] =
|
||||
"xxxxxxxxxxxxxx"
|
||||
"།"
|
||||
"xxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Roboto.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingTypographicalTest, wrap_typographical_hardlimit)
|
||||
{
|
||||
/* Must break at limit. */
|
||||
const char sample[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
int id = open_font("Ahem.ttf");
|
||||
BLF_size(id, 10.0f);
|
||||
const float width = BLF_width(id, sample, sizeof(sample));
|
||||
Vector<StringRef> wrapped = BLF_string_wrap(
|
||||
id, sample, int(float(width) * 0.7f), BLFWrapMode::Typographical | BLFWrapMode::HardLimit);
|
||||
EXPECT_TRUE(wrapped.size() == 2);
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
TEST_F(BlfWrappingMinimalTest, wrap_hardlimit_too_narrow_width)
|
||||
{
|
||||
/* Must break for each character. */
|
||||
const char sample[] = "aeiouáéíóú ;'/./\n\n1234567890-=";
|
||||
int id = open_font("Ahem.ttf");
|
||||
const Vector<StringRef> expected_wrap = {
|
||||
"a", "e", "i", "o", "u", "á", "é", "í", "ó", "ú", " ", ";", "\'", "/", ".",
|
||||
"/", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=",
|
||||
};
|
||||
for (float size : {0.1f, 1.0f, 5.0f, 10.0f}) {
|
||||
BLF_size(id, size);
|
||||
const Vector<StringRef> wrapped = BLF_string_wrap(id, sample, 0, BLFWrapMode::HardLimit);
|
||||
EXPECT_EQ(wrapped, expected_wrap);
|
||||
}
|
||||
close_font(id);
|
||||
}
|
||||
|
||||
} // namespace blender::tests
|
||||
Reference in New Issue
Block a user