Revert "Add type cast definitions for CPDF_Reference."
[pdfium.git] / fpdfsdk / src / fpdftext.cpp
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 "../../core/include/fpdfdoc/fpdf_doc.h"
8 #include "../../core/include/fpdftext/fpdf_text.h"
9 #include "../../public/fpdf_text.h"
10 #include "../include/fsdk_define.h"
11
12 #ifdef _WIN32
13 #include <tchar.h>
14 #endif
15
16 DLLEXPORT FPDF_TEXTPAGE STDCALL FPDFText_LoadPage(FPDF_PAGE page) {
17   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
18   if (!pPage)
19     return nullptr;
20   CPDF_ViewerPreferences viewRef(pPage->m_pDocument);
21   IPDF_TextPage* textpage =
22       IPDF_TextPage::CreateTextPage(pPage, viewRef.IsDirectionR2L());
23   textpage->ParseTextPage();
24   return textpage;
25 }
26 DLLEXPORT void STDCALL FPDFText_ClosePage(FPDF_TEXTPAGE text_page) {
27   delete (IPDF_TextPage*)text_page;
28 }
29 DLLEXPORT int STDCALL FPDFText_CountChars(FPDF_TEXTPAGE text_page) {
30   if (!text_page)
31     return -1;
32   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
33   return textpage->CountChars();
34 }
35 DLLEXPORT unsigned int STDCALL FPDFText_GetUnicode(FPDF_TEXTPAGE text_page,
36                                                    int index) {
37   if (!text_page)
38     return -1;
39   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
40
41   if (index < 0 || index >= textpage->CountChars())
42     return 0;
43
44   FPDF_CHAR_INFO charinfo;
45   textpage->GetCharInfo(index, charinfo);
46   return charinfo.m_Unicode;
47 }
48 DLLEXPORT double STDCALL FPDFText_GetFontSize(FPDF_TEXTPAGE text_page,
49                                               int index) {
50   if (!text_page)
51     return 0;
52   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
53
54   if (index < 0 || index >= textpage->CountChars())
55     return 0;
56
57   FPDF_CHAR_INFO charinfo;
58   textpage->GetCharInfo(index, charinfo);
59   return charinfo.m_FontSize;
60 }
61
62 DLLEXPORT void STDCALL FPDFText_GetCharBox(FPDF_TEXTPAGE text_page,
63                                            int index,
64                                            double* left,
65                                            double* right,
66                                            double* bottom,
67                                            double* top) {
68   if (!text_page)
69     return;
70   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
71
72   if (index < 0 || index >= textpage->CountChars())
73     return;
74   FPDF_CHAR_INFO charinfo;
75   textpage->GetCharInfo(index, charinfo);
76   *left = charinfo.m_CharBox.left;
77   *right = charinfo.m_CharBox.right;
78   *bottom = charinfo.m_CharBox.bottom;
79   *top = charinfo.m_CharBox.top;
80 }
81
82 // select
83 DLLEXPORT int STDCALL FPDFText_GetCharIndexAtPos(FPDF_TEXTPAGE text_page,
84                                                  double x,
85                                                  double y,
86                                                  double xTolerance,
87                                                  double yTolerance) {
88   if (!text_page)
89     return -3;
90   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
91   return textpage->GetIndexAtPos((FX_FLOAT)x, (FX_FLOAT)y, (FX_FLOAT)xTolerance,
92                                  (FX_FLOAT)yTolerance);
93 }
94
95 DLLEXPORT int STDCALL FPDFText_GetText(FPDF_TEXTPAGE text_page,
96                                        int start,
97                                        int count,
98                                        unsigned short* result) {
99   if (!text_page)
100     return 0;
101   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
102
103   if (start >= textpage->CountChars())
104     return 0;
105
106   CFX_WideString str = textpage->GetPageText(start, count);
107   if (str.GetLength() > count)
108     str = str.Left(count);
109
110   CFX_ByteString cbUTF16str = str.UTF16LE_Encode();
111   FXSYS_memcpy(result, cbUTF16str.GetBuffer(cbUTF16str.GetLength()),
112                cbUTF16str.GetLength());
113   cbUTF16str.ReleaseBuffer(cbUTF16str.GetLength());
114
115   return cbUTF16str.GetLength() / sizeof(unsigned short);
116 }
117
118 DLLEXPORT int STDCALL FPDFText_CountRects(FPDF_TEXTPAGE text_page,
119                                           int start,
120                                           int count) {
121   if (!text_page)
122     return 0;
123   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
124   return textpage->CountRects(start, count);
125 }
126 DLLEXPORT void STDCALL FPDFText_GetRect(FPDF_TEXTPAGE text_page,
127                                         int rect_index,
128                                         double* left,
129                                         double* top,
130                                         double* right,
131                                         double* bottom) {
132   if (!text_page)
133     return;
134   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
135   CFX_FloatRect rect;
136   textpage->GetRect(rect_index, rect.left, rect.top, rect.right, rect.bottom);
137   *left = rect.left;
138   *top = rect.top;
139   *right = rect.right;
140   *bottom = rect.bottom;
141 }
142
143 DLLEXPORT int STDCALL FPDFText_GetBoundedText(FPDF_TEXTPAGE text_page,
144                                               double left,
145                                               double top,
146                                               double right,
147                                               double bottom,
148                                               unsigned short* buffer,
149                                               int buflen) {
150   if (!text_page)
151     return 0;
152   IPDF_TextPage* textpage = (IPDF_TextPage*)text_page;
153   CFX_FloatRect rect((FX_FLOAT)left, (FX_FLOAT)bottom, (FX_FLOAT)right,
154                      (FX_FLOAT)top);
155   CFX_WideString str = textpage->GetTextByRect(rect);
156
157   if (buflen <= 0 || buffer == NULL) {
158     return str.GetLength();
159   }
160
161   CFX_ByteString cbUTF16Str = str.UTF16LE_Encode();
162   int len = cbUTF16Str.GetLength() / sizeof(unsigned short);
163   int size = buflen > len ? len : buflen;
164   FXSYS_memcpy(buffer, cbUTF16Str.GetBuffer(size * sizeof(unsigned short)),
165                size * sizeof(unsigned short));
166   cbUTF16Str.ReleaseBuffer(size * sizeof(unsigned short));
167
168   return size;
169 }
170
171 // Search
172 //-1 for end
173 DLLEXPORT FPDF_SCHHANDLE STDCALL FPDFText_FindStart(FPDF_TEXTPAGE text_page,
174                                                     FPDF_WIDESTRING findwhat,
175                                                     unsigned long flags,
176                                                     int start_index) {
177   if (!text_page)
178     return NULL;
179   IPDF_TextPageFind* textpageFind = NULL;
180   textpageFind = IPDF_TextPageFind::CreatePageFind((IPDF_TextPage*)text_page);
181   FX_STRSIZE len = CFX_WideString::WStringLength(findwhat);
182   textpageFind->FindFirst(CFX_WideString::FromUTF16LE(findwhat, len), flags,
183                           start_index);
184   return textpageFind;
185 }
186 DLLEXPORT FPDF_BOOL STDCALL FPDFText_FindNext(FPDF_SCHHANDLE handle) {
187   if (!handle)
188     return FALSE;
189   IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
190   return textpageFind->FindNext();
191 }
192 DLLEXPORT FPDF_BOOL STDCALL FPDFText_FindPrev(FPDF_SCHHANDLE handle) {
193   if (!handle)
194     return FALSE;
195   IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
196   return textpageFind->FindPrev();
197 }
198 DLLEXPORT int STDCALL FPDFText_GetSchResultIndex(FPDF_SCHHANDLE handle) {
199   if (!handle)
200     return 0;
201   IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
202   return textpageFind->GetCurOrder();
203 }
204 DLLEXPORT int STDCALL FPDFText_GetSchCount(FPDF_SCHHANDLE handle) {
205   if (!handle)
206     return 0;
207   IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
208   return textpageFind->GetMatchedCount();
209 }
210 DLLEXPORT void STDCALL FPDFText_FindClose(FPDF_SCHHANDLE handle) {
211   if (!handle)
212     return;
213   IPDF_TextPageFind* textpageFind = (IPDF_TextPageFind*)handle;
214   delete textpageFind;
215   handle = NULL;
216 }
217
218 // web link
219 DLLEXPORT FPDF_PAGELINK STDCALL FPDFLink_LoadWebLinks(FPDF_TEXTPAGE text_page) {
220   if (!text_page)
221     return NULL;
222   IPDF_LinkExtract* pageLink = NULL;
223   pageLink = IPDF_LinkExtract::CreateLinkExtract();
224   pageLink->ExtractLinks((IPDF_TextPage*)text_page);
225   return pageLink;
226 }
227 DLLEXPORT int STDCALL FPDFLink_CountWebLinks(FPDF_PAGELINK link_page) {
228   if (!link_page)
229     return 0;
230   IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
231   return pageLink->CountLinks();
232 }
233 DLLEXPORT int STDCALL FPDFLink_GetURL(FPDF_PAGELINK link_page,
234                                       int link_index,
235                                       unsigned short* buffer,
236                                       int buflen) {
237   if (!link_page)
238     return 0;
239   IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
240   CFX_WideString url = pageLink->GetURL(link_index);
241
242   CFX_ByteString cbUTF16URL = url.UTF16LE_Encode();
243   int len = cbUTF16URL.GetLength() / sizeof(unsigned short);
244   if (buffer == NULL || buflen <= 0)
245     return len;
246   int size = len < buflen ? len : buflen;
247   if (size > 0) {
248     FXSYS_memcpy(buffer, cbUTF16URL.GetBuffer(size * sizeof(unsigned short)),
249                  size * sizeof(unsigned short));
250     cbUTF16URL.ReleaseBuffer(size * sizeof(unsigned short));
251   }
252   return size;
253 }
254 DLLEXPORT int STDCALL FPDFLink_CountRects(FPDF_PAGELINK link_page,
255                                           int link_index) {
256   if (!link_page)
257     return 0;
258   IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
259   CFX_RectArray rectArray;
260   pageLink->GetRects(link_index, rectArray);
261   return rectArray.GetSize();
262 }
263 DLLEXPORT void STDCALL FPDFLink_GetRect(FPDF_PAGELINK link_page,
264                                         int link_index,
265                                         int rect_index,
266                                         double* left,
267                                         double* top,
268                                         double* right,
269                                         double* bottom) {
270   if (!link_page)
271     return;
272   IPDF_LinkExtract* pageLink = (IPDF_LinkExtract*)link_page;
273   CFX_RectArray rectArray;
274   pageLink->GetRects(link_index, rectArray);
275   if (rect_index >= 0 && rect_index < rectArray.GetSize()) {
276     CFX_FloatRect rect = rectArray.GetAt(rect_index);
277     *left = rect.left;
278     *right = rect.right;
279     *top = rect.top;
280     *bottom = rect.bottom;
281   }
282 }
283 DLLEXPORT void STDCALL FPDFLink_CloseWebLinks(FPDF_PAGELINK link_page) {
284   delete (IPDF_LinkExtract*)link_page;
285 }