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