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