summaryrefslogtreecommitdiff
path: root/core/fpdfapi
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi')
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp7
-rw-r--r--core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp99
-rw-r--r--core/fpdfapi/page/cpdf_path.cpp17
-rw-r--r--core/fpdfapi/page/cpdf_path.h8
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.cpp10
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.cpp59
6 files changed, 74 insertions, 126 deletions
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
index 4de89a47de..ff8b676de1 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp
@@ -148,14 +148,13 @@ void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf* buf,
void CPDF_PageContentGenerator::ProcessPath(CFX_ByteTextBuf* buf,
CPDF_PathObject* pPathObj) {
ProcessGraphics(buf, pPathObj);
- const FX_PATHPOINT* pPoints = pPathObj->m_Path.GetPoints();
+ auto& pPoints = pPathObj->m_Path.GetPoints();
if (pPathObj->m_Path.IsRect()) {
*buf << pPoints[0].m_PointX << " " << pPoints[0].m_PointY << " "
<< (pPoints[2].m_PointX - pPoints[0].m_PointX) << " "
<< (pPoints[2].m_PointY - pPoints[0].m_PointY) << " re";
} else {
- int numPoints = pPathObj->m_Path.GetPointCount();
- for (int i = 0; i < numPoints; i++) {
+ for (size_t i = 0; i < pPoints.size(); i++) {
if (i > 0)
*buf << " ";
*buf << pPoints[i].m_PointX << " " << pPoints[i].m_PointY;
@@ -165,7 +164,7 @@ void CPDF_PageContentGenerator::ProcessPath(CFX_ByteTextBuf* buf,
} else if (pointType == FXPT_TYPE::LineTo) {
*buf << " l";
} else if (pointType == FXPT_TYPE::BezierTo) {
- if (i + 2 >= numPoints ||
+ if (i + 2 >= pPoints.size() ||
!pPoints[i].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
!pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::BezierTo) ||
pPoints[i + 2].m_Type != FXPT_TYPE::BezierTo) {
diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
index 0a636a1888..42e6e2d843 100644
--- a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
+++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp
@@ -44,6 +44,7 @@ TEST_F(CPDF_PageContentGeneratorTest, ProcessRect) {
pPathObj->m_Path.AppendRect(10, 5, 13, 30);
pPathObj->m_FillType = FXFILL_ALTERNATE;
pPathObj->m_bStroke = true;
+
auto pTestPage = pdfium::MakeUnique<CPDF_Page>(nullptr, nullptr, false);
CPDF_PageContentGenerator generator(pTestPage.get());
CFX_ByteTextBuf buf;
@@ -51,77 +52,33 @@ TEST_F(CPDF_PageContentGeneratorTest, ProcessRect) {
EXPECT_EQ("q 10 5 3 25 re B* Q\n", buf.MakeString());
pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
- pPathObj->m_Path.SetPointCount(4);
- FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints();
- pPoints[0].m_PointX = 0;
- pPoints[0].m_PointY = 0;
- pPoints[0].m_Type = FXPT_TYPE::MoveTo;
- pPoints[0].m_CloseFigure = false;
- pPoints[1].m_PointX = 5.2f;
- pPoints[1].m_PointY = 0;
- pPoints[1].m_Type = FXPT_TYPE::LineTo;
- pPoints[1].m_CloseFigure = false;
- pPoints[2].m_PointX = 5.2f;
- pPoints[2].m_PointY = 3.78f;
- pPoints[2].m_Type = FXPT_TYPE::LineTo;
- pPoints[2].m_CloseFigure = false;
- pPoints[3].m_PointX = 0;
- pPoints[3].m_PointY = 3.78f;
- pPoints[3].m_Type = FXPT_TYPE::LineTo;
- pPoints[3].m_CloseFigure = true;
+ pPathObj->m_Path.AppendPoint(0, 0, FXPT_TYPE::MoveTo, false);
+ pPathObj->m_Path.AppendPoint(5.2f, 0, FXPT_TYPE::LineTo, false);
+ pPathObj->m_Path.AppendPoint(5.2f, 3.78f, FXPT_TYPE::LineTo, false);
+ pPathObj->m_Path.AppendPoint(0, 3.78f, FXPT_TYPE::LineTo, true);
pPathObj->m_FillType = 0;
pPathObj->m_bStroke = false;
buf.Clear();
+
TestProcessPath(&generator, &buf, pPathObj.get());
EXPECT_EQ("q 0 0 5.2 3.78 re n Q\n", buf.MakeString());
}
TEST_F(CPDF_PageContentGeneratorTest, ProcessPath) {
auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
- pPathObj->m_Path.SetPointCount(10);
- FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints();
- pPoints[0].m_PointX = 3.102f;
- pPoints[0].m_PointY = 4.67f;
- pPoints[0].m_Type = FXPT_TYPE::MoveTo;
- pPoints[0].m_CloseFigure = false;
- pPoints[1].m_PointX = 5.45f;
- pPoints[1].m_PointY = 0.29f;
- pPoints[1].m_Type = FXPT_TYPE::LineTo;
- pPoints[1].m_CloseFigure = false;
- pPoints[2].m_PointX = 4.24f;
- pPoints[2].m_PointY = 3.15f;
- pPoints[2].m_Type = FXPT_TYPE::BezierTo;
- pPoints[2].m_CloseFigure = false;
- pPoints[3].m_PointX = 4.65f;
- pPoints[3].m_PointY = 2.98f;
- pPoints[3].m_Type = FXPT_TYPE::BezierTo;
- pPoints[3].m_CloseFigure = false;
- pPoints[4].m_PointX = 3.456f;
- pPoints[4].m_PointY = 0.24f;
- pPoints[4].m_Type = FXPT_TYPE::BezierTo;
- pPoints[4].m_CloseFigure = false;
- pPoints[5].m_PointX = 10.6f;
- pPoints[5].m_PointY = 11.15f;
- pPoints[5].m_Type = FXPT_TYPE::LineTo;
- pPoints[5].m_CloseFigure = false;
- pPoints[6].m_PointX = 11;
- pPoints[6].m_PointY = 12.5f;
- pPoints[6].m_Type = FXPT_TYPE::LineTo;
- pPoints[6].m_CloseFigure = false;
- pPoints[7].m_PointX = 11.46f;
- pPoints[7].m_PointY = 12.67f;
- pPoints[7].m_Type = FXPT_TYPE::BezierTo;
- pPoints[7].m_CloseFigure = false;
- pPoints[8].m_PointX = 11.84f;
- pPoints[8].m_PointY = 12.96f;
- pPoints[8].m_Type = FXPT_TYPE::BezierTo;
- pPoints[8].m_CloseFigure = false;
- pPoints[9].m_PointX = 12;
- pPoints[9].m_PointY = 13.64f;
- pPoints[9].m_Type = FXPT_TYPE::BezierTo;
- pPoints[9].m_CloseFigure = true;
+ pPathObj->m_Path.AppendPoint(3.102f, 4.67f, FXPT_TYPE::MoveTo, false);
+ pPathObj->m_Path.AppendPoint(5.45f, 0.29f, FXPT_TYPE::LineTo, false);
+ pPathObj->m_Path.AppendPoint(4.24f, 3.15f, FXPT_TYPE::BezierTo, false);
+ pPathObj->m_Path.AppendPoint(4.65f, 2.98f, FXPT_TYPE::BezierTo, false);
+ pPathObj->m_Path.AppendPoint(3.456f, 0.24f, FXPT_TYPE::BezierTo, false);
+ pPathObj->m_Path.AppendPoint(10.6f, 11.15f, FXPT_TYPE::LineTo, false);
+ pPathObj->m_Path.AppendPoint(11, 12.5f, FXPT_TYPE::LineTo, false);
+ pPathObj->m_Path.AppendPoint(11.46f, 12.67f, FXPT_TYPE::BezierTo, false);
+ pPathObj->m_Path.AppendPoint(11.84f, 12.96f, FXPT_TYPE::BezierTo, false);
+ pPathObj->m_Path.AppendPoint(12, 13.64f, FXPT_TYPE::BezierTo, true);
pPathObj->m_FillType = FXFILL_WINDING;
pPathObj->m_bStroke = false;
+
auto pTestPage = pdfium::MakeUnique<CPDF_Page>(nullptr, nullptr, false);
CPDF_PageContentGenerator generator(pTestPage.get());
CFX_ByteTextBuf buf;
@@ -134,29 +91,21 @@ TEST_F(CPDF_PageContentGeneratorTest, ProcessPath) {
TEST_F(CPDF_PageContentGeneratorTest, ProcessGraphics) {
auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>();
- pPathObj->m_Path.SetPointCount(3);
- FX_PATHPOINT* pPoints = pPathObj->m_Path.GetMutablePoints();
- pPoints[0].m_PointX = 1;
- pPoints[0].m_PointY = 2;
- pPoints[0].m_Type = FXPT_TYPE::MoveTo;
- pPoints[0].m_CloseFigure = false;
- pPoints[1].m_PointX = 3;
- pPoints[1].m_PointY = 4;
- pPoints[1].m_Type = FXPT_TYPE::LineTo;
- pPoints[1].m_CloseFigure = false;
- pPoints[2].m_PointX = 5;
- pPoints[2].m_PointY = 6;
- pPoints[2].m_Type = FXPT_TYPE::LineTo;
- pPoints[2].m_CloseFigure = true;
+ pPathObj->m_Path.AppendPoint(1, 2, FXPT_TYPE::MoveTo, false);
+ pPathObj->m_Path.AppendPoint(3, 4, FXPT_TYPE::LineTo, false);
+ pPathObj->m_Path.AppendPoint(5, 6, FXPT_TYPE::LineTo, true);
pPathObj->m_FillType = FXFILL_WINDING;
pPathObj->m_bStroke = true;
+
FX_FLOAT rgb[3] = {0.5f, 0.7f, 0.35f};
CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB);
pPathObj->m_ColorState.SetFillColor(pCS, rgb, 3);
+
FX_FLOAT rgb2[3] = {1, 0.9f, 0};
pPathObj->m_ColorState.SetStrokeColor(pCS, rgb2, 3);
pPathObj->m_GeneralState.SetFillAlpha(0.5f);
pPathObj->m_GeneralState.SetStrokeAlpha(0.8f);
+
auto pDoc = pdfium::MakeUnique<CPDF_Document>(nullptr);
pDoc->CreateNewDoc();
CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(0);
@@ -165,6 +114,7 @@ TEST_F(CPDF_PageContentGeneratorTest, ProcessGraphics) {
CFX_ByteTextBuf buf;
TestProcessPath(&generator, &buf, pPathObj.get());
CFX_ByteString pathString = buf.MakeString();
+
// Color RGB values used are integers divided by 255.
EXPECT_EQ("q 0.501961 0.701961 0.34902 rg 1 0.901961 0 RG /",
pathString.Left(48));
@@ -184,6 +134,7 @@ TEST_F(CPDF_PageContentGeneratorTest, ProcessGraphics) {
EXPECT_EQ("q 0.501961 0.701961 0.34902 rg 1 0.901961 0 RG 10.5 w /",
pathString2.Left(55));
EXPECT_EQ(" gs 1 2 m 3 4 l 5 6 l h B Q\n", pathString2.Right(28));
+
// Compare with the previous (should use same dictionary for gs)
EXPECT_EQ(pathString.GetLength() + 7, pathString2.GetLength());
EXPECT_EQ(pathString.Mid(48, pathString.GetLength() - 76),
diff --git a/core/fpdfapi/page/cpdf_path.cpp b/core/fpdfapi/page/cpdf_path.cpp
index 96d6b72abb..a95ce1e5bc 100644
--- a/core/fpdfapi/page/cpdf_path.cpp
+++ b/core/fpdfapi/page/cpdf_path.cpp
@@ -12,20 +12,12 @@ CPDF_Path::CPDF_Path(const CPDF_Path& that) : m_Ref(that.m_Ref) {}
CPDF_Path::~CPDF_Path() {}
-int CPDF_Path::GetPointCount() const {
- return m_Ref.GetObject()->GetPointCount();
-}
-
-void CPDF_Path::SetPointCount(int count) {
- m_Ref.GetPrivateCopy()->SetPointCount(count);
-}
-
-const FX_PATHPOINT* CPDF_Path::GetPoints() const {
+const std::vector<FX_PATHPOINT>& CPDF_Path::GetPoints() const {
return m_Ref.GetObject()->GetPoints();
}
-FX_PATHPOINT* CPDF_Path::GetMutablePoints() {
- return m_Ref.GetPrivateCopy()->GetPoints();
+void CPDF_Path::ClosePath() {
+ m_Ref.GetPrivateCopy()->ClosePath();
}
FX_FLOAT CPDF_Path::GetPointX(int index) const {
@@ -73,7 +65,6 @@ void CPDF_Path::AppendPoint(FX_FLOAT x,
FXPT_TYPE type,
bool close) {
CFX_PathData data;
- data.SetPointCount(1);
- data.SetPoint(0, x, y, type, close);
+ data.AppendPoint(x, y, type, close);
Append(&data, nullptr);
}
diff --git a/core/fpdfapi/page/cpdf_path.h b/core/fpdfapi/page/cpdf_path.h
index 21a94becac..97dd8fd8a9 100644
--- a/core/fpdfapi/page/cpdf_path.h
+++ b/core/fpdfapi/page/cpdf_path.h
@@ -7,6 +7,8 @@
#ifndef CORE_FPDFAPI_PAGE_CPDF_PATH_H_
#define CORE_FPDFAPI_PAGE_CPDF_PATH_H_
+#include <vector>
+
#include "core/fxcrt/cfx_shared_copy_on_write.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxge/cfx_fxgedevice.h"
@@ -22,10 +24,8 @@ class CPDF_Path {
void Emplace() { m_Ref.Emplace(); }
explicit operator bool() const { return !!m_Ref; }
- int GetPointCount() const;
- void SetPointCount(int count);
- const FX_PATHPOINT* GetPoints() const;
- FX_PATHPOINT* GetMutablePoints();
+ const std::vector<FX_PATHPOINT>& GetPoints() const;
+ void ClosePath();
FX_FLOAT GetPointX(int index) const;
FX_FLOAT GetPointY(int index) const;
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index 0af43d08b2..e991e456b7 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -1506,10 +1506,14 @@ void CPDF_StreamContentParser::AddPathObject(int FillType, bool bStroke) {
m_pPathPoints[PathPointCount - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) {
PathPointCount--;
}
+
CPDF_Path Path;
- Path.SetPointCount(PathPointCount);
- FXSYS_memcpy(Path.GetMutablePoints(), m_pPathPoints,
- sizeof(FX_PATHPOINT) * PathPointCount);
+ for (int i = 0; i < PathPointCount; i++) {
+ FX_PATHPOINT& point = m_pPathPoints[i];
+ Path.AppendPoint(point.m_PointX, point.m_PointY, point.m_Type,
+ point.m_CloseFigure);
+ }
+
CFX_Matrix matrix = m_pCurStates->m_CTM;
matrix.Concat(m_mtContentToUser);
if (bStroke || FillType) {
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 4f2638f276..60b57600c2 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -611,18 +611,21 @@ struct Coon_Bezier {
x.FromPoints(x0, x1, x2, x3);
y.FromPoints(y0, y1, y2, y3);
}
+
Coon_Bezier first_half() {
Coon_Bezier result;
result.x = x.first_half();
result.y = y.first_half();
return result;
}
+
Coon_Bezier second_half() {
Coon_Bezier result;
result.x = x.second_half();
result.y = y.second_half();
return result;
}
+
void BezierInterpol(Coon_Bezier& C1,
Coon_Bezier& C2,
Coon_Bezier& D1,
@@ -630,30 +633,31 @@ struct Coon_Bezier {
x.BezierInterpol(C1.x, C2.x, D1.x, D2.x);
y.BezierInterpol(C1.y, C2.y, D1.y, D2.y);
}
- void GetPoints(FX_PATHPOINT* pPoints) {
+
+ void GetPoints(std::vector<FX_PATHPOINT>& pPoints, size_t start_idx) {
float p[4];
int i;
x.GetPoints(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointX = p[i];
- }
+ for (i = 0; i < 4; i++)
+ pPoints[start_idx + i].m_PointX = p[i];
+
y.GetPoints(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointY = p[i];
- }
+ for (i = 0; i < 4; i++)
+ pPoints[start_idx + i].m_PointY = p[i];
}
- void GetPointsReverse(FX_PATHPOINT* pPoints) {
+
+ void GetPointsReverse(std::vector<FX_PATHPOINT>& pPoints, size_t start_idx) {
float p[4];
int i;
x.GetPointsReverse(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointX = p[i];
- }
+ for (i = 0; i < 4; i++)
+ pPoints[i + start_idx].m_PointX = p[i];
+
y.GetPointsReverse(p);
- for (i = 0; i < 4; i++) {
- pPoints[i].m_PointY = p[i];
- }
+ for (i = 0; i < 4; i++)
+ pPoints[i + start_idx].m_PointY = p[i];
}
+
float Distance() { return x.Distance() + y.Distance(); }
};
@@ -693,6 +697,7 @@ struct Coon_Color {
}
};
+#define COONCOLOR_THRESHOLD 4
struct CPDF_PatchDrawer {
Coon_Color patch_colors[4];
int max_delta;
@@ -728,15 +733,15 @@ struct CPDF_PatchDrawer {
d_top = div_colors[1].Distance(div_colors[2]);
d_right = div_colors[2].Distance(div_colors[3]);
}
-#define COONCOLOR_THRESHOLD 4
+
if (bSmall ||
(d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD &&
d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) {
- FX_PATHPOINT* pPoints = path.GetPoints();
- C1.GetPoints(pPoints);
- D2.GetPoints(pPoints + 3);
- C2.GetPointsReverse(pPoints + 6);
- D1.GetPointsReverse(pPoints + 9);
+ std::vector<FX_PATHPOINT>& pPoints = path.GetPoints();
+ C1.GetPoints(pPoints, 0);
+ D2.GetPoints(pPoints, 3);
+ C2.GetPointsReverse(pPoints, 6);
+ D1.GetPointsReverse(pPoints, 9);
int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER;
if (fill_mode & RENDER_NOPATHSMOOTH) {
fillFlags |= FXFILL_NOPATHSMOOTH;
@@ -814,14 +819,12 @@ void DrawCoonPatchMeshes(
patch.alpha = alpha;
patch.pDevice = &device;
patch.fill_mode = fill_mode;
- patch.path.SetPointCount(13);
- FX_PATHPOINT* pPoints = patch.path.GetPoints();
- pPoints[0].m_Type = FXPT_TYPE::MoveTo;
- pPoints[0].m_CloseFigure = false;
- for (int i = 1; i < 13; i++) {
- pPoints[i].m_Type = FXPT_TYPE::BezierTo;
- pPoints[i].m_CloseFigure = false;
+
+ for (int i = 0; i < 13; i++) {
+ patch.path.AppendPoint(
+ 0, 0, i == 0 ? FXPT_TYPE::MoveTo : FXPT_TYPE::BezierTo, false);
}
+
CFX_PointF coords[16];
int point_count = type == kTensorProductPatchMeshShading ? 16 : 12;
while (!stream.BitStream()->IsEOF()) {
@@ -1368,7 +1371,7 @@ void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath,
if (!pPathData)
continue;
- if (pPathData->GetPointCount() == 0) {
+ if (pPathData->GetPoints().empty()) {
CFX_PathData EmptyPath;
EmptyPath.AppendRect(-1, -1, 0, 0);
int fill_mode = FXFILL_WINDING;