1 // Copyright 2016 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_
8 #define CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_
9 
10 #include <memory>
11 #include <vector>
12 
13 #include "core/fxcrt/fx_string.h"
14 #include "core/fxcrt/fx_system.h"
15 
16 class CPDF_PSEngine;
17 class CPDF_PSProc;
18 class CPDF_SimpleParser;
19 
20 enum PDF_PSOP : uint8_t {
21   PSOP_ADD,
22   PSOP_SUB,
23   PSOP_MUL,
24   PSOP_DIV,
25   PSOP_IDIV,
26   PSOP_MOD,
27   PSOP_NEG,
28   PSOP_ABS,
29   PSOP_CEILING,
30   PSOP_FLOOR,
31   PSOP_ROUND,
32   PSOP_TRUNCATE,
33   PSOP_SQRT,
34   PSOP_SIN,
35   PSOP_COS,
36   PSOP_ATAN,
37   PSOP_EXP,
38   PSOP_LN,
39   PSOP_LOG,
40   PSOP_CVI,
41   PSOP_CVR,
42   PSOP_EQ,
43   PSOP_NE,
44   PSOP_GT,
45   PSOP_GE,
46   PSOP_LT,
47   PSOP_LE,
48   PSOP_AND,
49   PSOP_OR,
50   PSOP_XOR,
51   PSOP_NOT,
52   PSOP_BITSHIFT,
53   PSOP_TRUE,
54   PSOP_FALSE,
55   PSOP_IF,
56   PSOP_IFELSE,
57   PSOP_POP,
58   PSOP_EXCH,
59   PSOP_DUP,
60   PSOP_COPY,
61   PSOP_INDEX,
62   PSOP_ROLL,
63   PSOP_PROC,
64   PSOP_CONST
65 };
66 
67 class CPDF_PSOP {
68  public:
69   CPDF_PSOP();
70   explicit CPDF_PSOP(PDF_PSOP op);
71   explicit CPDF_PSOP(float value);
72   ~CPDF_PSOP();
73 
74   float GetFloatValue() const;
75   CPDF_PSProc* GetProc() const;
76   PDF_PSOP GetOp() const { return m_op; }
77 
78  private:
79   const PDF_PSOP m_op;
80   const float m_value;
81   std::unique_ptr<CPDF_PSProc> m_proc;
82 };
83 
84 class CPDF_PSProc {
85  public:
86   CPDF_PSProc();
87   ~CPDF_PSProc();
88 
89   bool Parse(CPDF_SimpleParser* parser, int depth);
90   bool Execute(CPDF_PSEngine* pEngine);
91 
92   // These methods are exposed for testing.
93   void AddOperatorForTesting(const ByteStringView& word);
94   size_t num_operators() const { return m_Operators.size(); }
95   const std::unique_ptr<CPDF_PSOP>& last_operator() {
96     return m_Operators.back();
97   }
98 
99  private:
100   static const int kMaxDepth = 128;
101 
102   void AddOperator(const ByteStringView& word);
103 
104   std::vector<std::unique_ptr<CPDF_PSOP>> m_Operators;
105 };
106 
107 class CPDF_PSEngine {
108  public:
109   CPDF_PSEngine();
110   ~CPDF_PSEngine();
111 
112   bool Parse(const char* str, int size);
113   bool Execute();
114   bool DoOperator(PDF_PSOP op);
115   void Reset() { m_StackCount = 0; }
116   void Push(float value);
117   float Pop();
118   int PopInt();
119   uint32_t GetStackSize() const { return m_StackCount; }
120 
121  private:
122   static constexpr uint32_t kPSEngineStackSize = 100;
123   float m_Stack[kPSEngineStackSize];
124   uint32_t m_StackCount;
125   CPDF_PSProc m_MainProc;
126 };
127 
128 #endif  // CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_
129