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