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
17DLLEXPORT 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}
35DLLEXPORT 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}
43DLLEXPORT 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}
49DLLEXPORT 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}
60DLLEXPORT 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
72DLLEXPORT 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
88DLLEXPORT 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
95DLLEXPORT 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
113DLLEXPORT 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}
120DLLEXPORT 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
133DLLEXPORT 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
158DLLEXPORT 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		textpageFind->FindFirst(CFX_WideString::FromUTF16LE(findwhat),flags,start_index);
166	}
167	catch (...)
168	{
169		if (textpageFind)
170			delete textpageFind;
171		return NULL;
172	}
173	return textpageFind;
174}
175DLLEXPORT FPDF_BOOL	STDCALL FPDFText_FindNext(FPDF_SCHHANDLE handle)
176{
177	if (!handle) return FALSE;
178	IPDF_TextPageFind* textpageFind=(IPDF_TextPageFind*)handle;
179	return	textpageFind->FindNext();
180}
181DLLEXPORT FPDF_BOOL STDCALL FPDFText_FindPrev(FPDF_SCHHANDLE handle)
182{
183	if (!handle) return FALSE;
184	IPDF_TextPageFind* textpageFind=(IPDF_TextPageFind*)handle;
185	return	textpageFind->FindPrev();
186}
187DLLEXPORT int STDCALL FPDFText_GetSchResultIndex(FPDF_SCHHANDLE handle)
188{
189	if (!handle) return 0;
190	IPDF_TextPageFind* textpageFind=(IPDF_TextPageFind*)handle;
191	return textpageFind->GetCurOrder();
192}
193DLLEXPORT int STDCALL FPDFText_GetSchCount(FPDF_SCHHANDLE handle)
194{
195	if (!handle) return 0;
196	IPDF_TextPageFind* textpageFind=(IPDF_TextPageFind*)handle;
197	return textpageFind->GetMatchedCount();
198}
199DLLEXPORT void STDCALL FPDFText_FindClose(FPDF_SCHHANDLE handle)
200{
201	if (!handle) return;
202	IPDF_TextPageFind* textpageFind=(IPDF_TextPageFind*)handle;
203	delete	textpageFind;
204	handle=NULL;
205}
206
207//web link
208DLLEXPORT FPDF_PAGELINK STDCALL FPDFLink_LoadWebLinks(FPDF_TEXTPAGE text_page)
209{
210	if (!text_page) return NULL;
211	IPDF_LinkExtract* pageLink=NULL;
212	try
213	{
214		pageLink=IPDF_LinkExtract::CreateLinkExtract();
215		pageLink->ExtractLinks((IPDF_TextPage*)text_page);
216	}
217	catch (...)
218	{
219		if (pageLink)
220			delete pageLink;
221		return NULL;
222	}
223	return pageLink;
224}
225DLLEXPORT int STDCALL FPDFLink_CountWebLinks(FPDF_PAGELINK link_page)
226{
227	if (!link_page) return 0;
228	IPDF_LinkExtract* pageLink=(IPDF_LinkExtract*)link_page;
229	return	pageLink->CountLinks();
230}
231DLLEXPORT int STDCALL FPDFLink_GetURL(FPDF_PAGELINK link_page,int link_index, unsigned short* buffer,int buflen)
232{
233	if (!link_page) return 0;
234	IPDF_LinkExtract* pageLink=(IPDF_LinkExtract*)link_page;
235	CFX_WideString url=pageLink->GetURL(link_index);
236
237	CFX_ByteString cbUTF16URL = url.UTF16LE_Encode();
238	int len= cbUTF16URL.GetLength()/sizeof(unsigned short);
239	if (buffer==NULL || buflen<=0)
240		return len;
241	int size=len<buflen ? len :buflen;
242	if (size>0)
243	{
244		FXSYS_memcpy(buffer,cbUTF16URL.GetBuffer(size*sizeof(unsigned short)),size*sizeof(unsigned short));
245		cbUTF16URL.ReleaseBuffer(size*sizeof(unsigned short));
246	}
247	return size;
248}
249DLLEXPORT int STDCALL FPDFLink_CountRects(FPDF_PAGELINK link_page,int link_index)
250{
251	if (!link_page) return 0;
252	IPDF_LinkExtract* pageLink=(IPDF_LinkExtract*)link_page;
253	CFX_RectArray rectArray;
254	pageLink->GetRects(link_index,rectArray);
255	return rectArray.GetSize();
256}
257DLLEXPORT void STDCALL FPDFLink_GetRect(FPDF_PAGELINK link_page,int link_index,  int rect_index, double* left,
258										double*  top,double*  right, double*  bottom)
259{
260	if (!link_page) return;
261	IPDF_LinkExtract* pageLink=(IPDF_LinkExtract*)link_page;
262	CFX_RectArray rectArray;
263	pageLink->GetRects(link_index,rectArray);
264	CFX_FloatRect rect;
265	rect=rectArray.GetAt(rect_index);
266	*left=rect.left;
267	*right=rect.right;
268	*top=rect.top;
269	*bottom=rect.bottom;
270}
271DLLEXPORT void	STDCALL	FPDFLink_CloseWebLinks(FPDF_PAGELINK link_page)
272{
273	if (!link_page) return;
274	IPDF_LinkExtract* pageLink=(IPDF_LinkExtract*)link_page;
275	delete pageLink;
276	pageLink =NULL;
277}
278
279