blob: 6a65e4ae22c47969a178e8d57572a3d155d9e641 [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 -070019int THISMODULE = 0;
20
21CPDF_Bookmark FindBookmark(const CPDF_BookmarkTree& tree,
22 CPDF_Bookmark bookmark,
Wei Li0e2e5d72016-03-03 11:28:06 -080023 const CFX_WideString& title,
24 std::set<CPDF_Dictionary*>* visited) {
25 // Return if already checked to avoid circular calling.
26 if (pdfium::ContainsKey(*visited, bookmark.GetDict()))
27 return CPDF_Bookmark();
28 visited->insert(bookmark.GetDict());
29
Wei Li0fc6b252016-03-01 16:29:41 -080030 if (bookmark.GetDict() &&
31 bookmark.GetTitle().CompareNoCase(title.c_str()) == 0) {
Wei Li0e2e5d72016-03-03 11:28:06 -080032 // First check this item.
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033 return bookmark;
34 }
Wei Li0e2e5d72016-03-03 11:28:06 -080035
36 // Go into children items.
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037 CPDF_Bookmark child = tree.GetFirstChild(bookmark);
Wei Li0e2e5d72016-03-03 11:28:06 -080038 while (child.GetDict() && !pdfium::ContainsKey(*visited, child.GetDict())) {
39 // Check this item and its children.
40 CPDF_Bookmark found = FindBookmark(tree, child, title, visited);
Wei Li0fc6b252016-03-01 16:29:41 -080041 if (found.GetDict())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070042 return found;
43 child = tree.GetNextSibling(child);
44 }
45 return CPDF_Bookmark();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070046}
47
Lei Zhangbdf72c32015-08-14 19:24:08 -070048void ReleaseLinkList(void* data) {
49 delete (CPDF_LinkList*)data;
50}
51
52CPDF_LinkList* GetLinkList(CPDF_Page* page) {
53 if (!page)
54 return nullptr;
55
56 // Link list is stored with the document
57 CPDF_Document* pDoc = page->m_pDocument;
58 CPDF_LinkList* pLinkList = (CPDF_LinkList*)pDoc->GetPrivateData(&THISMODULE);
59 if (!pLinkList) {
60 pLinkList = new CPDF_LinkList;
61 pDoc->SetPrivateData(&THISMODULE, pLinkList, ReleaseLinkList);
62 }
63 return pLinkList;
64}
65
66} // namespace
67
Nico Weber9d8ec5a2015-08-04 13:00:21 -070068DLLEXPORT FPDF_BOOKMARK STDCALL
69FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -070070 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
71 if (!pDoc)
72 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073 CPDF_BookmarkTree tree(pDoc);
Dan Sinclairf1251c12015-10-20 16:24:45 -040074 CPDF_Bookmark bookmark =
75 CPDF_Bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076 return tree.GetFirstChild(bookmark).GetDict();
Bo Xu4d62b6b2015-01-10 22:52:59 -080077}
78
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079DLLEXPORT FPDF_BOOKMARK STDCALL
80FPDFBookmark_GetNextSibling(FPDF_DOCUMENT document, FPDF_BOOKMARK pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -070081 if (!pDict)
82 return nullptr;
83 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
84 if (!pDoc)
85 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 CPDF_BookmarkTree tree(pDoc);
Dan Sinclairf1251c12015-10-20 16:24:45 -040087 CPDF_Bookmark bookmark =
88 CPDF_Bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089 return tree.GetNextSibling(bookmark).GetDict();
Bo Xu4d62b6b2015-01-10 22:52:59 -080090}
91
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092DLLEXPORT unsigned long STDCALL FPDFBookmark_GetTitle(FPDF_BOOKMARK pDict,
93 void* buffer,
94 unsigned long buflen) {
95 if (!pDict)
96 return 0;
Dan Sinclairf1251c12015-10-20 16:24:45 -040097 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098 CFX_WideString title = bookmark.GetTitle();
99 CFX_ByteString encodedTitle = title.UTF16LE_Encode();
100 unsigned long len = encodedTitle.GetLength();
101 if (buffer && buflen >= len) {
102 FXSYS_memcpy(buffer, encodedTitle.c_str(), len);
103 }
104 return len;
Bo Xu4d62b6b2015-01-10 22:52:59 -0800105}
106
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document,
108 FPDF_WIDESTRING title) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 if (!title || title[0] == 0)
Tom Sepez471a1032015-10-15 16:17:18 -0700110 return nullptr;
111 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
112 if (!pDoc)
113 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114 CPDF_BookmarkTree tree(pDoc);
115 FX_STRSIZE len = CFX_WideString::WStringLength(title);
116 CFX_WideString encodedTitle = CFX_WideString::FromUTF16LE(title, len);
Wei Li0e2e5d72016-03-03 11:28:06 -0800117 std::set<CPDF_Dictionary*> visited;
118 return FindBookmark(tree, CPDF_Bookmark(), encodedTitle, &visited).GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700119}
120
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document,
122 FPDF_BOOKMARK pDict) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 if (!pDict)
Tom Sepez471a1032015-10-15 16:17:18 -0700124 return nullptr;
125 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
126 if (!pDoc)
127 return nullptr;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400128 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 CPDF_Dest dest = bookmark.GetDest(pDoc);
Wei Li0fc6b252016-03-01 16:29:41 -0800130 if (dest.GetObject())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 return dest.GetObject();
132 // If this bookmark is not directly associated with a dest, we try to get
133 // action
134 CPDF_Action action = bookmark.GetAction();
Wei Li0fc6b252016-03-01 16:29:41 -0800135 if (!action.GetDict())
Tom Sepez471a1032015-10-15 16:17:18 -0700136 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 return action.GetDest(pDoc).GetObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700138}
139
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140DLLEXPORT FPDF_ACTION STDCALL FPDFBookmark_GetAction(FPDF_BOOKMARK pDict) {
141 if (!pDict)
142 return NULL;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400143 CPDF_Bookmark bookmark(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 return bookmark.GetAction().GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700145}
146
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147DLLEXPORT unsigned long STDCALL FPDFAction_GetType(FPDF_ACTION pDict) {
148 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700149 return PDFACTION_UNSUPPORTED;
150
Dan Sinclairf1251c12015-10-20 16:24:45 -0400151 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700152 CPDF_Action::ActionType type = action.GetType();
153 switch (type) {
154 case CPDF_Action::GoTo:
155 return PDFACTION_GOTO;
156 case CPDF_Action::GoToR:
157 return PDFACTION_REMOTEGOTO;
158 case CPDF_Action::URI:
159 return PDFACTION_URI;
160 case CPDF_Action::Launch:
161 return PDFACTION_LAUNCH;
162 default:
163 return PDFACTION_UNSUPPORTED;
164 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700165}
166
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document,
168 FPDF_ACTION pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -0700169 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700170 return nullptr;
Tom Sepez471a1032015-10-15 16:17:18 -0700171 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
172 if (!pDoc)
173 return nullptr;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400174 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700175 return action.GetDest(pDoc).GetObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700176}
177
Dan Sinclairf766ad22016-03-14 13:51:24 -0400178DLLEXPORT unsigned long STDCALL FPDFAction_GetFilePath(FPDF_ACTION pDict,
179 void* buffer,
180 unsigned long buflen) {
Lei Zhange0947b32015-09-17 14:51:48 -0700181 unsigned long type = FPDFAction_GetType(pDict);
182 if (type != PDFACTION_REMOTEGOTO && type != PDFACTION_LAUNCH)
183 return 0;
184
Dan Sinclairf1251c12015-10-20 16:24:45 -0400185 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Lei Zhange0947b32015-09-17 14:51:48 -0700186 CFX_ByteString path = action.GetFilePath().UTF8Encode();
187 unsigned long len = path.GetLength() + 1;
188 if (buffer && buflen >= len)
189 FXSYS_memcpy(buffer, path.c_str(), len);
190 return len;
191}
192
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700193DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document,
194 FPDF_ACTION pDict,
195 void* buffer,
196 unsigned long buflen) {
Tom Sepez471a1032015-10-15 16:17:18 -0700197 if (!pDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700198 return 0;
Tom Sepez471a1032015-10-15 16:17:18 -0700199 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
200 if (!pDoc)
201 return 0;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400202 CPDF_Action action(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203 CFX_ByteString path = action.GetURI(pDoc);
204 unsigned long len = path.GetLength() + 1;
Lei Zhange0947b32015-09-17 14:51:48 -0700205 if (buffer && buflen >= len)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 FXSYS_memcpy(buffer, path.c_str(), len);
207 return len;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700208}
209
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document,
211 FPDF_DEST pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -0700212 if (!pDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 return 0;
Tom Sepez471a1032015-10-15 16:17:18 -0700214 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
215 if (!pDoc)
216 return 0;
Dan Sinclair2b11dc12015-10-22 15:02:06 -0400217 CPDF_Dest dest(static_cast<CPDF_Array*>(pDict));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 return dest.GetPageIndex(pDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700219}
220
Dan Sinclairf766ad22016-03-14 13:51:24 -0400221DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page,
222 double x,
223 double y) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700224 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Lei Zhangbdf72c32015-08-14 19:24:08 -0700225 if (!pPage)
226 return nullptr;
227
228 CPDF_LinkList* pLinkList = GetLinkList(pPage);
229 if (!pLinkList)
230 return nullptr;
231
232 return pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, nullptr)
233 .GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700234}
235
Dan Sinclairf766ad22016-03-14 13:51:24 -0400236DLLEXPORT int STDCALL FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page,
237 double x,
238 double y) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700239 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240 if (!pPage)
Lei Zhangbdf72c32015-08-14 19:24:08 -0700241 return -1;
242
243 CPDF_LinkList* pLinkList = GetLinkList(pPage);
244 if (!pLinkList)
245 return -1;
246
247 int z_order = -1;
248 pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, &z_order);
249 return z_order;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700250}
251
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document,
253 FPDF_LINK pDict) {
Tom Sepez471a1032015-10-15 16:17:18 -0700254 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700255 return nullptr;
Tom Sepez471a1032015-10-15 16:17:18 -0700256 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
257 if (!pDoc)
258 return nullptr;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400259 CPDF_Link link(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 FPDF_DEST dest = link.GetDest(pDoc).GetObject();
261 if (dest)
262 return dest;
263 // If this link is not directly associated with a dest, we try to get action
264 CPDF_Action action = link.GetAction();
Wei Li0fc6b252016-03-01 16:29:41 -0800265 if (!action.GetDict())
Lei Zhange0947b32015-09-17 14:51:48 -0700266 return nullptr;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267 return action.GetDest(pDoc).GetObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268}
269
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270DLLEXPORT FPDF_ACTION STDCALL FPDFLink_GetAction(FPDF_LINK pDict) {
271 if (!pDict)
Lei Zhange0947b32015-09-17 14:51:48 -0700272 return nullptr;
273
Dan Sinclairf1251c12015-10-20 16:24:45 -0400274 CPDF_Link link(ToDictionary(static_cast<CPDF_Object*>(pDict)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 return link.GetAction().GetDict();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700276}
277
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278DLLEXPORT FPDF_BOOL STDCALL FPDFLink_Enumerate(FPDF_PAGE page,
279 int* startPos,
280 FPDF_LINK* linkAnnot) {
Tom Sepezdb0be962015-10-16 14:00:21 -0700281 if (!startPos || !linkAnnot)
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700282 return FALSE;
Tom Sepezdb0be962015-10-16 14:00:21 -0700283 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
284 if (!pPage || !pPage->m_pFormDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 return FALSE;
Wei Li9b761132016-01-29 15:44:20 -0800286 CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayBy("Annots");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 if (!pAnnots)
288 return FALSE;
289 for (int i = *startPos; i < (int)pAnnots->GetCount(); i++) {
Dan Sinclairf1251c12015-10-20 16:24:45 -0400290 CPDF_Dictionary* pDict =
291 ToDictionary(static_cast<CPDF_Object*>(pAnnots->GetElementValue(i)));
292 if (!pDict)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293 continue;
Wei Li9b761132016-01-29 15:44:20 -0800294 if (pDict->GetStringBy("Subtype").Equal("Link")) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295 *startPos = i + 1;
296 *linkAnnot = (FPDF_LINK)pDict;
297 return TRUE;
298 }
299 }
300 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700301}
302
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetAnnotRect(FPDF_LINK linkAnnot,
304 FS_RECTF* rect) {
305 if (!linkAnnot || !rect)
306 return FALSE;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400307 CPDF_Dictionary* pAnnotDict =
308 ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
Tom Sepez281a9ea2016-02-26 14:24:28 -0800309 CFX_FloatRect rt = pAnnotDict->GetRectBy("Rect");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 rect->left = rt.left;
311 rect->bottom = rt.bottom;
312 rect->right = rt.right;
313 rect->top = rt.top;
314 return TRUE;
315}
316
317DLLEXPORT int STDCALL FPDFLink_CountQuadPoints(FPDF_LINK linkAnnot) {
318 if (!linkAnnot)
319 return 0;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400320 CPDF_Dictionary* pAnnotDict =
321 ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
Wei Li9b761132016-01-29 15:44:20 -0800322 CPDF_Array* pArray = pAnnotDict->GetArrayBy("QuadPoints");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700323 if (!pArray)
324 return 0;
325 return pArray->GetCount() / 8;
326}
327
328DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetQuadPoints(FPDF_LINK linkAnnot,
329 int quadIndex,
330 FS_QUADPOINTSF* quadPoints) {
331 if (!linkAnnot || !quadPoints)
332 return FALSE;
Dan Sinclairf1251c12015-10-20 16:24:45 -0400333 CPDF_Dictionary* pAnnotDict =
334 ToDictionary(static_cast<CPDF_Object*>(linkAnnot));
Wei Li9b761132016-01-29 15:44:20 -0800335 CPDF_Array* pArray = pAnnotDict->GetArrayBy("QuadPoints");
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700336 if (pArray) {
337 if (quadIndex < 0 || quadIndex >= (int)pArray->GetCount() / 8 ||
338 ((quadIndex * 8 + 7) >= (int)pArray->GetCount()))
339 return FALSE;
Wei Li9b761132016-01-29 15:44:20 -0800340 quadPoints->x1 = pArray->GetNumberAt(quadIndex * 8);
341 quadPoints->y1 = pArray->GetNumberAt(quadIndex * 8 + 1);
342 quadPoints->x2 = pArray->GetNumberAt(quadIndex * 8 + 2);
343 quadPoints->y2 = pArray->GetNumberAt(quadIndex * 8 + 3);
344 quadPoints->x3 = pArray->GetNumberAt(quadIndex * 8 + 4);
345 quadPoints->y3 = pArray->GetNumberAt(quadIndex * 8 + 5);
346 quadPoints->x4 = pArray->GetNumberAt(quadIndex * 8 + 6);
347 quadPoints->y4 = pArray->GetNumberAt(quadIndex * 8 + 7);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700348 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700349 }
350 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700351}
352
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700353DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc,
354 FPDF_BYTESTRING tag,
355 void* buffer,
356 unsigned long buflen) {
Tom Sepez471a1032015-10-15 16:17:18 -0700357 if (!tag)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358 return 0;
Tom Sepez471a1032015-10-15 16:17:18 -0700359 CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(doc);
360 if (!pDoc)
361 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700362 CPDF_Dictionary* pInfo = pDoc->GetInfo();
363 if (!pInfo)
364 return 0;
Wei Li9b761132016-01-29 15:44:20 -0800365 CFX_WideString text = pInfo->GetUnicodeTextBy(tag);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700366 // Use UTF-16LE encoding
367 CFX_ByteString encodedText = text.UTF16LE_Encode();
368 unsigned long len = encodedText.GetLength();
369 if (buffer && buflen >= len) {
370 FXSYS_memcpy(buffer, encodedText.c_str(), len);
371 }
372 return len;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700373}