PDFFont.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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 <LibGfx/Font/FontDatabase.h>
  9. #include <LibPDF/CommonNames.h>
  10. #include <LibPDF/Fonts/PDFFont.h>
  11. #include <LibPDF/Fonts/TrueTypeFont.h>
  12. #include <LibPDF/Fonts/Type0Font.h>
  13. #include <LibPDF/Fonts/Type1Font.h>
  14. namespace PDF {
  15. [[maybe_unused]] static bool is_standard_latin_font(DeprecatedFlyString const& font)
  16. {
  17. return font.is_one_of(
  18. "Times-Roman", "TimesNewRoman",
  19. "Helvetica", "Arial",
  20. "Courier", "CourierNew",
  21. "Times-Bold", "TimesNewRoman,Bold",
  22. "Helvetica-Bold", "Arial,Bold",
  23. "Courier-Bold", "CourierNew,Bold",
  24. "Times-Italic", "TimesNewRoman,Italic",
  25. "Helvetica-Oblique", "Arial,Italic",
  26. "Courier-Oblique", "CourierNew,Italic",
  27. "Times-BoldItalic", "TimesNewRoman,BoldItalic",
  28. "Helvetica-BoldOblique", "Arial,BoldItalic",
  29. "Courier-BoldOblique", "CourierNew,BoldItalic");
  30. }
  31. PDFErrorOr<NonnullRefPtr<PDFFont>> PDFFont::create(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size)
  32. {
  33. auto subtype = TRY(dict->get_name(document, CommonNames::Subtype))->name();
  34. RefPtr<PDFFont> font;
  35. if (subtype == "Type1")
  36. font = adopt_ref(*new Type1Font());
  37. else if (subtype == "TrueType")
  38. font = adopt_ref(*new TrueTypeFont());
  39. else if (subtype == "Type0")
  40. font = adopt_ref(*new Type0Font());
  41. else
  42. return Error::internal_error("Unhandled font subtype: {}", subtype);
  43. TRY(font->initialize(document, dict, font_size));
  44. return font.release_nonnull();
  45. }
  46. PDFErrorOr<void> PDFFont::initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float)
  47. {
  48. m_base_font_name = TRY(dict->get_name(document, CommonNames::BaseFont))->name();
  49. return {};
  50. }
  51. PDFErrorOr<NonnullRefPtr<Gfx::Font>> PDFFont::replacement_for(StringView name, float font_size)
  52. {
  53. bool is_bold = name.contains("bold"sv, CaseSensitivity::CaseInsensitive);
  54. bool is_italic = name.contains("italic"sv, CaseSensitivity::CaseInsensitive);
  55. DeprecatedString font_family;
  56. if (name.contains("times"sv, CaseSensitivity::CaseInsensitive)) {
  57. font_family = "Liberation Serif";
  58. } else if (name.contains("courier"sv, CaseSensitivity::CaseInsensitive)) {
  59. font_family = "Liberation Mono";
  60. } else {
  61. font_family = "Liberation Sans";
  62. }
  63. DeprecatedString font_variant;
  64. if (is_bold && is_italic) {
  65. font_variant = "BoldItalic";
  66. } else if (is_bold) {
  67. font_variant = "Bold";
  68. } else if (is_italic) {
  69. font_variant = "Italic";
  70. } else {
  71. font_variant = "Regular";
  72. }
  73. float point_size = (font_size * POINTS_PER_INCH) / DEFAULT_DPI;
  74. auto font = Gfx::FontDatabase::the().get(font_family, font_variant, point_size);
  75. if (!font)
  76. return Error::internal_error("Failed to load {} {} at {}pt", font_family, font_variant, point_size);
  77. return font.release_nonnull();
  78. }
  79. }