summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_func.cpp91
-rw-r--r--core/fpdfapi/fpdf_page/pageint.h30
-rw-r--r--core/fxge/skia/fx_skia_device.cpp98
3 files changed, 122 insertions, 97 deletions
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
index 1acf62b596..c9b0ea236e 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
@@ -515,7 +515,7 @@ uint32_t GetBits32(const uint8_t* pData, int bitpos, int nbits) {
class CPDF_PSFunc : public CPDF_Function {
public:
- CPDF_PSFunc() {}
+ CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {}
~CPDF_PSFunc() override {}
// CPDF_Function
@@ -548,7 +548,7 @@ FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
} // namespace
-CPDF_SampledFunc::CPDF_SampledFunc() {}
+CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {}
CPDF_SampledFunc::~CPDF_SampledFunc() {}
@@ -569,20 +569,19 @@ FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
m_pSampleStream.reset(new CPDF_StreamAcc);
m_pSampleStream->LoadAllData(pStream, FALSE);
FX_SAFE_UINT32 nTotalSampleBits = 1;
- m_pEncodeInfo.resize(m_nInputs);
+ m_EncodeInfo.resize(m_nInputs);
for (uint32_t i = 0; i < m_nInputs; i++) {
- m_pEncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0;
+ m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0;
if (!pSize && i == 0)
- m_pEncodeInfo[i].sizes = pDict->GetIntegerBy("Size");
- nTotalSampleBits *= m_pEncodeInfo[i].sizes;
+ m_EncodeInfo[i].sizes = pDict->GetIntegerBy("Size");
+ nTotalSampleBits *= m_EncodeInfo[i].sizes;
if (pEncode) {
- m_pEncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2);
- m_pEncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1);
+ m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2);
+ m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1);
} else {
- m_pEncodeInfo[i].encode_min = 0;
- m_pEncodeInfo[i].encode_max = m_pEncodeInfo[i].sizes == 1
- ? 1
- : (FX_FLOAT)m_pEncodeInfo[i].sizes - 1;
+ m_EncodeInfo[i].encode_min = 0;
+ m_EncodeInfo[i].encode_max =
+ m_EncodeInfo[i].sizes == 1 ? 1 : (FX_FLOAT)m_EncodeInfo[i].sizes - 1;
}
}
nTotalSampleBits *= m_nBitsPerSample;
@@ -594,14 +593,14 @@ FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) {
return FALSE;
}
- m_pDecodeInfo.resize(m_nOutputs);
+ m_DecodeInfo.resize(m_nOutputs);
for (uint32_t i = 0; i < m_nOutputs; i++) {
if (pDecode) {
- m_pDecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i);
- m_pDecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1);
+ m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i);
+ m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1);
} else {
- m_pDecodeInfo[i].decode_min = m_pRanges[i * 2];
- m_pDecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
+ m_DecodeInfo[i].decode_min = m_pRanges[i * 2];
+ m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1];
}
}
return TRUE;
@@ -618,12 +617,12 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
if (i == 0)
blocksize[i] = 1;
else
- blocksize[i] = blocksize[i - 1] * m_pEncodeInfo[i - 1].sizes;
- encoded_input[i] = PDF_Interpolate(
- inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
- m_pEncodeInfo[i].encode_min, m_pEncodeInfo[i].encode_max);
+ blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes;
+ encoded_input[i] =
+ PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1],
+ m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max);
index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]),
- m_pEncodeInfo[i].sizes - 1);
+ m_EncodeInfo[i].sizes - 1);
pos += index[i] * blocksize[i];
}
FX_SAFE_INT32 bits_to_output = m_nOutputs;
@@ -651,7 +650,7 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
m_nBitsPerSample);
FX_FLOAT encoded = (FX_FLOAT)sample;
for (uint32_t i = 0; i < m_nInputs; i++) {
- if (index[i] == m_pEncodeInfo[i].sizes - 1) {
+ if (index[i] == m_EncodeInfo[i].sizes - 1) {
if (index[i] == 0)
encoded = encoded_input[i] * (FX_FLOAT)sample;
} else {
@@ -668,17 +667,17 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
((FX_FLOAT)sample1 - (FX_FLOAT)sample);
}
}
- results[j] = PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax,
- m_pDecodeInfo[j].decode_min,
- m_pDecodeInfo[j].decode_max);
+ results[j] =
+ PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax,
+ m_DecodeInfo[j].decode_min, m_DecodeInfo[j].decode_max);
}
return TRUE;
}
-CPDF_ExpIntFunc::CPDF_ExpIntFunc() {
- m_pBeginValues = NULL;
- m_pEndValues = NULL;
-}
+CPDF_ExpIntFunc::CPDF_ExpIntFunc()
+ : CPDF_Function(Type::kType2ExpotentialInterpolation),
+ m_pBeginValues(nullptr),
+ m_pEndValues(nullptr) {}
CPDF_ExpIntFunc::~CPDF_ExpIntFunc() {
FX_Free(m_pBeginValues);
@@ -722,10 +721,10 @@ FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
return TRUE;
}
-CPDF_StitchFunc::CPDF_StitchFunc() {
- m_pBounds = NULL;
- m_pEncode = NULL;
-}
+CPDF_StitchFunc::CPDF_StitchFunc()
+ : CPDF_Function(Type::kType3Stitching),
+ m_pBounds(nullptr),
+ m_pEncode(nullptr) {}
CPDF_StitchFunc::~CPDF_StitchFunc() {
FX_Free(m_pBounds);
@@ -840,10 +839,8 @@ CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) {
}
}
-CPDF_Function::CPDF_Function() {
- m_pDomains = NULL;
- m_pRanges = NULL;
-}
+CPDF_Function::CPDF_Function(Type type)
+ : m_pDomains(nullptr), m_pRanges(nullptr), m_Type(type) {}
CPDF_Function::~CPDF_Function() {
FX_Free(m_pDomains);
@@ -912,3 +909,21 @@ FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs,
}
return TRUE;
}
+
+const CPDF_SampledFunc* CPDF_Function::ToSampledFunc() const {
+ return m_Type == Type::kType0Sampled
+ ? static_cast<const CPDF_SampledFunc*>(this)
+ : nullptr;
+}
+
+const CPDF_ExpIntFunc* CPDF_Function::ToExpIntFunc() const {
+ return m_Type == Type::kType2ExpotentialInterpolation
+ ? static_cast<const CPDF_ExpIntFunc*>(this)
+ : nullptr;
+}
+
+const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const {
+ return m_Type == Type::kType3Stitching
+ ? static_cast<const CPDF_StitchFunc*>(this)
+ : nullptr;
+}
diff --git a/core/fpdfapi/fpdf_page/pageint.h b/core/fpdfapi/fpdf_page/pageint.h
index 8d507a181d..64d106f1dc 100644
--- a/core/fpdfapi/fpdf_page/pageint.h
+++ b/core/fpdfapi/fpdf_page/pageint.h
@@ -19,6 +19,7 @@
class CPDF_AllStates;
class CPDF_ColorSpace;
+class CPDF_ExpIntFunc;
class CPDF_Font;
class CPDF_FontEncoding;
class CPDF_Form;
@@ -27,6 +28,8 @@ class CPDF_Image;
class CPDF_ImageObject;
class CPDF_Page;
class CPDF_Pattern;
+class CPDF_SampledFunc;
+class CPDF_StitchFunc;
class CPDF_StreamAcc;
class CPDF_TextObject;
class CPDF_Type3Char;
@@ -384,9 +387,15 @@ class CPDF_Function {
int& nresults) const;
uint32_t CountInputs() const { return m_nInputs; }
uint32_t CountOutputs() const { return m_nOutputs; }
+ FX_FLOAT GetDomain(int i) const { return m_pDomains[i]; }
+ FX_FLOAT GetRange(int i) const { return m_pRanges[i]; }
+
+ const CPDF_SampledFunc* ToSampledFunc() const;
+ const CPDF_ExpIntFunc* ToExpIntFunc() const;
+ const CPDF_StitchFunc* ToStitchFunc() const;
protected:
- CPDF_Function();
+ explicit CPDF_Function(Type type);
FX_BOOL Init(CPDF_Object* pObj);
virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0;
@@ -396,6 +405,7 @@ class CPDF_Function {
uint32_t m_nOutputs;
FX_FLOAT* m_pDomains;
FX_FLOAT* m_pRanges;
+ const Type m_Type;
};
class CPDF_ExpIntFunc : public CPDF_Function {
@@ -433,9 +443,17 @@ class CPDF_SampledFunc : public CPDF_Function {
FX_BOOL v_Init(CPDF_Object* pObj) override;
FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
+ const std::vector<SampleEncodeInfo>& GetEncodeInfo() const {
+ return m_EncodeInfo;
+ }
+ uint32_t GetBitsPerSample() const { return m_nBitsPerSample; }
+ const CPDF_StreamAcc* GetSampleStream() const {
+ return m_pSampleStream.get();
+ }
+
private:
- std::vector<SampleEncodeInfo> m_pEncodeInfo;
- std::vector<SampleDecodeInfo> m_pDecodeInfo;
+ std::vector<SampleEncodeInfo> m_EncodeInfo;
+ std::vector<SampleDecodeInfo> m_DecodeInfo;
uint32_t m_nBitsPerSample;
uint32_t m_SampleMax;
std::unique_ptr<CPDF_StreamAcc> m_pSampleStream;
@@ -450,6 +468,12 @@ class CPDF_StitchFunc : public CPDF_Function {
FX_BOOL v_Init(CPDF_Object* pObj) override;
FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
+ const std::vector<std::unique_ptr<CPDF_Function>>& GetSubFunctions() const {
+ return m_pSubFunctions;
+ }
+ FX_FLOAT GetBound(size_t i) const { return m_pBounds[i]; }
+
+ private:
std::vector<std::unique_ptr<CPDF_Function>> m_pSubFunctions;
FX_FLOAT* m_pBounds;
FX_FLOAT* m_pEncode;
diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp
index d6d8218d57..3168e2251b 100644
--- a/core/fxge/skia/fx_skia_device.cpp
+++ b/core/fxge/skia/fx_skia_device.cpp
@@ -156,25 +156,21 @@ SkXfermode::Mode GetSkiaBlendMode(int blend_type) {
}
}
-bool AddColors(const CPDF_Function* pFunc, SkTDArray<SkColor>* skColors) {
+bool AddColors(const CPDF_ExpIntFunc* pFunc, SkTDArray<SkColor>* skColors) {
if (pFunc->CountInputs() != 1)
return false;
- ASSERT(CPDF_Function::Type::kType2ExpotentialInterpolation ==
- pFunc->GetType());
- const CPDF_ExpIntFunc* expIntFunc =
- static_cast<const CPDF_ExpIntFunc*>(pFunc);
- if (expIntFunc->m_Exponent != 1)
+ if (pFunc->m_Exponent != 1)
return false;
- if (expIntFunc->m_nOrigOutputs != 3)
+ if (pFunc->m_nOrigOutputs != 3)
return false;
- skColors->push(SkColorSetARGB(
- 0xFF, SkUnitScalarClampToByte(expIntFunc->m_pBeginValues[0]),
- SkUnitScalarClampToByte(expIntFunc->m_pBeginValues[1]),
- SkUnitScalarClampToByte(expIntFunc->m_pBeginValues[2])));
skColors->push(
- SkColorSetARGB(0xFF, SkUnitScalarClampToByte(expIntFunc->m_pEndValues[0]),
- SkUnitScalarClampToByte(expIntFunc->m_pEndValues[1]),
- SkUnitScalarClampToByte(expIntFunc->m_pEndValues[2])));
+ SkColorSetARGB(0xFF, SkUnitScalarClampToByte(pFunc->m_pBeginValues[0]),
+ SkUnitScalarClampToByte(pFunc->m_pBeginValues[1]),
+ SkUnitScalarClampToByte(pFunc->m_pBeginValues[2])));
+ skColors->push(
+ SkColorSetARGB(0xFF, SkUnitScalarClampToByte(pFunc->m_pEndValues[0]),
+ SkUnitScalarClampToByte(pFunc->m_pEndValues[1]),
+ SkUnitScalarClampToByte(pFunc->m_pEndValues[2])));
return true;
}
@@ -213,39 +209,35 @@ uint8_t FloatToByte(FX_FLOAT f) {
return (uint8_t)(f * 255.99f);
}
-bool AddSamples(const CPDF_Function* pFunc,
+bool AddSamples(const CPDF_SampledFunc* pFunc,
SkTDArray<SkColor>* skColors,
SkTDArray<SkScalar>* skPos) {
if (pFunc->CountInputs() != 1)
return false;
if (pFunc->CountOutputs() != 3) // expect rgb
return false;
- ASSERT(CPDF_Function::Type::kType0Sampled == pFunc->GetType());
- const CPDF_SampledFunc* sampledFunc =
- static_cast<const CPDF_SampledFunc*>(pFunc);
- if (!sampledFunc->m_pEncodeInfo)
+ if (pFunc->GetEncodeInfo().empty())
return false;
const CPDF_SampledFunc::SampleEncodeInfo& encodeInfo =
- sampledFunc->m_pEncodeInfo[0];
+ pFunc->GetEncodeInfo()[0];
if (encodeInfo.encode_min != 0)
return false;
if (encodeInfo.encode_max != encodeInfo.sizes - 1)
return false;
- uint32_t sampleSize = sampledFunc->m_nBitsPerSample;
+ uint32_t sampleSize = pFunc->GetBitsPerSample();
uint32_t sampleCount = encodeInfo.sizes;
if (sampleCount != 1U << sampleSize)
return false;
- if (sampledFunc->m_pSampleStream->GetSize() <
- sampleCount * 3 * sampleSize / 8) {
+ if (pFunc->GetSampleStream()->GetSize() < sampleCount * 3 * sampleSize / 8)
return false;
- }
+
FX_FLOAT colorsMin[3];
FX_FLOAT colorsMax[3];
for (int i = 0; i < 3; ++i) {
- colorsMin[i] = sampledFunc->GetRange(i * 2);
- colorsMax[i] = sampledFunc->GetRange(i * 2 + 1);
+ colorsMin[i] = pFunc->GetRange(i * 2);
+ colorsMax[i] = pFunc->GetRange(i * 2 + 1);
}
- const uint8_t* pSampleData = sampledFunc->m_pSampleStream->GetData();
+ const uint8_t* pSampleData = pFunc->GetSampleStream()->GetData();
for (uint32_t i = 0; i < sampleCount; ++i) {
FX_FLOAT floatColors[3];
for (uint32_t j = 0; j < 3; ++j) {
@@ -262,24 +254,21 @@ bool AddSamples(const CPDF_Function* pFunc,
return true;
}
-bool AddStitching(const CPDF_Function* pFunc,
+bool AddStitching(const CPDF_StitchFunc* pFunc,
SkTDArray<SkColor>* skColors,
SkTDArray<SkScalar>* skPos) {
int inputs = pFunc->CountInputs();
- ASSERT(CPDF_Function::Type::kType3Stitching == pFunc->GetType());
- const CPDF_StitchFunc* stitchFunc =
- static_cast<const CPDF_StitchFunc*>(pFunc);
- FX_FLOAT boundsStart = stitchFunc->GetDomain(0);
+ FX_FLOAT boundsStart = pFunc->GetDomain(0);
+ const auto& subFunctions = pFunc->GetSubFunctions();
for (int i = 0; i < inputs; ++i) {
- const CPDF_Function* pSubFunc = stitchFunc->m_pSubFunctions[i];
- if (pSubFunc->GetType() !=
- CPDF_Function::Type::kType2ExpotentialInterpolation)
+ const CPDF_ExpIntFunc* pSubFunc = subFunctions[i]->ToExpIntFunc();
+ if (!pSubFunc)
return false;
if (!AddColors(pSubFunc, skColors))
return false;
FX_FLOAT boundsEnd =
- i < inputs - 1 ? stitchFunc->m_pBounds[i] : stitchFunc->GetDomain(1);
+ i < inputs - 1 ? pFunc->GetBound(i) : pFunc->GetDomain(1);
skPos->push(boundsStart);
skPos->push(boundsEnd);
boundsStart = boundsEnd;
@@ -814,27 +803,24 @@ FX_BOOL CFX_SkiaDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern,
const CPDF_Function* pFunc = pFuncs[j];
if (!pFunc)
continue;
- switch (pFunc->GetType()) {
- case CPDF_Function::Type::kType0Sampled:
- /* TODO(caryclark)
- Type 0 Sampled Functions in PostScript can also have an Order integer
- in the dictionary. PDFium doesn't appear to check for this anywhere.
- */
- if (!AddSamples(pFunc, &skColors, &skPos))
- return false;
- break;
- case CPDF_Function::Type::kType2ExpotentialInterpolation:
- if (!AddColors(pFunc, &skColors))
- return false;
- skPos.push(0);
- skPos.push(1);
- break;
- case CPDF_Function::Type::kType3Stitching:
- if (!AddStitching(pFunc, &skColors, &skPos))
- return false;
- break;
- default:
+
+ if (const CPDF_SampledFunc* pSampledFunc = pFunc->ToSampledFunc()) {
+ /* TODO(caryclark)
+ Type 0 Sampled Functions in PostScript can also have an Order integer
+ in the dictionary. PDFium doesn't appear to check for this anywhere.
+ */
+ if (!AddSamples(pSampledFunc, &skColors, &skPos))
return false;
+ } else if (const CPDF_ExpIntFunc* pExpIntFuc = pFunc->ToExpIntFunc()) {
+ if (!AddColors(pExpIntFuc, &skColors))
+ return false;
+ skPos.push(0);
+ skPos.push(1);
+ } else if (const CPDF_StitchFunc* pStitchFunc = pFunc->ToStitchFunc()) {
+ if (!AddStitching(pStitchFunc, &skColors, &skPos))
+ return false;
+ } else {
+ return false;
}
}
CPDF_Array* pArray = pDict->GetArrayBy("Extend");