7#include "core/fpdfapi/page/cpdf_psengine.h"
15#include "core/fpdfapi/parser/cpdf_simple_parser.h"
16#include "core/fxcrt/fx_safe_types.h"
17#include "core/fxcrt/fx_string.h"
18#include "third_party/base/check.h"
19#include "third_party/base/check_op.h"
20#include "third_party/base/notreached.h"
30constexpr PDF_PSOpName kPsOpNames[] = {
77float RoundHalfUp(
float f) {
80 if (f >
std::numeric_limits<
float>::max() - 0.5f)
81 return std::numeric_limits<
float>::max();
82 return floor(f + 0.5f);
91 DCHECK(m_op != PSOP_CONST);
92 DCHECK(m_op != PSOP_PROC);
101 return m_proc->Parse(parser, depth);
106 m_proc->Execute(pEngine);
113 NOTREACHED_NORETURN();
117 return m_MainProc.Execute(
this);
125 if (depth > kMaxDepth)
129 ByteStringView word = parser->GetWord();
137 m_Operators.push_back(std::make_unique<CPDF_PSOP>());
138 if (!m_Operators.back()->Parse(parser, depth + 1))
148 for (size_t i = 0; i < m_Operators.size(); ++i) {
149 const PDF_PSOP op = m_Operators[i]->GetOp();
154 pEngine->Push(m_Operators[i]->GetFloatValue());
159 if (i == 0 || m_Operators[i - 1]->GetOp() != PSOP_PROC)
162 if (pEngine->PopInt())
163 m_Operators[i - 1]->Execute(pEngine);
165 if (i < 2 || m_Operators[i - 1]->GetOp() != PSOP_PROC ||
166 m_Operators[i - 2]->GetOp() != PSOP_PROC) {
169 size_t offset = pEngine->PopInt() ? 2 : 1;
170 m_Operators[i - offset]->Execute(pEngine);
182void CPDF_PSProc::AddOperator(ByteStringView word) {
184 std::lower_bound(
std::begin(kPsOpNames),
std::end(kPsOpNames), word,
185 [](
const PDF_PSOpName& name, ByteStringView word) {
186 return name.name < word;
188 if (pFound != std::end(kPsOpNames) && pFound->name == word)
189 m_Operators.push_back(std::make_unique<CPDF_PSOP>(pFound->op));
191 m_Operators.push_back(std::make_unique<CPDF_PSOP>(StringToFloat(word)));
199 if (m_StackCount < kPSEngineStackSize)
200 m_Stack[m_StackCount++] = v;
204 return m_StackCount > 0 ? m_Stack[--m_StackCount] : 0;
208 return static_cast<
int>(
Pop());
213 return parser.GetWord() ==
"{" && m_MainProc.Parse(&parser, 0);
221 FX_SAFE_INT32 result;
249 Push(result.ValueOrDefault(0)
);
260 Push(result.ValueOrDefault(0)
);
304 d1 = atan2(d1, d2) * 180.0 /
FXSYS_PI;
385 FX_SAFE_INT32 safe_shift = shift;
386 result >>= (-safe_shift).ValueOrDefault(0);
388 Push(result.ValueOrDefault(0)
);
413 if (n < 0 || m_StackCount + n > kPSEngineStackSize ||
414 n >
static_cast<
int>(m_StackCount))
416 for (
int i = 0; i < n; i++)
417 m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n];
423 if (n < 0 || n >=
static_cast<
int>(m_StackCount))
425 Push(m_Stack[m_StackCount - n - 1]
);
431 if (j == 0 || n == 0 || m_StackCount == 0)
433 if (n < 0 || n >
static_cast<
int>(m_StackCount))
439 auto* begin_it =
std::begin(m_Stack) + m_StackCount - n;
440 auto* middle_it = begin_it - j;
441 auto* end_it =
std::begin(m_Stack) + m_StackCount;
442 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)