#pragma once #include "fonts/face/font_face.hpp" #include "fonts/shaping/hb_shaper.hpp" #include "fonts/cache/glyph_cache.hpp" #include "fonts/pdf_fonts/font.hpp" #include "fonts/pdf_fonts/types/truetype_font.hpp" #include "fonts/pdf_fonts/types/type1_font.hpp" #include "fonts/pdf_fonts/types/cid_font.hpp" #include "fonts/pdf_fonts/font_loader.hpp" #include "fonts/pdf_fonts/encoding/encoding.hpp" #include "fonts/pdf_fonts/encoding/cjk_collection_db.hpp" #include "fonts/pdf_fonts/font_fallback.hpp" #include "fonts/pdf_fonts/font_subset.hpp" #include #include #include #include #include #include #include #include namespace { bool containsCI(const std::string& haystack, const std::string& needle) { auto it = std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end(), [](char a, char b) { return std::tolower(static_cast(a)) == std::tolower(static_cast(b)); }); return it != haystack.end(); } bool saveGlyphAsPGM(const pdfengine::fonts::GlyphBitmap& bitmap, const std::string& filename) { if (bitmap.width == 0 || bitmap.height == 0 || bitmap.pixels.empty()) { return false; } std::ofstream out(filename, std::ios::binary); if (!out) { return false; } out << "P5\n" << bitmap.width << " " << bitmap.height << "\n255\n"; out.write(reinterpret_cast(bitmap.pixels.data()), bitmap.pixels.size()); return true; } std::string getSystemFontPath() { #if defined(_WIN32) std::vector paths = { "C:\\Windows\\Fonts\\arial.ttf", "C:\\Windows\\Fonts\\consola.ttf", "C:\\Windows\\Fonts\\tahoma.ttf" }; #elif defined(__APPLE__) std::vector paths = { "/Library/Fonts/Arial.ttf", "/System/Library/Fonts/Geneva.ttf", "/System/Library/Fonts/Helvetica.ttc", "/System/Library/Fonts/Supplemental/Arial.ttf" }; #else std::vector paths = { "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", "/usr/share/fonts/truetype/freefont/FreeSans.ttf" }; #endif for (const auto& path : paths) { if (std::filesystem::exists(path)) { return path; } } return ""; } }