Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: fpdfsdk/src/fpdf_transformpage.cpp

Issue 1799773002: Move fpdfsdk/src up to fpdfsdk/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « fpdfsdk/src/fpdf_sysfontinfo.cpp ('k') | fpdfsdk/src/fpdfdoc.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "public/fpdf_transformpage.h"
8
9 #include "core/include/fpdfapi/cpdf_array.h"
10 #include "core/include/fpdfapi/cpdf_document.h"
11 #include "core/include/fpdfapi/cpdf_number.h"
12 #include "core/include/fpdfapi/cpdf_reference.h"
13 #include "fpdfsdk/include/fsdk_define.h"
14
15 namespace {
16
17 void SetBoundingBox(CPDF_Page* page,
18 const CFX_ByteStringC& key,
19 float left,
20 float bottom,
21 float right,
22 float top) {
23 CPDF_Dictionary* pPageDict = page->m_pFormDict;
24 CPDF_Array* pBoundingBoxArray = new CPDF_Array;
25 pBoundingBoxArray->Add(new CPDF_Number(left));
26 pBoundingBoxArray->Add(new CPDF_Number(bottom));
27 pBoundingBoxArray->Add(new CPDF_Number(right));
28 pBoundingBoxArray->Add(new CPDF_Number(top));
29 pPageDict->SetAt(key, pBoundingBoxArray);
30 }
31
32 FPDF_BOOL GetBoundingBox(CPDF_Page* page,
33 const CFX_ByteStringC& key,
34 float* left,
35 float* bottom,
36 float* right,
37 float* top) {
38 CPDF_Dictionary* pPageDict = page->m_pFormDict;
39 CPDF_Array* pArray = pPageDict->GetArrayBy(key);
40 if (!pArray)
41 return FALSE;
42
43 *left = pArray->GetFloatAt(0);
44 *bottom = pArray->GetFloatAt(1);
45 *right = pArray->GetFloatAt(2);
46 *top = pArray->GetFloatAt(3);
47 return TRUE;
48 }
49
50 } // namespace
51
52 DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page,
53 float left,
54 float bottom,
55 float right,
56 float top) {
57 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
58 if (!pPage)
59 return;
60
61 SetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
62 }
63
64 DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page,
65 float left,
66 float bottom,
67 float right,
68 float top) {
69 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
70 if (!pPage)
71 return;
72
73 SetBoundingBox(pPage, "CropBox", left, bottom, right, top);
74 }
75
76 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page,
77 float* left,
78 float* bottom,
79 float* right,
80 float* top) {
81 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
82 return pPage && GetBoundingBox(pPage, "MediaBox", left, bottom, right, top);
83 }
84
85 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page,
86 float* left,
87 float* bottom,
88 float* right,
89 float* top) {
90 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
91 return pPage && GetBoundingBox(pPage, "CropBox", left, bottom, right, top);
92 }
93
94 DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page,
95 FS_MATRIX* matrix,
96 FS_RECTF* clipRect) {
97 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
98 if (!pPage)
99 return FALSE;
100
101 CFX_ByteTextBuf textBuf;
102 textBuf << "q ";
103 CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right,
104 clipRect->top);
105 rect.Normalize();
106 CFX_ByteString bsClipping;
107 bsClipping.Format("%f %f %f %f re W* n ", rect.left, rect.bottom,
108 rect.Width(), rect.Height());
109 textBuf << bsClipping;
110
111 CFX_ByteString bsMatix;
112 bsMatix.Format("%f %f %f %f %f %f cm ", matrix->a, matrix->b, matrix->c,
113 matrix->d, matrix->e, matrix->f);
114 textBuf << bsMatix;
115
116 CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
117 CPDF_Object* pContentObj =
118 pPageDic ? pPageDic->GetElement("Contents") : nullptr;
119 if (!pContentObj)
120 pContentObj = pPageDic ? pPageDic->GetArrayBy("Contents") : nullptr;
121 if (!pContentObj)
122 return FALSE;
123
124 CPDF_Dictionary* pDic = new CPDF_Dictionary;
125 CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
126 pStream->SetData(textBuf.GetBuffer(), textBuf.GetSize(), FALSE, FALSE);
127 CPDF_Document* pDoc = pPage->m_pDocument;
128 if (!pDoc)
129 return FALSE;
130 pDoc->AddIndirectObject(pStream);
131
132 pDic = new CPDF_Dictionary;
133 CPDF_Stream* pEndStream = new CPDF_Stream(nullptr, 0, pDic);
134 pEndStream->SetData((const uint8_t*)" Q", 2, FALSE, FALSE);
135 pDoc->AddIndirectObject(pEndStream);
136
137 CPDF_Array* pContentArray = nullptr;
138 if (CPDF_Array* pArray = ToArray(pContentObj)) {
139 pContentArray = pArray;
140 CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
141 pContentArray->InsertAt(0, pRef);
142 pContentArray->AddReference(pDoc, pEndStream);
143 } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
144 CPDF_Object* pDirectObj = pReference->GetDirect();
145 if (pDirectObj) {
146 if (CPDF_Array* pArray = pDirectObj->AsArray()) {
147 pContentArray = pArray;
148 CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
149 pContentArray->InsertAt(0, pRef);
150 pContentArray->AddReference(pDoc, pEndStream);
151 } else if (pDirectObj->IsStream()) {
152 pContentArray = new CPDF_Array();
153 pContentArray->AddReference(pDoc, pStream->GetObjNum());
154 pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
155 pContentArray->AddReference(pDoc, pEndStream);
156 pPageDic->SetAtReference("Contents", pDoc,
157 pDoc->AddIndirectObject(pContentArray));
158 }
159 }
160 }
161
162 // Need to transform the patterns as well.
163 CPDF_Dictionary* pRes = pPageDic->GetDictBy("Resources");
164 if (pRes) {
165 CPDF_Dictionary* pPattenDict = pRes->GetDictBy("Pattern");
166 if (pPattenDict) {
167 for (const auto& it : *pPattenDict) {
168 CPDF_Object* pObj = it.second;
169 if (pObj->IsReference())
170 pObj = pObj->GetDirect();
171
172 CPDF_Dictionary* pDict = nullptr;
173 if (pObj->IsDictionary())
174 pDict = pObj->AsDictionary();
175 else if (CPDF_Stream* pStream = pObj->AsStream())
176 pDict = pStream->GetDict();
177 else
178 continue;
179
180 CFX_Matrix m = pDict->GetMatrixBy("Matrix");
181 CFX_Matrix t = *(CFX_Matrix*)matrix;
182 m.Concat(t);
183 pDict->SetAtMatrix("Matrix", m);
184 }
185 }
186 }
187
188 return TRUE;
189 }
190
191 DLLEXPORT void STDCALL
192 FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object,
193 double a,
194 double b,
195 double c,
196 double d,
197 double e,
198 double f) {
199 CPDF_PageObject* pPageObj = (CPDF_PageObject*)page_object;
200 if (!pPageObj)
201 return;
202 CFX_Matrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d,
203 (FX_FLOAT)e, (FX_FLOAT)f);
204
205 // Special treatment to shading object, because the ClipPath for shading
206 // object is already transformed.
207 if (!pPageObj->IsShading())
208 pPageObj->TransformClipPath(matrix);
209 pPageObj->TransformGeneralState(matrix);
210 }
211
212 DLLEXPORT FPDF_CLIPPATH STDCALL FPDF_CreateClipPath(float left,
213 float bottom,
214 float right,
215 float top) {
216 CPDF_ClipPath* pNewClipPath = new CPDF_ClipPath();
217 pNewClipPath->GetModify();
218 CPDF_Path Path;
219 Path.GetModify();
220 Path.AppendRect(left, bottom, right, top);
221 pNewClipPath->AppendPath(Path, FXFILL_ALTERNATE, FALSE);
222 return pNewClipPath;
223 }
224
225 DLLEXPORT void STDCALL FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath) {
226 delete (CPDF_ClipPath*)clipPath;
227 }
228
229 void OutputPath(CFX_ByteTextBuf& buf, CPDF_Path path) {
230 const CFX_PathData* pPathData = path;
231 if (!pPathData)
232 return;
233
234 FX_PATHPOINT* pPoints = pPathData->GetPoints();
235
236 if (path.IsRect()) {
237 buf << (pPoints[0].m_PointX) << " " << (pPoints[0].m_PointY) << " "
238 << (pPoints[2].m_PointX - pPoints[0].m_PointX) << " "
239 << (pPoints[2].m_PointY - pPoints[0].m_PointY) << " re\n";
240 return;
241 }
242
243 CFX_ByteString temp;
244 for (int i = 0; i < pPathData->GetPointCount(); i++) {
245 buf << (pPoints[i].m_PointX) << " " << (pPoints[i].m_PointY);
246 int point_type = pPoints[i].m_Flag & FXPT_TYPE;
247 if (point_type == FXPT_MOVETO) {
248 buf << " m\n";
249 } else if (point_type == FXPT_BEZIERTO) {
250 buf << " " << (pPoints[i + 1].m_PointX) << " "
251 << (pPoints[i + 1].m_PointY) << " " << (pPoints[i + 2].m_PointX)
252 << " " << (pPoints[i + 2].m_PointY);
253 if (pPoints[i + 2].m_Flag & FXPT_CLOSEFIGURE)
254 buf << " c h\n";
255 else
256 buf << " c\n";
257 i += 2;
258 } else if (point_type == FXPT_LINETO) {
259 if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE)
260 buf << " l h\n";
261 else
262 buf << " l\n";
263 }
264 }
265 }
266
267 DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
268 FPDF_CLIPPATH clipPath) {
269 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
270 if (!pPage)
271 return;
272
273 CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
274 CPDF_Object* pContentObj =
275 pPageDic ? pPageDic->GetElement("Contents") : nullptr;
276 if (!pContentObj)
277 pContentObj = pPageDic ? pPageDic->GetArrayBy("Contents") : nullptr;
278 if (!pContentObj)
279 return;
280
281 CFX_ByteTextBuf strClip;
282 CPDF_ClipPath* pClipPath = (CPDF_ClipPath*)clipPath;
283 FX_DWORD i;
284 for (i = 0; i < pClipPath->GetPathCount(); i++) {
285 CPDF_Path path = pClipPath->GetPath(i);
286 int iClipType = pClipPath->GetClipType(i);
287 if (path.GetPointCount() == 0) {
288 // Empty clipping (totally clipped out)
289 strClip << "0 0 m W n ";
290 } else {
291 OutputPath(strClip, path);
292 if (iClipType == FXFILL_WINDING)
293 strClip << "W n\n";
294 else
295 strClip << "W* n\n";
296 }
297 }
298 CPDF_Dictionary* pDic = new CPDF_Dictionary;
299 CPDF_Stream* pStream = new CPDF_Stream(nullptr, 0, pDic);
300 pStream->SetData(strClip.GetBuffer(), strClip.GetSize(), FALSE, FALSE);
301 CPDF_Document* pDoc = pPage->m_pDocument;
302 if (!pDoc)
303 return;
304 pDoc->AddIndirectObject(pStream);
305
306 CPDF_Array* pContentArray = nullptr;
307 if (CPDF_Array* pArray = ToArray(pContentObj)) {
308 pContentArray = pArray;
309 CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
310 pContentArray->InsertAt(0, pRef);
311 } else if (CPDF_Reference* pReference = ToReference(pContentObj)) {
312 CPDF_Object* pDirectObj = pReference->GetDirect();
313 if (pDirectObj) {
314 if (CPDF_Array* pArray = pDirectObj->AsArray()) {
315 pContentArray = pArray;
316 CPDF_Reference* pRef = new CPDF_Reference(pDoc, pStream->GetObjNum());
317 pContentArray->InsertAt(0, pRef);
318 } else if (pDirectObj->IsStream()) {
319 pContentArray = new CPDF_Array();
320 pContentArray->AddReference(pDoc, pStream->GetObjNum());
321 pContentArray->AddReference(pDoc, pDirectObj->GetObjNum());
322 pPageDic->SetAtReference("Contents", pDoc,
323 pDoc->AddIndirectObject(pContentArray));
324 }
325 }
326 }
327 }
OLDNEW
« no previous file with comments | « fpdfsdk/src/fpdf_sysfontinfo.cpp ('k') | fpdfsdk/src/fpdfdoc.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698