Serenity Operating System
at master 92 lines 3.1 kB view raw
1/* 2 * Copyright (c) 2022, Matthew Olsson <mattco@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/String.h> 8#include <AK/StringView.h> 9#include <LibGfx/Font/FontDatabase.h> 10#include <LibPDF/CommonNames.h> 11#include <LibPDF/Fonts/PDFFont.h> 12#include <LibPDF/Fonts/TrueTypeFont.h> 13#include <LibPDF/Fonts/Type0Font.h> 14#include <LibPDF/Fonts/Type1Font.h> 15 16namespace PDF { 17 18[[maybe_unused]] static bool is_standard_latin_font(DeprecatedFlyString const& font) 19{ 20 return font.is_one_of( 21 "Times-Roman", "TimesNewRoman", 22 "Helvetica", "Arial", 23 "Courier", "CourierNew", 24 "Times-Bold", "TimesNewRoman,Bold", 25 "Helvetica-Bold", "Arial,Bold", 26 "Courier-Bold", "CourierNew,Bold", 27 "Times-Italic", "TimesNewRoman,Italic", 28 "Helvetica-Oblique", "Arial,Italic", 29 "Courier-Oblique", "CourierNew,Italic", 30 "Times-BoldItalic", "TimesNewRoman,BoldItalic", 31 "Helvetica-BoldOblique", "Arial,BoldItalic", 32 "Courier-BoldOblique", "CourierNew,BoldItalic"); 33} 34 35PDFErrorOr<NonnullRefPtr<PDFFont>> PDFFont::create(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size) 36{ 37 auto subtype = TRY(dict->get_name(document, CommonNames::Subtype))->name(); 38 39 RefPtr<PDFFont> font; 40 if (subtype == "Type1") 41 font = adopt_ref(*new Type1Font()); 42 else if (subtype == "TrueType") 43 font = adopt_ref(*new TrueTypeFont()); 44 else if (subtype == "Type0") 45 font = adopt_ref(*new Type0Font()); 46 else 47 return Error::internal_error("Unhandled font subtype: {}", subtype); 48 49 TRY(font->initialize(document, dict, font_size)); 50 return font.release_nonnull(); 51} 52 53PDFErrorOr<void> PDFFont::initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float) 54{ 55 m_base_font_name = TRY(dict->get_name(document, CommonNames::BaseFont))->name(); 56 return {}; 57} 58 59PDFErrorOr<NonnullRefPtr<Gfx::Font>> PDFFont::replacement_for(StringView name, float font_size) 60{ 61 bool is_bold = name.contains("bold"sv, CaseSensitivity::CaseInsensitive); 62 bool is_italic = name.contains("italic"sv, CaseSensitivity::CaseInsensitive); 63 64 DeprecatedString font_family; 65 if (name.contains("times"sv, CaseSensitivity::CaseInsensitive)) { 66 font_family = "Liberation Serif"; 67 } else if (name.contains("courier"sv, CaseSensitivity::CaseInsensitive)) { 68 font_family = "Liberation Mono"; 69 } else { 70 font_family = "Liberation Sans"; 71 } 72 73 DeprecatedString font_variant; 74 75 if (is_bold && is_italic) { 76 font_variant = "BoldItalic"; 77 } else if (is_bold) { 78 font_variant = "Bold"; 79 } else if (is_italic) { 80 font_variant = "Italic"; 81 } else { 82 font_variant = "Regular"; 83 } 84 85 float point_size = (font_size * POINTS_PER_INCH) / DEFAULT_DPI; 86 auto font = Gfx::FontDatabase::the().get(font_family, font_variant, point_size); 87 if (!font) 88 Error::internal_error("Failed to load {} {} at {}pt", font_family, font_variant, point_size); 89 return font.release_nonnull(); 90} 91 92}