diff options
-rw-r--r-- | core/fpdfapi/fpdf_page/fpdf_page_func.cpp | 91 | ||||
-rw-r--r-- | core/fpdfapi/fpdf_page/pageint.h | 30 | ||||
-rw-r--r-- | core/fxge/skia/fx_skia_device.cpp | 98 |
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"); |