7#include "core/fpdfapi/page/cpdf_psengine.h"
15#include "core/fpdfapi/parser/cpdf_simple_parser.h"
16#include "core/fxcrt/check.h"
17#include "core/fxcrt/check_op.h"
18#include "core/fxcrt/fx_safe_types.h"
19#include "core/fxcrt/fx_string.h"
29constexpr PDF_PSOpName kPsOpNames[] = {
76float RoundHalfUp(
float f) {
79 if (f >
std::numeric_limits<
float>::max() - 0.5f)
80 return std::numeric_limits<
float>::max();
81 return floor(f + 0.5f);
90 DCHECK(m_op != PSOP_CONST);
100 return m_proc->Parse(parser, depth);
105 m_proc->Execute(pEngine);
114 return m_MainProc.Execute(
this);
122 if (depth > kMaxDepth)
134 m_Operators.push_back(std::make_unique<CPDF_PSOP>());
135 if (!m_Operators.back()->Parse(parser, depth + 1))
145 for (size_t i = 0; i < m_Operators.size(); ++i) {
146 const PDF_PSOP op = m_Operators[i]->GetOp();
151 pEngine->Push(m_Operators[i]->GetFloatValue());
156 if (i == 0 || m_Operators[i - 1]->GetOp() != PSOP_PROC)
159 if (pEngine->PopInt())
160 m_Operators[i - 1]->Execute(pEngine);
162 if (i < 2 || m_Operators[i - 1]->GetOp() != PSOP_PROC ||
163 m_Operators[i - 2]->GetOp() != PSOP_PROC) {
167 m_Operators[i - offset]->Execute(pEngine);
181 std::lower_bound(
std::begin(kPsOpNames),
std::end(kPsOpNames), word,
183 return name.name < word;
185 if (pFound != std::end(kPsOpNames) && pFound->name == word)
186 m_Operators.push_back(std::make_unique<CPDF_PSOP>(pFound->op));
188 m_Operators.push_back(std::make_unique<CPDF_PSOP>(StringToFloat(word)));
196 if (m_StackCount < kPSEngineStackSize)
197 m_Stack[m_StackCount++] = v;
201 return m_StackCount > 0 ? m_Stack[--m_StackCount] : 0;
205 return static_cast<
int>(
Pop());
210 return parser.GetWord() ==
"{" && m_MainProc.Parse(&parser, 0);
246 Push(result.ValueOrDefault(0)
);
257 Push(result.ValueOrDefault(0)
);
301 d1 = atan2(d1, d2) * 180.0 /
FXSYS_PI;
383 result >>= (-safe_shift).ValueOrDefault(0);
385 Push(result.ValueOrDefault(0)
);
410 if (n < 0 || m_StackCount + n > kPSEngineStackSize ||
411 n >
static_cast<
int>(m_StackCount))
413 for (
int i = 0; i < n; i++)
414 m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
420 if (n < 0 || n >=
static_cast<
int>(m_StackCount))
422 Push(m_Stack[m_StackCount - n - 1]);
428 if (j == 0 || n == 0 || m_StackCount == 0)
430 if (n < 0 || n >
static_cast<
int>(m_StackCount))
436 auto begin_it = std::begin(m_Stack) + m_StackCount - n;
437 auto middle_it = begin_it - j;
438 auto end_it = std::begin(m_Stack) + m_StackCount;
439 std::rotate(begin_it, middle_it, end_it);
bool DoOperator(PDF_PSOP op)
bool Parse(pdfium::span< const uint8_t > input)
void Execute(CPDF_PSEngine *pEngine)
float GetFloatValue() const
bool Parse(CPDF_SimpleParser *parser, int depth)
bool Execute(CPDF_PSEngine *pEngine)
bool Parse(CPDF_SimpleParser *parser, int depth)
void AddOperatorForTesting(ByteStringView word)
pdfium::CheckedNumeric< int32_t > FX_SAFE_INT32
fxcrt::ByteStringView ByteStringView