summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.h
blob: ca660674aadab673a90b0e5aaeca5e226819aada (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 * Copyright (c) 2022, Julian Offenhäuser <offenhaeuser@protonmail.com>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/Forward.h>
#include <LibGfx/AffineTransform.h>
#include <LibGfx/Font/Font.h>
#include <LibGfx/Path.h>
#include <LibPDF/Error.h>

namespace PDF {

class Reader;
class Encoding;

class PS1FontProgram : public RefCounted<PS1FontProgram> {
public:
    PDFErrorOr<void> create(ReadonlyBytes const&, RefPtr<Encoding>, size_t cleartext_length, size_t encrypted_length);

    RefPtr<Gfx::Bitmap> rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset);
    Gfx::Path build_char(u32 char_code, float width);

    RefPtr<Encoding> encoding() const { return m_encoding; }
    Gfx::FloatPoint glyph_translation(u32 char_code, float width) const;

private:
    struct Glyph {
        Gfx::Path path;
        float width;
    };

    struct GlyphParserState {
        Glyph glyph;

        Gfx::FloatPoint point;

        bool flex_feature { false };
        size_t flex_index;
        Array<float, 14> flex_sequence;

        size_t sp { 0 };
        Array<float, 24> stack;

        size_t postscript_sp { 0 };
        Array<float, 24> postscript_stack;
    };

    Gfx::AffineTransform glyph_transform_to_device_space(Glyph const&, float width) const;

    PDFErrorOr<Glyph> parse_glyph(ReadonlyBytes const&, GlyphParserState&);
    PDFErrorOr<void> parse_encrypted_portion(ByteBuffer const&);
    PDFErrorOr<Vector<ByteBuffer>> parse_subroutines(Reader&);
    PDFErrorOr<Vector<float>> parse_number_array(Reader&, size_t length);
    PDFErrorOr<DeprecatedString> parse_word(Reader&);
    PDFErrorOr<float> parse_float(Reader&);
    PDFErrorOr<int> parse_int(Reader&);

    PDFErrorOr<ByteBuffer> decrypt(ReadonlyBytes const&, u16 key, size_t skip);
    bool seek_name(Reader&, DeprecatedString const&);

    static Error error(
        DeprecatedString const& message
#ifdef PDF_DEBUG
        ,
        SourceLocation loc = SourceLocation::current()
#endif
    );

    Vector<ByteBuffer> m_subroutines;
    Vector<ByteBuffer> m_character_names;
    HashMap<u16, Glyph> m_glyph_map;

    Gfx::AffineTransform m_font_matrix;

    RefPtr<Encoding> m_encoding;

    u16 m_encryption_key { 4330 };
    int m_lenIV { 4 };
};

}