blob: 8a93d2299d70958f232828a10af3b9c6a2e4d268 [file] [log] [blame]
thestig9067fd62016-11-23 14:10:06 -08001// Copyright 2016 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#include "public/fpdf_structtree.h"
6
Tom Sepezf4a8c722017-01-26 16:37:20 -08007#include <memory>
8
thestig9067fd62016-11-23 14:10:06 -08009#include "core/fpdfapi/page/cpdf_page.h"
10#include "core/fpdfapi/parser/cpdf_dictionary.h"
11#include "core/fpdfdoc/fpdf_tagged.h"
12#include "fpdfsdk/fsdk_define.h"
13
14namespace {
15
16IPDF_StructTree* ToStructTree(FPDF_STRUCTTREE struct_tree) {
17 return reinterpret_cast<IPDF_StructTree*>(struct_tree);
18}
19
20IPDF_StructElement* ToStructTreeElement(FPDF_STRUCTELEMENT struct_element) {
21 return reinterpret_cast<IPDF_StructElement*>(struct_element);
22}
23
Dan Sinclair29479f62017-04-04 10:48:19 -040024unsigned long WideStringToBuffer(const CFX_WideString& str,
25 void* buffer,
26 unsigned long buflen) {
27 if (str.IsEmpty())
28 return 0;
29
30 CFX_ByteString encodedStr = str.UTF16LE_Encode();
31 const unsigned long len = encodedStr.GetLength();
32 if (buffer && len <= buflen)
33 memcpy(buffer, encodedStr.c_str(), len);
34 return len;
35}
36
thestig9067fd62016-11-23 14:10:06 -080037} // namespace
38
39DLLEXPORT FPDF_STRUCTTREE STDCALL FPDF_StructTree_GetForPage(FPDF_PAGE page) {
40 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
41 if (!pPage)
42 return nullptr;
tsepezd5b81ce2016-12-16 14:45:46 -080043 return IPDF_StructTree::LoadPage(pPage->m_pDocument, pPage->m_pFormDict)
44 .release();
thestig9067fd62016-11-23 14:10:06 -080045}
46
47DLLEXPORT void STDCALL FPDF_StructTree_Close(FPDF_STRUCTTREE struct_tree) {
Tom Sepezf4a8c722017-01-26 16:37:20 -080048 std::unique_ptr<IPDF_StructTree>(ToStructTree(struct_tree));
thestig9067fd62016-11-23 14:10:06 -080049}
50
51DLLEXPORT int STDCALL
52FPDF_StructTree_CountChildren(FPDF_STRUCTTREE struct_tree) {
53 IPDF_StructTree* tree = ToStructTree(struct_tree);
54 return tree ? tree->CountTopElements() : -1;
55}
56
57DLLEXPORT FPDF_STRUCTELEMENT STDCALL
58FPDF_StructTree_GetChildAtIndex(FPDF_STRUCTTREE struct_tree, int index) {
59 IPDF_StructTree* tree = ToStructTree(struct_tree);
60 if (!tree || index < 0 || index >= tree->CountTopElements())
61 return nullptr;
62 return tree->GetTopElement(index);
63}
64
65DLLEXPORT unsigned long STDCALL
66FPDF_StructElement_GetAltText(FPDF_STRUCTELEMENT struct_element,
67 void* buffer,
68 unsigned long buflen) {
69 IPDF_StructElement* elem = ToStructTreeElement(struct_element);
Dan Sinclair29479f62017-04-04 10:48:19 -040070 return (elem && elem->GetDict())
71 ? WideStringToBuffer(elem->GetDict()->GetUnicodeTextFor("Alt"),
72 buffer, buflen)
73 : 0;
74}
thestig9067fd62016-11-23 14:10:06 -080075
Dan Sinclair29479f62017-04-04 10:48:19 -040076DLLEXPORT unsigned long STDCALL
77FPDF_StructElement_GetType(FPDF_STRUCTELEMENT struct_element,
78 void* buffer,
79 unsigned long buflen) {
80 IPDF_StructElement* elem = ToStructTreeElement(struct_element);
81 return elem ? WideStringToBuffer(elem->GetType().UTF8Decode(), buffer, buflen)
82 : 0;
thestig9067fd62016-11-23 14:10:06 -080083}
84
85DLLEXPORT int STDCALL
86FPDF_StructElement_CountChildren(FPDF_STRUCTELEMENT struct_element) {
87 IPDF_StructElement* elem = ToStructTreeElement(struct_element);
88 return elem ? elem->CountKids() : -1;
89}
90
91DLLEXPORT FPDF_STRUCTELEMENT STDCALL
92FPDF_StructElement_GetChildAtIndex(FPDF_STRUCTELEMENT struct_element,
93 int index) {
94 IPDF_StructElement* elem = ToStructTreeElement(struct_element);
95 if (!elem || index < 0 || index >= elem->CountKids())
96 return nullptr;
97
tsepez0370d6b2017-01-26 12:15:34 -080098 return elem->GetKidIfElement(index);
thestig9067fd62016-11-23 14:10:06 -080099}