/* Copyright (C) 2026 Carl Hetherington This file is part of libttf. libttf is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libttf is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with libttf. If not, see . */ #define BOOST_TEST_MODULE libttf_test #include "collection.h" #include "font.h" #include "name_table.h" #include #include #include #include #include void check_file(boost::filesystem::path ref, boost::filesystem::path check) { uintmax_t size = boost::filesystem::file_size(ref); BOOST_CHECK_EQUAL(size, boost::filesystem::file_size(check)); boost::filesystem::ifstream ref_file(ref, std::ios::binary); BOOST_REQUIRE(ref_file.good()); boost::filesystem::ifstream check_file(check, std::ios::binary); BOOST_REQUIRE(check_file.good()); int constexpr buffer_size = 65536; std::vector ref_buffer(buffer_size); std::vector check_buffer(buffer_size); uintmax_t pos = 0; while (pos < size) { uintmax_t this_time = std::min(uintmax_t(buffer_size), size - pos); ref_file.read(reinterpret_cast(ref_buffer.data()), this_time); BOOST_CHECK(ref_file); check_file.read(reinterpret_cast(check_buffer.data()), this_time); BOOST_CHECK(check_file); if (memcmp(ref_buffer.data(), check_buffer.data(), this_time) != 0) { for (int i = 0; i < buffer_size; ++i) { if (ref_buffer[i] != check_buffer[i]) { BOOST_CHECK_MESSAGE ( false, "File " << check << " differs from reference " << ref << " at offset " << (pos + i) ); break; } } break; } pos += this_time; } } BOOST_AUTO_TEST_CASE(passthrough_test) { ttf::Font font("test/data/LiberationSans-Regular.ttf"); font.write("build/test/passthrough_test.ttf"); check_file("test/data/LiberationSans-Regular.ttf", "build/test/passthrough_test.ttf"); } BOOST_AUTO_TEST_CASE(get_names_test) { ttf::Font font("test/data/LiberationSans-Regular.ttf"); auto name_table = font.name_table(); BOOST_REQUIRE(name_table); auto font_family = name_table->names(ttf::NameTable::Identifier::FONT_FAMILY); BOOST_REQUIRE_EQUAL(font_family.size(), 2U); BOOST_CHECK_EQUAL(boost::variant2::get<0>(font_family[1]), "Liberation Sans"); auto full_name = name_table->names(ttf::NameTable::Identifier::FULL_NAME); BOOST_REQUIRE_EQUAL(full_name.size(), 2U); BOOST_CHECK_EQUAL(boost::variant2::get<0>(full_name[1]), "Liberation Sans"); auto postscript_name = name_table->names(ttf::NameTable::Identifier::POSTSCRIPT_NAME); BOOST_REQUIRE_EQUAL(postscript_name.size(), 2U); BOOST_CHECK_EQUAL(boost::variant2::get<0>(postscript_name[1]), "LiberationSans"); } BOOST_AUTO_TEST_CASE(set_names_test) { ttf::Font font("test/data/LiberationSans-Regular.ttf"); auto name_table = font.name_table(); BOOST_REQUIRE(name_table); name_table->set_names(ttf::NameTable::Identifier::FONT_FAMILY, "Adams", L"Adams"); name_table->set_names(ttf::NameTable::Identifier::FULL_NAME, "Frobozz", L"Frobozz"); name_table->set_names(ttf::NameTable::Identifier::POSTSCRIPT_NAME, "Pat", L"Pat"); font.write("build/test/set_names_test.ttf"); ttf::Font loaded("build/test/set_names_test.ttf"); auto loaded_name_table = loaded.name_table(); auto font_family = loaded_name_table->names(ttf::NameTable::Identifier::FONT_FAMILY); BOOST_CHECK_EQUAL(font_family.size(), 2U); BOOST_CHECK_EQUAL(boost::variant2::get<0>(font_family[1]), "Adams"); BOOST_CHECK(boost::variant2::get<1>(font_family[0]) == L"Adams"); auto full_name = loaded_name_table->names(ttf::NameTable::Identifier::FULL_NAME); BOOST_CHECK_EQUAL(full_name.size(), 2U); BOOST_CHECK_EQUAL(boost::variant2::get<0>(full_name[1]), "Frobozz"); BOOST_CHECK(boost::variant2::get<1>(full_name[0]) == L"Frobozz"); auto postscript_name = loaded_name_table->names(ttf::NameTable::Identifier::POSTSCRIPT_NAME); BOOST_CHECK_EQUAL(postscript_name.size(), 2U); BOOST_CHECK_EQUAL(boost::variant2::get<0>(postscript_name[1]), "Pat"); BOOST_CHECK(boost::variant2::get<1>(postscript_name[0]) == L"Pat"); } BOOST_AUTO_TEST_CASE(set_names_test2) { ttf::Font font("test/data/539c-fffe-768a-d2c7"); auto name_table = font.name_table(); BOOST_REQUIRE(name_table); name_table->set_names(ttf::NameTable::Identifier::FONT_FAMILY, "Arial_0", L"Arial_0"); auto font_family = name_table->names(ttf::NameTable::Identifier::FONT_FAMILY); BOOST_REQUIRE_EQUAL(font_family.size(), 3U); BOOST_CHECK(boost::variant2::get<1>(font_family[0]) == L"Arial_0"); BOOST_CHECK(boost::variant2::get<1>(font_family[1]) == L"Arial_0"); BOOST_CHECK_EQUAL(boost::variant2::get<0>(font_family[2]), "Arial_0"); } BOOST_AUTO_TEST_CASE(load_ttc_file) { BOOST_CHECK_THROW(ttf::Font("test/data/8fb0935f-28cd-4d8f-9ee9-85897c600364"), ttf::InvalidScalerType); ttf::Collection collection("test/data/8fb0935f-28cd-4d8f-9ee9-85897c600364"); auto fonts = collection.fonts(); BOOST_CHECK_EQUAL(fonts.size(), 9U); BOOST_REQUIRE(fonts[0].name_table()); auto const& table = fonts[0].name_table(); auto const font_family = table->names(ttf::NameTable::Identifier::FONT_FAMILY); BOOST_REQUIRE_EQUAL(font_family.size(), 2U); BOOST_CHECK_EQUAL(boost::variant2::get<0>(font_family[1]), "Arial Hebrew"); }