aboutsummaryrefslogtreecommitdiff
path: root/core/fpdfapi/page/cpdf_psengine.h
blob: 0b82bc0e86129ddb6357208478746ec7aac04d36 (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_
#define CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "core/fxcrt/bytestring.h"
#include "third_party/base/containers/span.h"

class CPDF_PSEngine;
class CPDF_PSProc;
class CPDF_SimpleParser;

enum PDF_PSOP : uint8_t {
  PSOP_ADD,
  PSOP_SUB,
  PSOP_MUL,
  PSOP_DIV,
  PSOP_IDIV,
  PSOP_MOD,
  PSOP_NEG,
  PSOP_ABS,
  PSOP_CEILING,
  PSOP_FLOOR,
  PSOP_ROUND,
  PSOP_TRUNCATE,
  PSOP_SQRT,
  PSOP_SIN,
  PSOP_COS,
  PSOP_ATAN,
  PSOP_EXP,
  PSOP_LN,
  PSOP_LOG,
  PSOP_CVI,
  PSOP_CVR,
  PSOP_EQ,
  PSOP_NE,
  PSOP_GT,
  PSOP_GE,
  PSOP_LT,
  PSOP_LE,
  PSOP_AND,
  PSOP_OR,
  PSOP_XOR,
  PSOP_NOT,
  PSOP_BITSHIFT,
  PSOP_TRUE,
  PSOP_FALSE,
  PSOP_IF,
  PSOP_IFELSE,
  PSOP_POP,
  PSOP_EXCH,
  PSOP_DUP,
  PSOP_COPY,
  PSOP_INDEX,
  PSOP_ROLL,
  PSOP_PROC,
  PSOP_CONST
};

class CPDF_PSOP {
 public:
  CPDF_PSOP();
  explicit CPDF_PSOP(PDF_PSOP op);
  explicit CPDF_PSOP(float value);
  ~CPDF_PSOP();

  bool Parse(CPDF_SimpleParser* parser, int depth);
  void Execute(CPDF_PSEngine* pEngine);
  float GetFloatValue() const;
  PDF_PSOP GetOp() const { return m_op; }

 private:
  const PDF_PSOP m_op;
  const float m_value;
  std::unique_ptr<CPDF_PSProc> m_proc;
};

class CPDF_PSProc {
 public:
  CPDF_PSProc();
  ~CPDF_PSProc();

  bool Parse(CPDF_SimpleParser* parser, int depth);
  bool Execute(CPDF_PSEngine* pEngine);

  // These methods are exposed for testing.
  void AddOperatorForTesting(ByteStringView word);
  size_t num_operators() const { return m_Operators.size(); }
  const std::unique_ptr<CPDF_PSOP>& last_operator() {
    return m_Operators.back();
  }

 private:
  static constexpr int kMaxDepth = 128;

  void AddOperator(ByteStringView word);

  std::vector<std::unique_ptr<CPDF_PSOP>> m_Operators;
};

class CPDF_PSEngine {
 public:
  CPDF_PSEngine();
  ~CPDF_PSEngine();

  bool Parse(pdfium::span<const uint8_t> input);
  bool Execute();
  bool DoOperator(PDF_PSOP op);
  void Reset() { m_StackCount = 0; }
  void Push(float value);
  float Pop();
  int PopInt();
  uint32_t GetStackSize() const { return m_StackCount; }

 private:
  static constexpr uint32_t kPSEngineStackSize = 100;

  uint32_t m_StackCount = 0;
  CPDF_PSProc m_MainProc;
  float m_Stack[kPSEngineStackSize] = {};
};

#endif  // CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_