// SPDX-License-Identifier: GPL-2.0-or-later /* * Inkscape PaperSize * * Authors: * Bob Jamison (2006) * Martin Owens (2021) * * Copyright (C) 2021 AUTHORS * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #include #include "paper.h" #include "pages-skeleton.h" #include "io/resource.h" namespace Inkscape { /** * Returns a list of page sizes. */ const std::vector& PaperSize::getPageSizes() { // Static makes us only load pages once. static std::vector ret; if (!ret.empty()) return ret; char *path = Inkscape::IO::Resource::profile_path("pages.csv"); if (!g_file_test(path, G_FILE_TEST_EXISTS)) { if (!g_file_set_contents(path, pages_skeleton, -1, nullptr)) { g_warning("%s", _("Failed to create the page file.")); } } gchar *content = nullptr; if (g_file_get_contents(path, &content, nullptr, nullptr)) { gchar **lines = g_strsplit_set(content, "\n", 0); for (int i = 0; lines && lines[i]; ++i) { gchar **line = g_strsplit_set(lines[i], ",", 5); if (!line[0] || !line[1] || !line[2] || !line[3] || line[0][0]=='#') continue; //name, width, height, unit double width = g_ascii_strtod(line[1], nullptr); double height = g_ascii_strtod(line[2], nullptr); g_strstrip(line[0]); g_strstrip(line[3]); Glib::ustring name = line[0]; ret.push_back(PaperSize(name, width, height, Inkscape::Util::unit_table.getUnit(line[3]))); } g_strfreev(lines); g_free(content); } g_free(path); return ret; } PaperSize::PaperSize() : name("") , width(0.0) , height(0.0) { unit = Inkscape::Util::unit_table.getUnit("px"); } PaperSize::PaperSize(std::string name, double width, double height, Inkscape::Util::Unit const *unit) : name(std::move(name)) , width(width) , height(height) , unit(unit) {} std::string PaperSize::getDescription(bool landscape) const { return toDescription(name, size[landscape], size[!landscape], unit); } std::string PaperSize::toDescription(std::string name, double x, double y, Inkscape::Util::Unit const *unit) { return name + " (" + formatNumber(x) + " x " + formatNumber(y) + " " + unit->abbr + ")"; } std::string PaperSize::formatNumber(double val) { char buf[20]; snprintf(buf, 19, "%0.1f", val); auto ret = std::string(buf); // C++ doesn't provide a good number formatting control, so hack off trailing zeros. if ((ret.length() > 2) && (ret.back() == '0')) { ret = ret.substr(0, ret.length() - 2); } return ret; } void PaperSize::assign(const PaperSize &other) { name = other.name; width = other.width; height = other.height; auto [smaller, larger] = std::minmax(width, height); size = Geom::Point(smaller, larger); unit = other.unit; } /** * Returns a matching paper size, if possible. */ const PaperSize *PaperSize::findPaperSize(double width, double height, Inkscape::Util::Unit const *unit) { auto [smaller, larger] = std::minmax(width, height); auto size = Geom::Point(smaller, larger); auto px = Inkscape::Util::unit_table.getUnit("px"); for (auto&& page_size : Inkscape::PaperSize::getPageSizes()) { auto cmp = Geom::Point( unit->convert(size[0], page_size.unit), unit->convert(size[1], page_size.unit) ); // We want a half a pixel tollerance to catch floating point errors auto tollerance = px->convert(0.5, page_size.unit); if (Geom::are_near(page_size.size, cmp, tollerance)) { return &page_size; } } return nullptr; } } // namespace Inkscape /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :