summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
authorcaryclark <caryclark@google.com>2016-04-12 05:08:17 -0700
committerCommit bot <commit-bot@chromium.org>2016-04-12 05:08:17 -0700
commitf9924422a4cd1d1b6d2d4240c83b5c1082da3629 (patch)
tree94b978e3ee586645eccb6ad6c0d35d3ba7c808b1 /core/fpdfapi
parent822484b5f88d92dbcd567b1c2da38af1e720b56f (diff)
downloadpdfium-f9924422a4cd1d1b6d2d4240c83b5c1082da3629.tar.xz
flesh out gradient shaders
Using these webpages as guides http://www.globelegislators.org/pdfjs/test/pdfs/alphatrans.pdf http://www.antennahouse.com/antenna1/wp-content/uploads/2015/07/background-image-gradient-1.pdf flesh out the gradient shaders to include the PostScript Type 0 sampling function and to include radial gradients. This CL makes rendering these pages agree with Adobe Reader output. Some of these examples use an Extend array to clip the gradient. Skia does not currently support this natively, so construct the clip manually for now. Other PDF pages may construct gradients using alternate mechanisms -- this code will continue to be refactored as those come to light. In particular, this CL sets up the clip and matrix differently for axial gradients and radial gradients -- while it makes sense to do it one way only, I prefer to defer until I have more examples to work with. R=dsinclair@chromium.org,tsepez@chromium.org Review URL: https://codereview.chromium.org/1870463002
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_func.cpp86
-rw-r--r--core/fpdfapi/fpdf_page/pageint.h28
-rw-r--r--core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp4
3 files changed, 63 insertions, 55 deletions
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
index b00ab73af1..31faf6a2d7 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
@@ -491,28 +491,40 @@ static uint32_t _GetBits32(const uint8_t* pData, int bitpos, int nbits) {
}
return result;
}
-typedef struct {
- FX_FLOAT encode_max, encode_min;
- int sizes;
-} SampleEncodeInfo;
-typedef struct { FX_FLOAT decode_max, decode_min; } SampleDecodeInfo;
-class CPDF_SampledFunc : public CPDF_Function {
+class CPDF_PSFunc : public CPDF_Function {
public:
- CPDF_SampledFunc();
- ~CPDF_SampledFunc() override;
-
+ CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {}
// CPDF_Function
FX_BOOL v_Init(CPDF_Object* pObj) override;
FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
- SampleEncodeInfo* m_pEncodeInfo;
- SampleDecodeInfo* m_pDecodeInfo;
- uint32_t m_nBitsPerSample;
- uint32_t m_SampleMax;
- CPDF_StreamAcc* m_pSampleStream;
+ private:
+ CPDF_PSEngine m_PS;
};
+FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) {
+ CPDF_StreamAcc acc;
+ acc.LoadAllData(pObj->AsStream(), FALSE);
+ return m_PS.Parse(reinterpret_cast<const FX_CHAR*>(acc.GetData()),
+ acc.GetSize());
+}
+
+FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
+ CPDF_PSEngine& PS = const_cast<CPDF_PSEngine&>(m_PS);
+ PS.Reset();
+ for (uint32_t i = 0; i < m_nInputs; i++)
+ PS.Push(inputs[i]);
+ PS.Execute();
+ if (PS.GetStackSize() < m_nOutputs)
+ return FALSE;
+ for (uint32_t i = 0; i < m_nOutputs; i++)
+ results[m_nOutputs - i - 1] = PS.Pop();
+ return TRUE;
+}
+
+} // namespace
+
CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {
m_pSampleStream = NULL;
m_pEncodeInfo = NULL;
@@ -524,6 +536,7 @@ CPDF_SampledFunc::~CPDF_SampledFunc() {
FX_Free(m_pEncodeInfo);
FX_Free(m_pDecodeInfo);
}
+
FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
CPDF_Stream* pStream = pObj->AsStream();
if (!pStream)
@@ -579,13 +592,14 @@ FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) {
}
return TRUE;
}
+
FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
int pos = 0;
CFX_FixedBufGrow<FX_FLOAT, 16> encoded_input_buf(m_nInputs);
FX_FLOAT* encoded_input = encoded_input_buf;
- CFX_FixedBufGrow<int, 32> int_buf(m_nInputs * 2);
- int* index = int_buf;
- int* blocksize = index + m_nInputs;
+ CFX_FixedBufGrow<uint32_t, 32> int_buf(m_nInputs * 2);
+ uint32_t* index = int_buf;
+ uint32_t* blocksize = index + m_nInputs;
for (uint32_t i = 0; i < m_nInputs; i++) {
if (i == 0)
blocksize[i] = 1;
@@ -594,11 +608,8 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
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);
- index[i] = (int)encoded_input[i];
- if (index[i] < 0)
- index[i] = 0;
- else if (index[i] > m_pEncodeInfo[i].sizes - 1)
- index[i] = m_pEncodeInfo[i].sizes - 1;
+ index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]),
+ m_pEncodeInfo[i].sizes - 1);
pos += index[i] * blocksize[i];
}
FX_SAFE_INT32 bits_to_output = m_nOutputs;
@@ -650,37 +661,6 @@ FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
return TRUE;
}
-class CPDF_PSFunc : public CPDF_Function {
- public:
- // CPDF_Function
- CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {}
- FX_BOOL v_Init(CPDF_Object* pObj) override;
- FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
-
- CPDF_PSEngine m_PS;
-};
-
-FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) {
- CPDF_Stream* pStream = pObj->AsStream();
- CPDF_StreamAcc acc;
- acc.LoadAllData(pStream, FALSE);
- return m_PS.Parse((const FX_CHAR*)acc.GetData(), acc.GetSize());
-}
-FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
- CPDF_PSEngine& PS = (CPDF_PSEngine&)m_PS;
- PS.Reset();
- for (uint32_t i = 0; i < m_nInputs; i++)
- PS.Push(inputs[i]);
- PS.Execute();
- if (PS.GetStackSize() < m_nOutputs)
- return FALSE;
- for (uint32_t i = 0; i < m_nOutputs; i++)
- results[m_nOutputs - i - 1] = PS.Pop();
- return TRUE;
-}
-
-} // namespace
-
CPDF_ExpIntFunc::CPDF_ExpIntFunc()
: CPDF_Function(Type::kType2ExpotentialInterpolation) {
m_pBeginValues = NULL;
diff --git a/core/fpdfapi/fpdf_page/pageint.h b/core/fpdfapi/fpdf_page/pageint.h
index e6496cfd20..98a05d5495 100644
--- a/core/fpdfapi/fpdf_page/pageint.h
+++ b/core/fpdfapi/fpdf_page/pageint.h
@@ -393,6 +393,7 @@ class CPDF_Function {
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]; }
Type GetType() const { return m_Type; }
protected:
@@ -423,6 +424,33 @@ class CPDF_ExpIntFunc : public CPDF_Function {
FX_FLOAT* m_pEndValues;
};
+class CPDF_SampledFunc : public CPDF_Function {
+ public:
+ struct SampleEncodeInfo {
+ FX_FLOAT encode_max;
+ FX_FLOAT encode_min;
+ uint32_t sizes;
+ };
+
+ struct SampleDecodeInfo {
+ FX_FLOAT decode_max;
+ FX_FLOAT decode_min;
+ };
+
+ CPDF_SampledFunc();
+ ~CPDF_SampledFunc() override;
+
+ // CPDF_Function
+ FX_BOOL v_Init(CPDF_Object* pObj) override;
+ FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
+
+ SampleEncodeInfo* m_pEncodeInfo;
+ SampleDecodeInfo* m_pDecodeInfo;
+ uint32_t m_nBitsPerSample;
+ uint32_t m_SampleMax;
+ CPDF_StreamAcc* m_pSampleStream;
+};
+
class CPDF_StitchFunc : public CPDF_Function {
public:
CPDF_StitchFunc();
diff --git a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
index 3f98279dbf..48f9f5d98a 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp
@@ -855,8 +855,8 @@ void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern,
clip_rect.Intersect(rect.GetOutterRect());
}
if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SHADING &&
- m_pDevice->GetDeviceDriver()->DrawShading(pPattern, pMatrix, alpha,
- bAlphaMode)) {
+ m_pDevice->GetDeviceDriver()->DrawShading(pPattern, pMatrix, clip_rect,
+ alpha, bAlphaMode)) {
return;
}
CPDF_DeviceBuffer buffer;