PDFFont.cpp 3.6 KB

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