blob: 0cf222d7968f790c5ce385dea4c3ca5b23bf6c2d [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangb4e7f302015-11-06 15:52:32 -08007#include "public/fpdf_doc.h"
8
Wei Li0e2e5d72016-03-03 11:28:06 -08009#include <set>
10
Dan Sinclair455a4192016-03-16 09:48:56 -040011#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -040012#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
13#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080014#include "fpdfsdk/include/fsdk_define.h"
Wei Li0e2e5d72016-03-03 11:28:06 -080015#include "third_party/base/stl_util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016
Lei Zhangbdf72c32015-08-14 19:24:08 -070017namespace {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070018
Lei Zhangbdf72c32015-08-14 19:24:08 -070019CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree,
20 CPDF_Bookmark bookmark,
Wei Li0e2e5d72016-03-03 11:28:06 -080021 const CFX_WideString& title,
22 std::set<CPDF_Dictionary*>* visited) {
23 // Return if already checked to avoid circular calling.
24 if (pdfium::ContainsKey(*visited, bookmark.GetDict()))
25 return CPDF_Bookmark();
26 visited->insert(bookmark.GetDict());
27
Wei Li0fc6b252016-03-01 16:29:41 -080028 if (bookmark.GetDict() &&
29 bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) {
Wei Li0e2e5d72016-03-03 11:28:06 -080030 // First check this item.
Nico Weber9d8ec5a2015-08-04 13:00:21 -070031 return bookmark;
32 }
Wei Li0e2e5d72016-03-03 11:28:06 -080033
34 // Go into children items.
Nico Weber9d8ec5a2015-08-04 13:00:21 -070035 CPDF_Bookmark child = tree.GetFirstChild(bookmark);
Wei Li0e2e5d72016-03-03 11:28:06 -080036 while (child.GetDict() && !pdfium::ContainsKey(*visited, child.GetDict())) {
37 // Check this item and its children.
38 CPDF_Bookmark found = FindBookmark(tree, child, title, visited);
Wei Li0fc6b252016-03-01 16:29:41 -080039 if (found.GetDict())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070040 return found;
41 child = tree.GetNextSibling(child);
42 }
43 return CPDF_Bookmark();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044}
45
Lei Zhangbdf72c32015-08-14 19:24:08 -070046CPDF_LinkList* GetLinkList(CPDF_Page* page) {
47 if (!page)
48 return nullptr;
49
Lei Zhangbdf72c32015-08-14 19:24:08 -070050 CPDF_Document* pDoc = page->m_pDocument;
tsepez5ce09682016-05-25 16:16:32 -070051 std::unique_ptr<CPDF_LinkList>* pHolder = pDoc->LinksContext();
52 if (!pHolder->get())
53 pHolder->reset(new CPDF_LinkList);
54 return pHolder->get();
Lei Zhangbdf72c32015-08-14 19:24:08 -070055}
56
57} // namespace
58
Nico Weber9d8ec5a2015-08-04 13:00:21 -070059DLLEXPORT FPDF_BOOKMARK STDCALL
60FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -070061 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
62 if (!pDoc)
63 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064 CPDF_BookmarkTree tree(pDoc);
Dan Sinclairf1251c12015-10-20 16:24:45 -040065 CPDF_Bookmark bookmark =
66 CPDF_Bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067 return tree.GetFirstChild(bookmark).GetDict();
Bo Xu4d62b6b2015-01-10 22:52:59 -080068}
69
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070DLLEXPORT FPDF_BOOKMARK STDCALL
71FPDFBookmark_GetNextSibling(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -070072 if (!pDict)
73 return nullptr;
74 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
75 if (!pDoc)
76 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070077 CPDF_BookmarkTree tree(pDoc);
Dan Sinclairf1251c12015-10-20 16:24:45 -040078 CPDF_Bookmark bookmark =
79 CPDF_Bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 return tree.GetNextSibling(bookmark).GetDict();
Bo Xu4d62b6b2015-01-10 22:52:59 -080081}
82
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083DLLEXPORT unsigned long STDCALL FPDFBookmark_GetTitle(FPDF_BOOKMARK pDict,
84 void* buffer,
85 unsigned long buflen) {
86 if (!pDict)
87 return 0;
Dan Sinclairf1251c12015-10-20 16:24:45 -040088 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089 CFX_WideString title = bookmark.GetTitle();
90 CFX_ByteString encodedTitle = title.UTF16LE_Encode();
91 unsigned long len = encodedTitle.GetLength();
92 if (buffer && buflen >= len) {
93 FXSYS_memcpy(buffer, encodedTitle.c_str(), len);
94 }
95 return len;
Bo Xu4d62b6b2015-01-10 22:52:59 -080096}
97
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document,
99 FPDF_WIDESTRING title) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100 if (!title || title[0] == 0)
Tom Sepez471a1032015-10-15 16:17:18 -0700101 return nullptr;
102 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
103 if (!pDoc)
104 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105 CPDF_BookmarkTree tree(pDoc);
106 FX_STRSIZE len = CFX_WideString::WStringLength(title);
107 CFX_WideString encodedTitle = CFX_WideString::FromUTF16LE(title, len);
Wei Li0e2e5d72016-03-03 11:28:06 -0800108 std::set<CPDF_Dictionary*> visited;
109 return FindBookmark(tree, CPDF_Bookmark(), encodedTitle, &visited).GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700110}
111
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document,
113 FPDF_BOOKMARK pDict) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114 if (!pDict)
Tom Sepez471a1032015-10-15 16:17:18 -0700115 return nullptr;
116 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
117 if (!pDoc)
118 return nullptr;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400119 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120 CPDF_Dest dest = bookmark.GetDest(pDoc);
Wei Li0fc6b252016-03-01 16:29:41 -0800121 if (dest.GetObject())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122 return dest.GetObject();
123 // If this bookmark is not directly associated with a dest, we try to get
124 // action
125 CPDF_Action action = bookmark.GetAction();
Wei Li0fc6b252016-03-01 16:29:41 -0800126 if (!action.GetDict())
Tom Sepez471a1032015-10-15 16:17:18 -0700127 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128 return action.GetDest(pDoc).GetObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700129}
130
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131DLLEXPORT FPDF_ACTION STDCALL FPDFBookmark_GetAction(FPDF_BOOKMARK pDict) {
132 if (!pDict)
thestig1cd352e2016-06-07 17:53:06 -0700133 return nullptr;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400134 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 return bookmark.GetAction().GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136}
137
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138DLLEXPORT unsigned long STDCALL FPDFAction_GetType(FPDF_ACTION pDict) {
139 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700140 return PDFACTION_UNSUPPORTED;
141
Dan Sinclairf1251c12015-10-20 16:24:45 -0400142 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700143 CPDF_Action::ActionType type = action.GetType();
144 switch (type) {
145 case CPDF_Action::GoTo:
146 return PDFACTION_GOTO;
147 case CPDF_Action::GoToR:
148 return PDFACTION_REMOTEGOTO;
149 case CPDF_Action::URI:
150 return PDFACTION_URI;
151 case CPDF_Action::Launch:
152 return PDFACTION_LAUNCH;
153 default:
154 return PDFACTION_UNSUPPORTED;
155 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700156}
157
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700158DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document,
159 FPDF_ACTION pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -0700160 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700161 return nullptr;
Tom Sepez471a1032015-10-15 16:17:18 -0700162 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
163 if (!pDoc)
164 return nullptr;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400165 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700166 return action.GetDest(pDoc).GetObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700167}
168
Dan Sinclairf766ad22016-03-14 13:51:24 -0400169DLLEXPORT unsigned long STDCALL FPDFAction_GetFilePath(FPDF_ACTION pDict,
170 void* buffer,
171 unsigned long buflen) {
Lei Zhange0947b32015-09-17 14:51:48 -0700172 unsigned long type = FPDFAction_GetType(pDict);
173 if (type != PDFACTION_REMOTEGOTO && type != PDFACTION_LAUNCH)
174 return 0;
175
Dan Sinclairf1251c12015-10-20 16:24:45 -0400176 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Lei Zhange0947b32015-09-17 14:51:48 -0700177 CFX_ByteString path = action.GetFilePath().UTF8Encode();
178 unsigned long len = path.GetLength() + 1;
179 if (buffer && buflen >= len)
180 FXSYS_memcpy(buffer, path.c_str(), len);
181 return len;
182}
183
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document,
185 FPDF_ACTION pDict,
186 void* buffer,
187 unsigned long buflen) {
Tom Sepez471a1032015-10-15 16:17:18 -0700188 if (!pDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700189 return 0;
Tom Sepez471a1032015-10-15 16:17:18 -0700190 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
191 if (!pDoc)
192 return 0;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400193 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 CFX_ByteString path = action.GetURI(pDoc);
195 unsigned long len = path.GetLength() + 1;
Lei Zhange0947b32015-09-17 14:51:48 -0700196 if (buffer && buflen >= len)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700197 FXSYS_memcpy(buffer, path.c_str(), len);
198 return len;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700199}
200
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document,
202 FPDF_DEST pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -0700203 if (!pDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204 return 0;
Tom Sepez471a1032015-10-15 16:17:18 -0700205 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
206 if (!pDoc)
207 return 0;
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400208 CPDF_Dest dest(static_cast<CPDF_Array*>(pDict));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 return dest.GetPageIndex(pDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700210}
211
Dan Sinclairf766ad22016-03-14 13:51:24 -0400212DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page,
213 double x,
214 double y) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700215 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Lei Zhangbdf72c32015-08-14 19:24:08 -0700216 if (!pPage)
217 return nullptr;
218
219 CPDF_LinkList* pLinkList = GetLinkList(pPage);
220 if (!pLinkList)
221 return nullptr;
222
223 return pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, nullptr)
224 .GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225}
226
Dan Sinclairf766ad22016-03-14 13:51:24 -0400227DLLEXPORT int STDCALL FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page,
228 double x,
229 double y) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700230 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231 if (!pPage)
Lei Zhangbdf72c32015-08-14 19:24:08 -0700232 return -1;
233
234 CPDF_LinkList* pLinkList = GetLinkList(pPage);
235 if (!pLinkList)
236 return -1;
237
238 int z_order = -1;
239 pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, &z_order);
240 return z_order;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700241}
242
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700243DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document,
244 FPDF_LINK pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -0700245 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700246 return nullptr;
Tom Sepez471a1032015-10-15 16:17:18 -0700247 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
248 if (!pDoc)
249 return nullptr;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400250 CPDF_Link link(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 FPDF_DEST dest = link.GetDest(pDoc).GetObject();
252 if (dest)
253 return dest;
254 // If this link is not directly associated with a dest, we try to get action
255 CPDF_Action action = link.GetAction();
Wei Li0fc6b252016-03-01 16:29:41 -0800256 if (!action.GetDict())
Lei Zhange0947b32015-09-17 14:51:48 -0700257 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258 return action.GetDest(pDoc).GetObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700259}
260
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261DLLEXPORT FPDF_ACTION STDCALL FPDFLink_GetAction(FPDF_LINK pDict) {
262 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700263 return nullptr;
264
Dan Sinclairf1251c12015-10-20 16:24:45 -0400265 CPDF_Link link(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 return link.GetAction().GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700267}
268
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269DLLEXPORT FPDF_BOOL STDCALL FPDFLink_Enumerate(FPDF_PAGE page,
270 int* startPos,
271 FPDF_LINK* linkAnnot) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700272 if (!startPos || !linkAnnot)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700273 return FALSE;
Tom Sepezdb0be962015-10-16 14:00:21 -0700274 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
275 if (!pPage || !pPage->m_pFormDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 return FALSE;
Wei Li9b761132016-01-29 15:44:20 -0800277 CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayBy("Annots");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 if (!pAnnots)
279 return FALSE;
Wei Lie1aebd42016-04-11 10:02:09 -0700280 for (size_t i = *startPos; i < pAnnots->GetCount(); i++) {
Dan Sinclairf1251c12015-10-20 16:24:45 -0400281 CPDF_Dictionary* pDict =
tsepezbd567552016-03-29 14:51:50 -0700282 ToDictionary(static_cast<CPDF_Object*>(pAnnots->GetDirectObjectAt(i)));
Dan Sinclairf1251c12015-10-20 16:24:45 -0400283 if (!pDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 continue;
tsepez9f2970c2016-04-01 10:23:04 -0700285 if (pDict->GetStringBy("Subtype") == "Link") {
Wei Lie1aebd42016-04-11 10:02:09 -0700286 *startPos = static_cast<int>(i + 1);
287 *linkAnnot = static_cast<FPDF_LINK>(pDict);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 return TRUE;
289 }
290 }
291 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700292}
293
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetAnnotRect(FPDF_LINK linkAnnot,
295 FS_RECTF* rect) {
296 if (!linkAnnot || !rect)
297 return FALSE;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400298 CPDF_Dictionary* pAnnotDict =
299 ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
Tom Sepez281a9ea2016-02-26 14:24:28 -0800300 CFX_FloatRect rt = pAnnotDict->GetRectBy("Rect");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301 rect->left = rt.left;
302 rect->bottom = rt.bottom;
303 rect->right = rt.right;
304 rect->top = rt.top;
305 return TRUE;
306}
307
308DLLEXPORT int STDCALL FPDFLink_CountQuadPoints(FPDF_LINK linkAnnot) {
309 if (!linkAnnot)
310 return 0;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400311 CPDF_Dictionary* pAnnotDict =
312 ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
Wei Li9b761132016-01-29 15:44:20 -0800313 CPDF_Array* pArray = pAnnotDict->GetArrayBy("QuadPoints");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 if (!pArray)
315 return 0;
Wei Lie1aebd42016-04-11 10:02:09 -0700316 return static_cast<int>(pArray->GetCount() / 8);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317}
318
319DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetQuadPoints(FPDF_LINK linkAnnot,
320 int quadIndex,
321 FS_QUADPOINTSF* quadPoints) {
322 if (!linkAnnot || !quadPoints)
323 return FALSE;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400324 CPDF_Dictionary* pAnnotDict =
325 ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
Wei Li9b761132016-01-29 15:44:20 -0800326 CPDF_Array* pArray = pAnnotDict->GetArrayBy("QuadPoints");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327 if (pArray) {
Wei Lie1aebd42016-04-11 10:02:09 -0700328 if (quadIndex < 0 ||
329 static_cast<size_t>(quadIndex) >= pArray->GetCount() / 8 ||
330 (static_cast<size_t>(quadIndex * 8 + 7) >= pArray->GetCount()))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700331 return FALSE;
Wei Li9b761132016-01-29 15:44:20 -0800332 quadPoints->x1 = pArray->GetNumberAt(quadIndex * 8);
333 quadPoints->y1 = pArray->GetNumberAt(quadIndex * 8 + 1);
334 quadPoints->x2 = pArray->GetNumberAt(quadIndex * 8 + 2);
335 quadPoints->y2 = pArray->GetNumberAt(quadIndex * 8 + 3);
336 quadPoints->x3 = pArray->GetNumberAt(quadIndex * 8 + 4);
337 quadPoints->y3 = pArray->GetNumberAt(quadIndex * 8 + 5);
338 quadPoints->x4 = pArray->GetNumberAt(quadIndex * 8 + 6);
339 quadPoints->y4 = pArray->GetNumberAt(quadIndex * 8 + 7);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700340 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341 }
342 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700343}
344
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700345DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc,
346 FPDF_BYTESTRING tag,
347 void* buffer,
348 unsigned long buflen) {
Tom Sepez471a1032015-10-15 16:17:18 -0700349 if (!tag)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350 return 0;
Tom Sepez471a1032015-10-15 16:17:18 -0700351 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
352 if (!pDoc)
353 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700354 CPDF_Dictionary* pInfo = pDoc->GetInfo();
355 if (!pInfo)
356 return 0;
Wei Li9b761132016-01-29 15:44:20 -0800357 CFX_WideString text = pInfo->GetUnicodeTextBy(tag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358 // Use UTF-16LE encoding
359 CFX_ByteString encodedText = text.UTF16LE_Encode();
360 unsigned long len = encodedText.GetLength();
361 if (buffer && buflen >= len) {
362 FXSYS_memcpy(buffer, encodedText.c_str(), len);
363 }
364 return len;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700365}