mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:17:44 +00:00
LibPDF: Implement ZapfDingbats clause of the adobe glphy list algorithm
Liberation Sans still doesn't have the vast majority of the Zapf Dingbats glyphs, but now we map the Zapf Dingbats names to good unicode values. So we only need to use a different font and all should work. (And Liberation Sans has _some_ of the glyphs, like 13 of the 223.) And we now render empty squares instead of wrong glyphs for the ones we don't have. I haven't seen any PDFs using ZapfDingbats in the wild, but they probably exist somewhere. (Tests/LibPDF/standard-14-fonts.pdf is a synthetic PDF using it.)
This commit is contained in:
parent
2eb099aabe
commit
8e3c54f203
5 changed files with 242 additions and 32 deletions
|
@ -12,23 +12,24 @@ Contains the Adobe Glyph List, transformed into C++ via this script:
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
print(f'static HashMap<StringView, u32> constexpr glyph_list = {{')
|
def write_table(source_filename, table_name):
|
||||||
for line in open('glyphlist.txt'):
|
print(f'static HashMap<StringView, u32> constexpr {table_name} = {{')
|
||||||
line = line.strip()
|
for line in open(source_filename):
|
||||||
if line.startswith('#'):
|
line = line.strip()
|
||||||
continue
|
if line.startswith('#'):
|
||||||
|
continue
|
||||||
|
name, codepoint = line.split(';')
|
||||||
|
if ' ' in codepoint:
|
||||||
|
print(f'skipping {name}, multiple codepoints', file=sys.stderr)
|
||||||
|
continue
|
||||||
|
print(f' {{ "{name}"sv, 0x{codepoint} }},')
|
||||||
|
print(f'}};')
|
||||||
|
|
||||||
name, codepoint = line.split(';')
|
write_table('glyphlist.txt', 'glyph_list')
|
||||||
|
write_table('zapfdingbats.txt', 'zapf_dingbats_list')
|
||||||
if ' ' in codepoint:
|
|
||||||
print(f'skipping {name}, multiple codepoints', file=sys.stderr)
|
|
||||||
continue
|
|
||||||
|
|
||||||
print(f' {{ "{name}"sv, 0x{codepoint} }},')
|
|
||||||
print(f'}};')
|
|
||||||
```
|
```
|
||||||
|
|
||||||
where glyphlist.txt is from https://github.com/adobe-type-tools/agl-aglfn/blob/master/glyphlist.txt
|
where glyphlist.txt and zapfdingbats.txt are from https://github.com/adobe-type-tools/agl-aglfn/blob/master/glyphlist.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/CharacterTypes.h>
|
#include <AK/CharacterTypes.h>
|
||||||
|
@ -4240,6 +4241,209 @@ static HashMap<StringView, u32> const glyph_list = {
|
||||||
{ "zuhiragana"sv, 0x305A },
|
{ "zuhiragana"sv, 0x305A },
|
||||||
{ "zukatakana"sv, 0x30BA },
|
{ "zukatakana"sv, 0x30BA },
|
||||||
};
|
};
|
||||||
|
static HashMap<StringView, u32> const zapf_dingbats_list = {
|
||||||
|
{ "a100"sv, 0x275E },
|
||||||
|
{ "a101"sv, 0x2761 },
|
||||||
|
{ "a102"sv, 0x2762 },
|
||||||
|
{ "a103"sv, 0x2763 },
|
||||||
|
{ "a104"sv, 0x2764 },
|
||||||
|
{ "a105"sv, 0x2710 },
|
||||||
|
{ "a106"sv, 0x2765 },
|
||||||
|
{ "a107"sv, 0x2766 },
|
||||||
|
{ "a108"sv, 0x2767 },
|
||||||
|
{ "a109"sv, 0x2660 },
|
||||||
|
{ "a10"sv, 0x2721 },
|
||||||
|
{ "a110"sv, 0x2665 },
|
||||||
|
{ "a111"sv, 0x2666 },
|
||||||
|
{ "a112"sv, 0x2663 },
|
||||||
|
{ "a117"sv, 0x2709 },
|
||||||
|
{ "a118"sv, 0x2708 },
|
||||||
|
{ "a119"sv, 0x2707 },
|
||||||
|
{ "a11"sv, 0x261B },
|
||||||
|
{ "a120"sv, 0x2460 },
|
||||||
|
{ "a121"sv, 0x2461 },
|
||||||
|
{ "a122"sv, 0x2462 },
|
||||||
|
{ "a123"sv, 0x2463 },
|
||||||
|
{ "a124"sv, 0x2464 },
|
||||||
|
{ "a125"sv, 0x2465 },
|
||||||
|
{ "a126"sv, 0x2466 },
|
||||||
|
{ "a127"sv, 0x2467 },
|
||||||
|
{ "a128"sv, 0x2468 },
|
||||||
|
{ "a129"sv, 0x2469 },
|
||||||
|
{ "a12"sv, 0x261E },
|
||||||
|
{ "a130"sv, 0x2776 },
|
||||||
|
{ "a131"sv, 0x2777 },
|
||||||
|
{ "a132"sv, 0x2778 },
|
||||||
|
{ "a133"sv, 0x2779 },
|
||||||
|
{ "a134"sv, 0x277A },
|
||||||
|
{ "a135"sv, 0x277B },
|
||||||
|
{ "a136"sv, 0x277C },
|
||||||
|
{ "a137"sv, 0x277D },
|
||||||
|
{ "a138"sv, 0x277E },
|
||||||
|
{ "a139"sv, 0x277F },
|
||||||
|
{ "a13"sv, 0x270C },
|
||||||
|
{ "a140"sv, 0x2780 },
|
||||||
|
{ "a141"sv, 0x2781 },
|
||||||
|
{ "a142"sv, 0x2782 },
|
||||||
|
{ "a143"sv, 0x2783 },
|
||||||
|
{ "a144"sv, 0x2784 },
|
||||||
|
{ "a145"sv, 0x2785 },
|
||||||
|
{ "a146"sv, 0x2786 },
|
||||||
|
{ "a147"sv, 0x2787 },
|
||||||
|
{ "a148"sv, 0x2788 },
|
||||||
|
{ "a149"sv, 0x2789 },
|
||||||
|
{ "a14"sv, 0x270D },
|
||||||
|
{ "a150"sv, 0x278A },
|
||||||
|
{ "a151"sv, 0x278B },
|
||||||
|
{ "a152"sv, 0x278C },
|
||||||
|
{ "a153"sv, 0x278D },
|
||||||
|
{ "a154"sv, 0x278E },
|
||||||
|
{ "a155"sv, 0x278F },
|
||||||
|
{ "a156"sv, 0x2790 },
|
||||||
|
{ "a157"sv, 0x2791 },
|
||||||
|
{ "a158"sv, 0x2792 },
|
||||||
|
{ "a159"sv, 0x2793 },
|
||||||
|
{ "a15"sv, 0x270E },
|
||||||
|
{ "a160"sv, 0x2794 },
|
||||||
|
{ "a161"sv, 0x2192 },
|
||||||
|
{ "a162"sv, 0x27A3 },
|
||||||
|
{ "a163"sv, 0x2194 },
|
||||||
|
{ "a164"sv, 0x2195 },
|
||||||
|
{ "a165"sv, 0x2799 },
|
||||||
|
{ "a166"sv, 0x279B },
|
||||||
|
{ "a167"sv, 0x279C },
|
||||||
|
{ "a168"sv, 0x279D },
|
||||||
|
{ "a169"sv, 0x279E },
|
||||||
|
{ "a16"sv, 0x270F },
|
||||||
|
{ "a170"sv, 0x279F },
|
||||||
|
{ "a171"sv, 0x27A0 },
|
||||||
|
{ "a172"sv, 0x27A1 },
|
||||||
|
{ "a173"sv, 0x27A2 },
|
||||||
|
{ "a174"sv, 0x27A4 },
|
||||||
|
{ "a175"sv, 0x27A5 },
|
||||||
|
{ "a176"sv, 0x27A6 },
|
||||||
|
{ "a177"sv, 0x27A7 },
|
||||||
|
{ "a178"sv, 0x27A8 },
|
||||||
|
{ "a179"sv, 0x27A9 },
|
||||||
|
{ "a17"sv, 0x2711 },
|
||||||
|
{ "a180"sv, 0x27AB },
|
||||||
|
{ "a181"sv, 0x27AD },
|
||||||
|
{ "a182"sv, 0x27AF },
|
||||||
|
{ "a183"sv, 0x27B2 },
|
||||||
|
{ "a184"sv, 0x27B3 },
|
||||||
|
{ "a185"sv, 0x27B5 },
|
||||||
|
{ "a186"sv, 0x27B8 },
|
||||||
|
{ "a187"sv, 0x27BA },
|
||||||
|
{ "a188"sv, 0x27BB },
|
||||||
|
{ "a189"sv, 0x27BC },
|
||||||
|
{ "a18"sv, 0x2712 },
|
||||||
|
{ "a190"sv, 0x27BD },
|
||||||
|
{ "a191"sv, 0x27BE },
|
||||||
|
{ "a192"sv, 0x279A },
|
||||||
|
{ "a193"sv, 0x27AA },
|
||||||
|
{ "a194"sv, 0x27B6 },
|
||||||
|
{ "a195"sv, 0x27B9 },
|
||||||
|
{ "a196"sv, 0x2798 },
|
||||||
|
{ "a197"sv, 0x27B4 },
|
||||||
|
{ "a198"sv, 0x27B7 },
|
||||||
|
{ "a199"sv, 0x27AC },
|
||||||
|
{ "a19"sv, 0x2713 },
|
||||||
|
{ "a1"sv, 0x2701 },
|
||||||
|
{ "a200"sv, 0x27AE },
|
||||||
|
{ "a201"sv, 0x27B1 },
|
||||||
|
{ "a202"sv, 0x2703 },
|
||||||
|
{ "a203"sv, 0x2750 },
|
||||||
|
{ "a204"sv, 0x2752 },
|
||||||
|
{ "a205"sv, 0x276E },
|
||||||
|
{ "a206"sv, 0x2770 },
|
||||||
|
{ "a20"sv, 0x2714 },
|
||||||
|
{ "a21"sv, 0x2715 },
|
||||||
|
{ "a22"sv, 0x2716 },
|
||||||
|
{ "a23"sv, 0x2717 },
|
||||||
|
{ "a24"sv, 0x2718 },
|
||||||
|
{ "a25"sv, 0x2719 },
|
||||||
|
{ "a26"sv, 0x271A },
|
||||||
|
{ "a27"sv, 0x271B },
|
||||||
|
{ "a28"sv, 0x271C },
|
||||||
|
{ "a29"sv, 0x2722 },
|
||||||
|
{ "a2"sv, 0x2702 },
|
||||||
|
{ "a30"sv, 0x2723 },
|
||||||
|
{ "a31"sv, 0x2724 },
|
||||||
|
{ "a32"sv, 0x2725 },
|
||||||
|
{ "a33"sv, 0x2726 },
|
||||||
|
{ "a34"sv, 0x2727 },
|
||||||
|
{ "a35"sv, 0x2605 },
|
||||||
|
{ "a36"sv, 0x2729 },
|
||||||
|
{ "a37"sv, 0x272A },
|
||||||
|
{ "a38"sv, 0x272B },
|
||||||
|
{ "a39"sv, 0x272C },
|
||||||
|
{ "a3"sv, 0x2704 },
|
||||||
|
{ "a40"sv, 0x272D },
|
||||||
|
{ "a41"sv, 0x272E },
|
||||||
|
{ "a42"sv, 0x272F },
|
||||||
|
{ "a43"sv, 0x2730 },
|
||||||
|
{ "a44"sv, 0x2731 },
|
||||||
|
{ "a45"sv, 0x2732 },
|
||||||
|
{ "a46"sv, 0x2733 },
|
||||||
|
{ "a47"sv, 0x2734 },
|
||||||
|
{ "a48"sv, 0x2735 },
|
||||||
|
{ "a49"sv, 0x2736 },
|
||||||
|
{ "a4"sv, 0x260E },
|
||||||
|
{ "a50"sv, 0x2737 },
|
||||||
|
{ "a51"sv, 0x2738 },
|
||||||
|
{ "a52"sv, 0x2739 },
|
||||||
|
{ "a53"sv, 0x273A },
|
||||||
|
{ "a54"sv, 0x273B },
|
||||||
|
{ "a55"sv, 0x273C },
|
||||||
|
{ "a56"sv, 0x273D },
|
||||||
|
{ "a57"sv, 0x273E },
|
||||||
|
{ "a58"sv, 0x273F },
|
||||||
|
{ "a59"sv, 0x2740 },
|
||||||
|
{ "a5"sv, 0x2706 },
|
||||||
|
{ "a60"sv, 0x2741 },
|
||||||
|
{ "a61"sv, 0x2742 },
|
||||||
|
{ "a62"sv, 0x2743 },
|
||||||
|
{ "a63"sv, 0x2744 },
|
||||||
|
{ "a64"sv, 0x2745 },
|
||||||
|
{ "a65"sv, 0x2746 },
|
||||||
|
{ "a66"sv, 0x2747 },
|
||||||
|
{ "a67"sv, 0x2748 },
|
||||||
|
{ "a68"sv, 0x2749 },
|
||||||
|
{ "a69"sv, 0x274A },
|
||||||
|
{ "a6"sv, 0x271D },
|
||||||
|
{ "a70"sv, 0x274B },
|
||||||
|
{ "a71"sv, 0x25CF },
|
||||||
|
{ "a72"sv, 0x274D },
|
||||||
|
{ "a73"sv, 0x25A0 },
|
||||||
|
{ "a74"sv, 0x274F },
|
||||||
|
{ "a75"sv, 0x2751 },
|
||||||
|
{ "a76"sv, 0x25B2 },
|
||||||
|
{ "a77"sv, 0x25BC },
|
||||||
|
{ "a78"sv, 0x25C6 },
|
||||||
|
{ "a79"sv, 0x2756 },
|
||||||
|
{ "a7"sv, 0x271E },
|
||||||
|
{ "a81"sv, 0x25D7 },
|
||||||
|
{ "a82"sv, 0x2758 },
|
||||||
|
{ "a83"sv, 0x2759 },
|
||||||
|
{ "a84"sv, 0x275A },
|
||||||
|
{ "a85"sv, 0x276F },
|
||||||
|
{ "a86"sv, 0x2771 },
|
||||||
|
{ "a87"sv, 0x2772 },
|
||||||
|
{ "a88"sv, 0x2773 },
|
||||||
|
{ "a89"sv, 0x2768 },
|
||||||
|
{ "a8"sv, 0x271F },
|
||||||
|
{ "a90"sv, 0x2769 },
|
||||||
|
{ "a91"sv, 0x276C },
|
||||||
|
{ "a92"sv, 0x276D },
|
||||||
|
{ "a93"sv, 0x276A },
|
||||||
|
{ "a94"sv, 0x276B },
|
||||||
|
{ "a95"sv, 0x2774 },
|
||||||
|
{ "a96"sv, 0x2775 },
|
||||||
|
{ "a97"sv, 0x275B },
|
||||||
|
{ "a98"sv, 0x275C },
|
||||||
|
{ "a99"sv, 0x275D },
|
||||||
|
{ "a9"sv, 0x2720 },
|
||||||
|
};
|
||||||
|
|
||||||
static bool are_all_uppercase_hex(StringView component)
|
static bool are_all_uppercase_hex(StringView component)
|
||||||
{
|
{
|
||||||
|
@ -4259,7 +4463,7 @@ static u32 decode_hex(StringView hex_string)
|
||||||
return code_point;
|
return code_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<u32> glyph_name_to_unicode(StringView name)
|
Optional<u32> glyph_name_to_unicode(StringView name, bool is_zapf_dingbats)
|
||||||
{
|
{
|
||||||
// https://github.com/adobe-type-tools/agl-specification?tab=readme-ov-file#2-the-mapping
|
// https://github.com/adobe-type-tools/agl-specification?tab=readme-ov-file#2-the-mapping
|
||||||
// "To map a glyph name to a character string, follow the three steps below:
|
// "To map a glyph name to a character string, follow the three steps below:
|
||||||
|
@ -4277,10 +4481,14 @@ Optional<u32> glyph_name_to_unicode(StringView name)
|
||||||
// 3. Map each component to a character string according to the procedure below, and concatenate those strings; the result is the character string to which the glyph name is mapped.
|
// 3. Map each component to a character string according to the procedure below, and concatenate those strings; the result is the character string to which the glyph name is mapped.
|
||||||
StringView component = name;
|
StringView component = name;
|
||||||
|
|
||||||
// If the font is Zapf Dingbats (PostScript FontName: ZapfDingbats), and the component is in the ITC Zapf Dingbats Glyph List, then map it to the corresponding character in that list."
|
// If the font is Zapf Dingbats (PostScript FontName: ZapfDingbats), and the component is in the ITC Zapf Dingbats Glyph List, then map it to the corresponding character in that list.
|
||||||
// FIXME: Implement.
|
if (is_zapf_dingbats) {
|
||||||
|
auto zapf_dingbats_entry = zapf_dingbats_list.get(component);
|
||||||
|
if (zapf_dingbats_entry.has_value())
|
||||||
|
return zapf_dingbats_entry.value();
|
||||||
|
}
|
||||||
|
|
||||||
// "Otherwise, if the component is in AGL, then map it to the corresponding character in that list.
|
// Otherwise, if the component is in AGL, then map it to the corresponding character in that list.
|
||||||
auto agl_entry = glyph_list.get(component);
|
auto agl_entry = glyph_list.get(component);
|
||||||
if (agl_entry.has_value())
|
if (agl_entry.has_value())
|
||||||
return agl_entry.value();
|
return agl_entry.value();
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
|
|
||||||
namespace PDF {
|
namespace PDF {
|
||||||
|
|
||||||
Optional<u32> glyph_name_to_unicode(StringView);
|
Optional<u32> glyph_name_to_unicode(StringView, bool is_zapf_dingbats);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,17 @@
|
||||||
|
|
||||||
namespace PDF {
|
namespace PDF {
|
||||||
|
|
||||||
TrueTypePainter::TrueTypePainter(AK::NonnullRefPtr<Gfx::Font> font, NonnullRefPtr<Encoding> encoding, bool encoding_is_mac_roman_or_win_ansi, bool is_nonsymbolic, Optional<u8> high_byte)
|
TrueTypePainter::TrueTypePainter(AK::NonnullRefPtr<Gfx::Font> font, NonnullRefPtr<Encoding> encoding, bool encoding_is_mac_roman_or_win_ansi, bool is_nonsymbolic, Optional<u8> high_byte, bool is_zapf_dingbats)
|
||||||
: m_font(move(font))
|
: m_font(move(font))
|
||||||
, m_encoding(move(encoding))
|
, m_encoding(move(encoding))
|
||||||
, m_encoding_is_mac_roman_or_win_ansi(encoding_is_mac_roman_or_win_ansi)
|
, m_encoding_is_mac_roman_or_win_ansi(encoding_is_mac_roman_or_win_ansi)
|
||||||
, m_is_nonsymbolic(is_nonsymbolic)
|
, m_is_nonsymbolic(is_nonsymbolic)
|
||||||
, m_high_byte(high_byte)
|
, m_high_byte(high_byte)
|
||||||
|
, m_is_zapf_dingbats(is_zapf_dingbats)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NonnullOwnPtr<TrueTypePainter> TrueTypePainter::create(Document* document, NonnullRefPtr<DictObject> const& dict, SimpleFont const& containing_pdf_font, AK::NonnullRefPtr<Gfx::Font> font, NonnullRefPtr<Encoding> encoding)
|
NonnullOwnPtr<TrueTypePainter> TrueTypePainter::create(Document* document, NonnullRefPtr<DictObject> const& dict, SimpleFont const& containing_pdf_font, AK::NonnullRefPtr<Gfx::Font> font, NonnullRefPtr<Encoding> encoding, bool is_zapf_dingbats)
|
||||||
{
|
{
|
||||||
bool encoding_is_mac_roman_or_win_ansi = false;
|
bool encoding_is_mac_roman_or_win_ansi = false;
|
||||||
if (dict->contains(CommonNames::Encoding)) {
|
if (dict->contains(CommonNames::Encoding)) {
|
||||||
|
@ -55,7 +56,7 @@ NonnullOwnPtr<TrueTypePainter> TrueTypePainter::create(Document* document, Nonnu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return adopt_own(*new TrueTypePainter { move(font), move(encoding), encoding_is_mac_roman_or_win_ansi, containing_pdf_font.is_nonsymbolic(), high_byte });
|
return adopt_own(*new TrueTypePainter { move(font), move(encoding), encoding_is_mac_roman_or_win_ansi, containing_pdf_font.is_nonsymbolic(), high_byte, is_zapf_dingbats });
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 unicode, Gfx::Font const& font, ColorOrStyle const& style)
|
static void do_draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 unicode, Gfx::Font const& font, ColorOrStyle const& style)
|
||||||
|
@ -106,7 +107,7 @@ PDFErrorOr<void> TrueTypePainter::draw_glyph(Gfx::Painter& painter, Gfx::FloatPo
|
||||||
// use the (3, 1) algorithm.
|
// use the (3, 1) algorithm.
|
||||||
// FIXME: Implement (1, 0) subtable support.
|
// FIXME: Implement (1, 0) subtable support.
|
||||||
auto char_name = m_encoding->get_name(char_code);
|
auto char_name = m_encoding->get_name(char_code);
|
||||||
u32 unicode = glyph_name_to_unicode(char_name).value_or(char_code);
|
u32 unicode = glyph_name_to_unicode(char_name, m_is_zapf_dingbats).value_or(char_code);
|
||||||
if (m_font->contains_glyph(unicode)) {
|
if (m_font->contains_glyph(unicode)) {
|
||||||
do_draw_glyph(painter, point, width, unicode, *m_font, style);
|
do_draw_glyph(painter, point, width, unicode, *m_font, style);
|
||||||
return {};
|
return {};
|
||||||
|
@ -132,7 +133,7 @@ PDFErrorOr<void> TrueTypePainter::draw_glyph(Gfx::Painter& painter, Gfx::FloatPo
|
||||||
// "If a character cannot be mapped in any of the ways described above, the results are implementation-dependent."
|
// "If a character cannot be mapped in any of the ways described above, the results are implementation-dependent."
|
||||||
// FIXME: Do something smarter?
|
// FIXME: Do something smarter?
|
||||||
auto char_name = m_encoding->get_name(char_code);
|
auto char_name = m_encoding->get_name(char_code);
|
||||||
unicode = glyph_name_to_unicode(char_name).value_or(char_code);
|
unicode = glyph_name_to_unicode(char_name, m_is_zapf_dingbats).value_or(char_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_draw_glyph(painter, point, width, unicode, *m_font, style);
|
do_draw_glyph(painter, point, width, unicode, *m_font, style);
|
||||||
|
@ -143,7 +144,7 @@ Optional<float> TrueTypePainter::get_glyph_width(u8 char_code) const
|
||||||
{
|
{
|
||||||
// FIXME: Make this use the full char_code lookup method used in draw_glyph() once that's complete.
|
// FIXME: Make this use the full char_code lookup method used in draw_glyph() once that's complete.
|
||||||
auto char_name = m_encoding->get_name(char_code);
|
auto char_name = m_encoding->get_name(char_code);
|
||||||
u32 unicode = glyph_name_to_unicode(char_name).value_or(char_code);
|
u32 unicode = glyph_name_to_unicode(char_name, m_is_zapf_dingbats).value_or(char_code);
|
||||||
return m_font->glyph_width(unicode);
|
return m_font->glyph_width(unicode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +178,8 @@ PDFErrorOr<void> TrueTypeFont::initialize(Document* document, NonnullRefPtr<Dict
|
||||||
if (!effective_encoding)
|
if (!effective_encoding)
|
||||||
effective_encoding = Encoding::standard_encoding();
|
effective_encoding = Encoding::standard_encoding();
|
||||||
|
|
||||||
m_font_painter = TrueTypePainter::create(document, dict, *this, *font, *effective_encoding);
|
bool const is_zapf_dingbats = false;
|
||||||
|
m_font_painter = TrueTypePainter::create(document, dict, *this, *font, *effective_encoding, is_zapf_dingbats);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,20 +14,21 @@ namespace PDF {
|
||||||
|
|
||||||
class TrueTypePainter {
|
class TrueTypePainter {
|
||||||
public:
|
public:
|
||||||
static NonnullOwnPtr<TrueTypePainter> create(Document*, NonnullRefPtr<DictObject> const&, SimpleFont const& containing_pdf_font, AK::NonnullRefPtr<Gfx::Font>, NonnullRefPtr<Encoding>);
|
static NonnullOwnPtr<TrueTypePainter> create(Document*, NonnullRefPtr<DictObject> const&, SimpleFont const& containing_pdf_font, AK::NonnullRefPtr<Gfx::Font>, NonnullRefPtr<Encoding>, bool is_zapf_dingbats);
|
||||||
|
|
||||||
PDFErrorOr<void> draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float width, u8 char_code, Renderer const&);
|
PDFErrorOr<void> draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float width, u8 char_code, Renderer const&);
|
||||||
Optional<float> get_glyph_width(u8 char_code) const;
|
Optional<float> get_glyph_width(u8 char_code) const;
|
||||||
void set_font_size(float font_size);
|
void set_font_size(float font_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TrueTypePainter(AK::NonnullRefPtr<Gfx::Font>, NonnullRefPtr<Encoding>, bool encoding_is_mac_roman_or_win_ansi, bool is_nonsymbolic, Optional<u8> high_byte);
|
TrueTypePainter(AK::NonnullRefPtr<Gfx::Font>, NonnullRefPtr<Encoding>, bool encoding_is_mac_roman_or_win_ansi, bool is_nonsymbolic, Optional<u8> high_byte, bool is_zapf_dingbats);
|
||||||
|
|
||||||
NonnullRefPtr<Gfx::Font> m_font;
|
NonnullRefPtr<Gfx::Font> m_font;
|
||||||
NonnullRefPtr<Encoding> m_encoding;
|
NonnullRefPtr<Encoding> m_encoding;
|
||||||
bool m_encoding_is_mac_roman_or_win_ansi { false };
|
bool m_encoding_is_mac_roman_or_win_ansi { false };
|
||||||
bool m_is_nonsymbolic { false };
|
bool m_is_nonsymbolic { false };
|
||||||
Optional<u8> m_high_byte;
|
Optional<u8> m_high_byte;
|
||||||
|
bool m_is_zapf_dingbats { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
class TrueTypeFont : public SimpleFont {
|
class TrueTypeFont : public SimpleFont {
|
||||||
|
|
|
@ -63,9 +63,8 @@ PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObj
|
||||||
// since the names in that font are meaningless.)"
|
// since the names in that font are meaningless.)"
|
||||||
// FIXME: We use Liberation Sans for both Symbol and ZapfDingbats. It doesn't have all Symbol
|
// FIXME: We use Liberation Sans for both Symbol and ZapfDingbats. It doesn't have all Symbol
|
||||||
// characters, or at least not under the codepoints used in AdobeGlpyhList. It doesn't
|
// characters, or at least not under the codepoints used in AdobeGlpyhList. It doesn't
|
||||||
// have any ZapfDingbats characters, or at least not the names for it. Not sure what to do about
|
// have most of the ZapfDingbats characters. Not sure what to do about this -- we might need a different font.
|
||||||
// this -- we either need a different font, or need to tweak the encoding somehow.
|
// (For Helvetica / Times / Courier, the Liberation family also doesn't have the right metrics.)
|
||||||
// (For Helvetica / Times / Courier, the Liberation family doesn't have the right metrics.)
|
|
||||||
if (base_font_name() == "Symbol"sv)
|
if (base_font_name() == "Symbol"sv)
|
||||||
effective_encoding = Encoding::symbol_encoding();
|
effective_encoding = Encoding::symbol_encoding();
|
||||||
else if (base_font_name() == "ZapfDingbats"sv)
|
else if (base_font_name() == "ZapfDingbats"sv)
|
||||||
|
@ -76,7 +75,7 @@ PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObj
|
||||||
|
|
||||||
// FIXME: For the standard 14 fonts, set some m_flags bits (symbolic/nonsymbolic, italic, bold, fixed pitch, serif).
|
// FIXME: For the standard 14 fonts, set some m_flags bits (symbolic/nonsymbolic, italic, bold, fixed pitch, serif).
|
||||||
|
|
||||||
m_fallback_font_painter = TrueTypePainter::create(document, dict, *this, *font, *effective_encoding);
|
m_fallback_font_painter = TrueTypePainter::create(document, dict, *this, *font, *effective_encoding, base_font_name() == "ZapfDingbats"sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY(m_font_program || m_fallback_font_painter);
|
VERIFY(m_font_program || m_fallback_font_painter);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue