149 lines
4.6 KiB
C++
149 lines
4.6 KiB
C++
|
|
// 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
|
||
|
|
|
||
|
|
#include "core/fpdfdoc/cpdf_defaultappearance.h"
|
||
|
|
|
||
|
|
#include <algorithm>
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
#include "core/fpdfapi/parser/cpdf_simple_parser.h"
|
||
|
|
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
|
||
|
|
#include "core/fxcrt/fx_string.h"
|
||
|
|
#include "core/fxge/cfx_color.h"
|
||
|
|
#include "third_party/base/notreached.h"
|
||
|
|
|
||
|
|
namespace {
|
||
|
|
|
||
|
|
// Find the token and its |nParams| parameters from the start of data,
|
||
|
|
// and move the current position to the start of those parameters.
|
||
|
|
bool FindTagParamFromStart(CPDF_SimpleParser* parser,
|
||
|
|
ByteStringView token,
|
||
|
|
int nParams) {
|
||
|
|
nParams++;
|
||
|
|
|
||
|
|
std::vector<uint32_t> pBuf(nParams);
|
||
|
|
int buf_index = 0;
|
||
|
|
int buf_count = 0;
|
||
|
|
|
||
|
|
parser->SetCurPos(0);
|
||
|
|
while (true) {
|
||
|
|
pBuf[buf_index++] = parser->GetCurPos();
|
||
|
|
if (buf_index == nParams)
|
||
|
|
buf_index = 0;
|
||
|
|
|
||
|
|
buf_count++;
|
||
|
|
if (buf_count > nParams)
|
||
|
|
buf_count = nParams;
|
||
|
|
|
||
|
|
ByteStringView word = parser->GetWord();
|
||
|
|
if (word.IsEmpty())
|
||
|
|
return false;
|
||
|
|
|
||
|
|
if (word == token) {
|
||
|
|
if (buf_count < nParams)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
parser->SetCurPos(pBuf[buf_index]);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace
|
||
|
|
|
||
|
|
CPDF_DefaultAppearance::CPDF_DefaultAppearance() = default;
|
||
|
|
|
||
|
|
CPDF_DefaultAppearance::CPDF_DefaultAppearance(const ByteString& csDA)
|
||
|
|
: m_csDA(csDA) {}
|
||
|
|
|
||
|
|
CPDF_DefaultAppearance::CPDF_DefaultAppearance(
|
||
|
|
const CPDF_DefaultAppearance& cDA) = default;
|
||
|
|
|
||
|
|
CPDF_DefaultAppearance::~CPDF_DefaultAppearance() = default;
|
||
|
|
|
||
|
|
absl::optional<ByteString> CPDF_DefaultAppearance::GetFont(
|
||
|
|
float* fFontSize) const {
|
||
|
|
*fFontSize = 0.0f;
|
||
|
|
if (m_csDA.IsEmpty())
|
||
|
|
return absl::nullopt;
|
||
|
|
|
||
|
|
ByteString csFontNameTag;
|
||
|
|
CPDF_SimpleParser syntax(m_csDA.AsStringView().raw_span());
|
||
|
|
if (FindTagParamFromStart(&syntax, "Tf", 2)) {
|
||
|
|
csFontNameTag = ByteString(syntax.GetWord());
|
||
|
|
csFontNameTag.Delete(0, 1);
|
||
|
|
*fFontSize = StringToFloat(syntax.GetWord());
|
||
|
|
}
|
||
|
|
return PDF_NameDecode(csFontNameTag.AsStringView());
|
||
|
|
}
|
||
|
|
|
||
|
|
absl::optional<CFX_Color> CPDF_DefaultAppearance::GetColor() const {
|
||
|
|
if (m_csDA.IsEmpty())
|
||
|
|
return absl::nullopt;
|
||
|
|
|
||
|
|
float fc[4];
|
||
|
|
CPDF_SimpleParser syntax(m_csDA.AsStringView().raw_span());
|
||
|
|
if (FindTagParamFromStart(&syntax, "g", 1)) {
|
||
|
|
fc[0] = StringToFloat(syntax.GetWord());
|
||
|
|
return CFX_Color(CFX_Color::Type::kGray, fc[0]);
|
||
|
|
}
|
||
|
|
if (FindTagParamFromStart(&syntax, "rg", 3)) {
|
||
|
|
fc[0] = StringToFloat(syntax.GetWord());
|
||
|
|
fc[1] = StringToFloat(syntax.GetWord());
|
||
|
|
fc[2] = StringToFloat(syntax.GetWord());
|
||
|
|
return CFX_Color(CFX_Color::Type::kRGB, fc[0], fc[1], fc[2]);
|
||
|
|
}
|
||
|
|
if (FindTagParamFromStart(&syntax, "k", 4)) {
|
||
|
|
fc[0] = StringToFloat(syntax.GetWord());
|
||
|
|
fc[1] = StringToFloat(syntax.GetWord());
|
||
|
|
fc[2] = StringToFloat(syntax.GetWord());
|
||
|
|
fc[3] = StringToFloat(syntax.GetWord());
|
||
|
|
return CFX_Color(CFX_Color::Type::kCMYK, fc[0], fc[1], fc[2], fc[3]);
|
||
|
|
}
|
||
|
|
return absl::nullopt;
|
||
|
|
}
|
||
|
|
|
||
|
|
absl::optional<CFX_Color::TypeAndARGB> CPDF_DefaultAppearance::GetColorARGB()
|
||
|
|
const {
|
||
|
|
absl::optional<CFX_Color> maybe_color = GetColor();
|
||
|
|
if (!maybe_color.has_value())
|
||
|
|
return absl::nullopt;
|
||
|
|
|
||
|
|
const CFX_Color& color = maybe_color.value();
|
||
|
|
if (color.nColorType == CFX_Color::Type::kGray) {
|
||
|
|
int g = static_cast<int>(color.fColor1 * 255 + 0.5f);
|
||
|
|
return CFX_Color::TypeAndARGB(CFX_Color::Type::kGray,
|
||
|
|
ArgbEncode(255, g, g, g));
|
||
|
|
}
|
||
|
|
if (color.nColorType == CFX_Color::Type::kRGB) {
|
||
|
|
int r = static_cast<int>(color.fColor1 * 255 + 0.5f);
|
||
|
|
int g = static_cast<int>(color.fColor2 * 255 + 0.5f);
|
||
|
|
int b = static_cast<int>(color.fColor3 * 255 + 0.5f);
|
||
|
|
return CFX_Color::TypeAndARGB(CFX_Color::Type::kRGB,
|
||
|
|
ArgbEncode(255, r, g, b));
|
||
|
|
}
|
||
|
|
if (color.nColorType == CFX_Color::Type::kCMYK) {
|
||
|
|
float r = 1.0f - std::min(1.0f, color.fColor1 + color.fColor4);
|
||
|
|
float g = 1.0f - std::min(1.0f, color.fColor2 + color.fColor4);
|
||
|
|
float b = 1.0f - std::min(1.0f, color.fColor3 + color.fColor4);
|
||
|
|
return CFX_Color::TypeAndARGB(
|
||
|
|
CFX_Color::Type::kCMYK,
|
||
|
|
ArgbEncode(255, static_cast<int>(r * 255 + 0.5f),
|
||
|
|
static_cast<int>(g * 255 + 0.5f),
|
||
|
|
static_cast<int>(b * 255 + 0.5f)));
|
||
|
|
}
|
||
|
|
NOTREACHED();
|
||
|
|
return absl::nullopt;
|
||
|
|
}
|
||
|
|
|
||
|
|
// static
|
||
|
|
bool CPDF_DefaultAppearance::FindTagParamFromStartForTesting(
|
||
|
|
CPDF_SimpleParser* parser,
|
||
|
|
ByteStringView token,
|
||
|
|
int nParams) {
|
||
|
|
return FindTagParamFromStart(parser, token, nParams);
|
||
|
|
}
|