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