• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/fxedit/fxet_stub.h"
8 #include "../../include/fxedit/fx_edit.h"
9 #include "../../include/fxedit/fxet_edit.h"
10 
11 #define FX_EDIT_UNDERLINEHALFWIDTH				0.5f
12 #define FX_EDIT_CROSSOUTHALFWIDTH				0.5f
13 
14 extern CFX_ByteString GetPDFWordString(IFX_Edit_FontMap * pFontMap, FX_INT32 nFontIndex, FX_WORD Word, FX_WORD SubWord);
15 
GetUnderLineRect(const CPVT_Word & word)16 CPDF_Rect GetUnderLineRect(const CPVT_Word& word)
17 {
18 	return CPDF_Rect(word.ptWord.x, word.ptWord.y + word.fDescent * 0.5f,
19 						word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent * 0.25f);
20 }
21 
GetCrossoutRect(const CPVT_Word & word)22 CPDF_Rect GetCrossoutRect(const CPVT_Word& word)
23 {
24 	return CPDF_Rect(word.ptWord.x, word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f + word.fDescent * 0.25f,
25 							word.ptWord.x + word.fWidth, word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f);
26 }
27 
DrawTextString(CFX_RenderDevice * pDevice,const CPDF_Point & pt,CPDF_Font * pFont,FX_FLOAT fFontSize,CPDF_Matrix * pUser2Device,const CFX_ByteString & str,FX_ARGB crTextFill,FX_ARGB crTextStroke,FX_INT32 nHorzScale)28 static void DrawTextString(CFX_RenderDevice* pDevice, const CPDF_Point& pt, CPDF_Font* pFont, FX_FLOAT fFontSize, CPDF_Matrix* pUser2Device,
29 					  const CFX_ByteString& str, FX_ARGB crTextFill, FX_ARGB crTextStroke, FX_INT32 nHorzScale)
30 {
31 	FX_FLOAT x = pt.x, y = pt.y;
32 	pUser2Device->Transform(x, y);
33 
34 	if (pFont)
35 	{
36 		if (nHorzScale != 100)
37 		{
38 			CPDF_Matrix mt(nHorzScale/100.0f,0,0,1,0,0);
39 			mt.Concat(*pUser2Device);
40 
41 			CPDF_RenderOptions ro;
42 			ro.m_Flags = RENDER_CLEARTYPE;
43 			ro.m_ColorMode = RENDER_COLOR_NORMAL;
44 
45 			if (crTextStroke != 0)
46 			{
47 				CPDF_Point pt1(0,0), pt2(1,0);
48 				pUser2Device->Transform(pt1.x, pt1.y);
49 				pUser2Device->Transform(pt2.x, pt2.y);
50 				CFX_GraphStateData gsd;
51 				gsd.m_LineWidth = (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
52 
53 				CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, &mt, str, crTextFill, crTextStroke, &gsd, &ro);
54 			}
55 			else
56 				CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, &mt, str, crTextFill, 0, NULL, &ro);
57 		}
58 		else
59 		{
60 			CPDF_RenderOptions ro;
61 			ro.m_Flags = RENDER_CLEARTYPE;
62 			ro.m_ColorMode = RENDER_COLOR_NORMAL;
63 
64 			if (crTextStroke != 0)
65 			{
66 				CPDF_Point pt1(0,0), pt2(1,0);
67 				pUser2Device->Transform(pt1.x, pt1.y);
68 				pUser2Device->Transform(pt2.x, pt2.y);
69 				CFX_GraphStateData gsd;
70 				gsd.m_LineWidth = (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y));
71 
72 				CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, pUser2Device, str, crTextFill, crTextStroke, &gsd, &ro);
73 			}
74 			else
75 				CPDF_TextRenderer::DrawTextString(pDevice,x, y, pFont, fFontSize, pUser2Device, str, crTextFill, 0, NULL, &ro);
76 		}
77 	}
78 }
79 
DrawUnderline(CFX_RenderDevice * pDevice,CPDF_Matrix * pUser2Device,IFX_Edit * pEdit,FX_COLORREF color,const CPDF_Rect & rcClip,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange)80 void IFX_Edit::DrawUnderline(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit, FX_COLORREF color,
81 								const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange)
82 {
83 	pDevice->SaveState();
84 
85 	if (!rcClip.IsEmpty())
86 	{
87 		CPDF_Rect rcTemp = rcClip;
88 		pUser2Device->TransformRect(rcTemp);
89 		FX_RECT rcDevClip;
90 		rcDevClip.left = (FX_INT32)rcTemp.left;
91 		rcDevClip.right = (FX_INT32)rcTemp.right;
92 		rcDevClip.top = (FX_INT32)rcTemp.top;
93 		rcDevClip.bottom = (FX_INT32)rcTemp.bottom;
94 		pDevice->SetClip_Rect(&rcDevClip);
95 	}
96 
97 	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
98 	{
99 		if (pEdit->GetFontMap())
100 		{
101 			if (pRange)
102 				pIterator->SetAt(pRange->BeginPos);
103 			else
104 				pIterator->SetAt(0);
105 
106 			while (pIterator->NextWord())
107 			{
108 				CPVT_WordPlace place = pIterator->GetAt();
109 				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
110 
111 				CPVT_Word word;
112 				if (pIterator->GetWord(word))
113 				{
114 					CFX_PathData pathUnderline;
115 					CPDF_Rect rcUnderline = GetUnderLineRect(word);
116 					rcUnderline.left += ptOffset.x;
117 					rcUnderline.right += ptOffset.x;
118 					rcUnderline.top += ptOffset.y;
119 					rcUnderline.bottom += ptOffset.y;
120 					pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, rcUnderline.right, rcUnderline.top);
121 
122 					pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, color, 0, FXFILL_WINDING);
123 				}
124 			}
125 		}
126 	}
127 
128 	pDevice->RestoreState();
129 }
130 
DrawEdit(CFX_RenderDevice * pDevice,CPDF_Matrix * pUser2Device,IFX_Edit * pEdit,FX_COLORREF crTextFill,FX_COLORREF crTextStroke,const CPDF_Rect & rcClip,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange,IFX_SystemHandler * pSystemHandler,void * pFFLData)131 void IFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit, FX_COLORREF crTextFill, FX_COLORREF crTextStroke,
132 						const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, IFX_SystemHandler* pSystemHandler, void* pFFLData)
133 {
134 
135 	FX_BOOL bContinuous = pEdit->GetCharArray() == 0;
136 	if (pEdit->GetCharSpace() > 0.0f)
137 		bContinuous = FALSE;
138 
139 	FX_WORD SubWord = pEdit->GetPasswordChar();
140 	FX_FLOAT fFontSize = pEdit->GetFontSize();
141 	CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
142 	FX_INT32 nHorzScale = pEdit->GetHorzScale();
143 
144 	FX_COLORREF crCurFill = crTextFill;
145 	FX_COLORREF crOldFill = crCurFill;
146 
147 	FX_BOOL bSelect = FALSE;
148 	const FX_COLORREF crWhite = ArgbEncode(255,255,255,255);
149 	const FX_COLORREF crSelBK = ArgbEncode(255,0,51,113);
150 
151 	CFX_ByteTextBuf sTextBuf;
152 	FX_INT32 nFontIndex = -1;
153 	CPDF_Point ptBT(0.0f,0.0f);
154 
155 	pDevice->SaveState();
156 
157 	if (!rcClip.IsEmpty())
158 	{
159 		CPDF_Rect rcTemp = rcClip;
160 		pUser2Device->TransformRect(rcTemp);
161 		FX_RECT rcDevClip;
162 		rcDevClip.left = (FX_INT32)rcTemp.left;
163 		rcDevClip.right = (FX_INT32)rcTemp.right;
164 		rcDevClip.top = (FX_INT32)rcTemp.top;
165 		rcDevClip.bottom = (FX_INT32)rcTemp.bottom;
166 		pDevice->SetClip_Rect(&rcDevClip);
167 	}
168 
169 	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
170 	{
171 		if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
172 		{
173 			if (pRange)
174 				pIterator->SetAt(pRange->BeginPos);
175 			else
176 				pIterator->SetAt(0);
177 
178 			CPVT_WordPlace oldplace;
179 
180 			while (pIterator->NextWord())
181 			{
182 				CPVT_WordPlace place = pIterator->GetAt();
183 				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
184 
185 				if (wrSelect.IsExist())
186 				{
187 					bSelect = place.WordCmp(wrSelect.BeginPos) > 0 && place.WordCmp(wrSelect.EndPos) <= 0;
188 					if (bSelect)
189 					{
190 						crCurFill = crWhite;
191 					}
192 					else
193 					{
194 						crCurFill = crTextFill;
195 					}
196 				}
197 				if(pSystemHandler && pSystemHandler->IsSelectionImplemented())
198 				{
199 					crCurFill = crTextFill;
200  					crOldFill = crCurFill;
201 				}
202 				CPVT_Word word;
203 				if (pIterator->GetWord(word))
204 				{
205 
206 					if (bSelect)
207 					{
208 
209 						CPVT_Line line;
210 						pIterator->GetLine(line);
211 
212 						if(pSystemHandler && pSystemHandler->IsSelectionImplemented())
213 						{
214 							CPDF_Rect rc(word.ptWord.x,line.ptLine.y + line.fLineDescent,
215 								word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
216 							rc.Intersect(rcClip);
217 							//CFX_Edit* pEt = (CFX_Edit*)pEdit;
218 							//CPDF_Rect rcEdit = pEt->VTToEdit(rc);
219 							pSystemHandler->OutputSelectedRect(pFFLData,rc);
220 						}
221 						else
222 						{
223  							CFX_PathData pathSelBK;
224  							pathSelBK.AppendRect(word.ptWord.x,line.ptLine.y + line.fLineDescent,
225  								word.ptWord.x+word.fWidth,line.ptLine.y + line.fLineAscent);
226 
227  							pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0, FXFILL_WINDING);
228 						}
229 					}
230 
231 					if (bContinuous)
232 					{
233 						if (place.LineCmp(oldplace) != 0 || word.nFontIndex != nFontIndex ||
234 							crOldFill != crCurFill)
235 						{
236 							if (sTextBuf.GetLength() > 0)
237 							{
238 								DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(nFontIndex),
239 									fFontSize, pUser2Device, sTextBuf.GetByteString(), crOldFill, crTextStroke, nHorzScale);
240 
241 								sTextBuf.Clear();
242 							}
243 							nFontIndex = word.nFontIndex;
244 							ptBT = word.ptWord;
245 							crOldFill = crCurFill;
246 						}
247 
248 						sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord);
249 					}
250 					else
251 					{
252 						DrawTextString(pDevice,CPDF_Point(word.ptWord.x+ptOffset.x, word.ptWord.y+ptOffset.y), pFontMap->GetPDFFont(word.nFontIndex),
253 							fFontSize, pUser2Device, GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord), crCurFill, crTextStroke, nHorzScale);
254 
255 					}
256 					oldplace = place;
257 
258 
259 				}
260 			}
261 
262 			if (sTextBuf.GetLength() > 0)
263 			{
264 				DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(nFontIndex),
265 					fFontSize, pUser2Device, sTextBuf.GetByteString(), crOldFill, crTextStroke, nHorzScale);
266 			}
267 		}
268 	}
269 
270 	pDevice->RestoreState();
271 }
272 
DrawRichEdit(CFX_RenderDevice * pDevice,CPDF_Matrix * pUser2Device,IFX_Edit * pEdit,const CPDF_Rect & rcClip,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange)273 void IFX_Edit::DrawRichEdit(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, IFX_Edit* pEdit,
274 						const CPDF_Rect& rcClip, const CPDF_Point& ptOffset, const CPVT_WordRange* pRange)
275 {
276 	//FX_FLOAT fFontSize = pEdit->GetFontSize();
277 	CPVT_WordRange wrSelect = pEdit->GetSelectWordRange();
278 
279 	FX_COLORREF crCurText = ArgbEncode(255, 0,0,0);
280 	FX_COLORREF crOld = crCurText;
281 	FX_BOOL bSelect = FALSE;
282 	const FX_COLORREF crWhite = ArgbEncode(255,255,255,255);
283 	const FX_COLORREF crSelBK = ArgbEncode(255,0,51,113);
284 
285 	CFX_ByteTextBuf sTextBuf;
286 	CPVT_WordProps wp;
287 	CPDF_Point ptBT(0.0f,0.0f);
288 
289 	pDevice->SaveState();
290 
291 	if (!rcClip.IsEmpty())
292 	{
293 		CPDF_Rect rcTemp = rcClip;
294 		pUser2Device->TransformRect(rcTemp);
295 		FX_RECT rcDevClip;
296 		rcDevClip.left = (FX_INT32)rcTemp.left;
297 		rcDevClip.right = (FX_INT32)rcTemp.right;
298 		rcDevClip.top = (FX_INT32)rcTemp.top;
299 		rcDevClip.bottom = (FX_INT32)rcTemp.bottom;
300 		pDevice->SetClip_Rect(&rcDevClip);
301 	}
302 
303 	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
304 	{
305 		if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
306 		{
307 			if (pRange)
308 				pIterator->SetAt(pRange->BeginPos);
309 			else
310 				pIterator->SetAt(0);
311 
312 			CPVT_WordPlace oldplace;
313 
314 			while (pIterator->NextWord())
315 			{
316 				CPVT_WordPlace place = pIterator->GetAt();
317 				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
318 
319 				CPVT_Word word;
320 				if (pIterator->GetWord(word))
321 				{
322 					word.WordProps.fFontSize = word.fFontSize;
323 
324 					crCurText = ArgbEncode(255,word.WordProps.dwWordColor);
325 
326 					if (wrSelect.IsExist())
327 					{
328 						bSelect = place.WordCmp(wrSelect.BeginPos) > 0 && place.WordCmp(wrSelect.EndPos) <= 0;
329 						if (bSelect)
330 						{
331 							crCurText = crWhite;
332 						}
333 					}
334 
335 					if (bSelect)
336 					{
337 						CPVT_Line line;
338 						pIterator->GetLine(line);
339 
340 						CFX_PathData pathSelBK;
341 						pathSelBK.AppendRect(word.ptWord.x		+ ptOffset.x,
342 							line.ptLine.y + line.fLineDescent	+ ptOffset.y,
343 							word.ptWord.x+word.fWidth			+ ptOffset.x,
344 							line.ptLine.y + line.fLineAscent	+ ptOffset.y);
345 
346 						pDevice->DrawPath(&pathSelBK, pUser2Device, NULL, crSelBK, 0, FXFILL_WINDING);
347 					}
348 
349 					if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || word.WordProps.nHorzScale != 100 ||
350 						FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
351 						crOld != crCurText)
352 					{
353 						if (sTextBuf.GetLength() > 0)
354 						{
355 							DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(wp.nFontIndex),
356 								wp.fFontSize, pUser2Device, sTextBuf.GetByteString(), crOld, 0, wp.nHorzScale);
357 
358 							sTextBuf.Clear();
359 						}
360 						wp = word.WordProps;
361 						ptBT = word.ptWord;
362 						crOld = crCurText;
363 					}
364 
365 					sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, word.Word, 0);
366 
367 					if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE)
368 					{
369 						CFX_PathData pathUnderline;
370 						CPDF_Rect rcUnderline = GetUnderLineRect(word);
371 						pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, rcUnderline.right, rcUnderline.top);
372 
373 						pDevice->DrawPath(&pathUnderline, pUser2Device, NULL, crCurText, 0, FXFILL_WINDING);
374 					}
375 
376 					if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT)
377 					{
378 						CFX_PathData pathCrossout;
379 						CPDF_Rect rcCrossout = GetCrossoutRect(word);
380 						pathCrossout.AppendRect(rcCrossout.left, rcCrossout.bottom, rcCrossout.right, rcCrossout.top);
381 
382 						pDevice->DrawPath(&pathCrossout, pUser2Device, NULL, crCurText, 0, FXFILL_WINDING);
383 					}
384 
385 					oldplace = place;
386 				}
387 			}
388 
389 			if (sTextBuf.GetLength() > 0)
390 			{
391 				DrawTextString(pDevice, CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), pFontMap->GetPDFFont(wp.nFontIndex),
392 					wp.fFontSize, pUser2Device, sTextBuf.GetByteString(), crOld, 0, wp.nHorzScale);
393 			}
394 		}
395 	}
396 
397 	pDevice->RestoreState();
398 }
399 
AddRectToPageObjects(CPDF_PageObjects * pPageObjs,FX_COLORREF crFill,const CPDF_Rect & rcFill)400 static void AddRectToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crFill, const CPDF_Rect& rcFill)
401 {
402 	CPDF_PathObject* pPathObj = new CPDF_PathObject;
403 	CPDF_PathData* pPathData = pPathObj->m_Path.GetModify();
404 	pPathData->AppendRect(rcFill.left,rcFill.bottom,rcFill.right,rcFill.top);
405 
406 	FX_FLOAT rgb[3];
407 	rgb[0] = FXARGB_R(crFill) / 255.0f ;
408 	rgb[1] = FXARGB_G(crFill) / 255.0f;
409 	rgb[2] = FXARGB_B(crFill) / 255.0f;
410 	pPathObj->m_ColorState.SetFillColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3);
411 
412 	pPathObj->m_FillType = FXFILL_ALTERNATE;
413 	pPathObj->m_bStroke = FALSE;
414 
415 	pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pPathObj);
416 }
417 
AddTextObjToPageObjects(CPDF_PageObjects * pPageObjs,FX_COLORREF crText,CPDF_Font * pFont,FX_FLOAT fFontSize,FX_FLOAT fCharSpace,FX_INT32 nHorzScale,const CPDF_Point & point,const CFX_ByteString & text)418 static CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjects* pPageObjs, FX_COLORREF crText,
419 							 CPDF_Font* pFont, FX_FLOAT fFontSize, FX_FLOAT fCharSpace, FX_INT32 nHorzScale,
420 							 const CPDF_Point& point, const CFX_ByteString& text)
421 {
422 	CPDF_TextObject* pTxtObj = new CPDF_TextObject;
423 
424 	CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify();
425 	pTextStateData->m_pFont = pFont;
426 	pTextStateData->m_FontSize = fFontSize;
427 	pTextStateData->m_CharSpace = fCharSpace;
428 	pTextStateData->m_WordSpace = 0;
429 	pTextStateData->m_TextMode  = 0;
430 	pTextStateData->m_Matrix[0] = nHorzScale / 100.0f;
431 	pTextStateData->m_Matrix[1] = 0;
432 	pTextStateData->m_Matrix[2] = 0;
433 	pTextStateData->m_Matrix[3] = 1;
434 
435 	FX_FLOAT rgb[3];
436 	rgb[0] = FXARGB_R(crText) / 255.0f ;
437 	rgb[1] = FXARGB_G(crText) / 255.0f;
438 	rgb[2] = FXARGB_B(crText) / 255.0f;
439 	pTxtObj->m_ColorState.SetFillColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB),rgb, 3);
440 	pTxtObj->m_ColorState.SetStrokeColor(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB),rgb, 3);
441 
442 	pTxtObj->SetPosition(point.x,point.y);
443 	pTxtObj->SetText(text);
444 
445 	pPageObjs->InsertObject(pPageObjs->GetLastObjectPosition(),pTxtObj);
446 
447 	return pTxtObj;
448 }
449 
GeneratePageObjects(CPDF_PageObjects * pPageObjects,IFX_Edit * pEdit,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange,FX_COLORREF crText,CFX_ArrayTemplate<CPDF_TextObject * > & ObjArray)450 void IFX_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,
451 								   const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, FX_COLORREF crText, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray)
452 {
453 	FX_FLOAT fFontSize = pEdit->GetFontSize();
454 
455 	FX_INT32 nOldFontIndex = -1;
456 
457 	CFX_ByteTextBuf sTextBuf;
458 	CPDF_Point ptBT(0.0f,0.0f);
459 
460 	ObjArray.RemoveAll();
461 
462 	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
463 	{
464 		if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
465 		{
466 			if (pRange)
467 				pIterator->SetAt(pRange->BeginPos);
468 			else
469 				pIterator->SetAt(0);
470 
471 			CPVT_WordPlace oldplace;
472 
473 			while (pIterator->NextWord())
474 			{
475 				CPVT_WordPlace place = pIterator->GetAt();
476 				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
477 
478 				CPVT_Word word;
479 				if (pIterator->GetWord(word))
480 				{
481 					if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex)
482 					{
483 						if (sTextBuf.GetLength() > 0)
484 						{
485 							ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, 0.0f, 100,
486 								CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
487 
488 							sTextBuf.Clear();
489 						}
490 
491 						ptBT = word.ptWord;
492 						nOldFontIndex = word.nFontIndex;
493 					}
494 
495 					sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0);
496 					oldplace = place;
497 				}
498 			}
499 
500 			if (sTextBuf.GetLength() > 0)
501 			{
502 				ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, 0.0f, 100,
503 					CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
504 			}
505 		}
506 	}
507 }
508 
GenerateRichPageObjects(CPDF_PageObjects * pPageObjects,IFX_Edit * pEdit,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange,CFX_ArrayTemplate<CPDF_TextObject * > & ObjArray)509 void IFX_Edit::GenerateRichPageObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,
510 								   const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray)
511 {
512 
513 
514 	FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0);
515 	FX_COLORREF crOld = crCurText;
516 
517 
518 	CFX_ByteTextBuf sTextBuf;
519 	CPVT_WordProps wp;
520 	CPDF_Point ptBT(0.0f,0.0f);
521 
522 	ObjArray.RemoveAll();
523 
524 	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
525 	{
526 		if (IFX_Edit_FontMap* pFontMap = pEdit->GetFontMap())
527 		{
528 			if (pRange)
529 				pIterator->SetAt(pRange->BeginPos);
530 			else
531 				pIterator->SetAt(0);
532 
533 			CPVT_WordPlace oldplace;
534 
535 			while (pIterator->NextWord())
536 			{
537 				CPVT_WordPlace place = pIterator->GetAt();
538 				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
539 
540 				CPVT_Word word;
541 				if (pIterator->GetWord(word))
542 				{
543 					word.WordProps.fFontSize = word.fFontSize;
544 
545 					crCurText = ArgbEncode(255,word.WordProps.dwWordColor);
546 
547 					if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || word.WordProps.nHorzScale != 100 ||
548 						FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 ||
549 						crOld != crCurText)
550 					{
551 						if (sTextBuf.GetLength() > 0)
552 						{
553 							ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
554 								CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
555 
556 							sTextBuf.Clear();
557 						}
558 
559 						wp = word.WordProps;
560 						ptBT = word.ptWord;
561 						crOld = crCurText;
562 
563 					}
564 
565 					sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, word.Word, 0);
566 
567 					if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE)
568 					{/*
569 						AddLineToPageObjects(pPageObjects, crCurText,
570 							CPDF_Point(word.ptWord.x, word.ptWord.y + word.fDescent * 0.4f),
571 							CPDF_Point(word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent * 0.4f));
572 */
573 						CPDF_Rect rcUnderline = GetUnderLineRect(word);
574 						rcUnderline.left += ptOffset.x;
575 						rcUnderline.right += ptOffset.x;
576 						rcUnderline.top += ptOffset.y;
577 						rcUnderline.bottom += ptOffset.y;
578 
579 						AddRectToPageObjects(pPageObjects, crCurText, rcUnderline);
580 					}
581 
582 					if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT)
583 					{
584 						CPDF_Rect rcCrossout = GetCrossoutRect(word);
585 						rcCrossout.left += ptOffset.x;
586 						rcCrossout.right += ptOffset.x;
587 						rcCrossout.top += ptOffset.y;
588 						rcCrossout.bottom += ptOffset.y;
589 
590 						AddRectToPageObjects(pPageObjects, crCurText, rcCrossout);
591 					}
592 
593 					oldplace = place;
594 				}
595 			}
596 
597 			if (sTextBuf.GetLength() > 0)
598 			{
599 				ObjArray.Add(AddTextObjToPageObjects(pPageObjects, crOld, pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, wp.fCharSpace, wp.nHorzScale,
600 					CPDF_Point(ptBT.x+ptOffset.x, ptBT.y+ptOffset.y), sTextBuf.GetByteString()));
601 			}
602 		}
603 	}
604 }
605 
GenerateUnderlineObjects(CPDF_PageObjects * pPageObjects,IFX_Edit * pEdit,const CPDF_Point & ptOffset,const CPVT_WordRange * pRange,FX_COLORREF color)606 void IFX_Edit::GenerateUnderlineObjects(CPDF_PageObjects* pPageObjects, IFX_Edit* pEdit,
607 								   const CPDF_Point& ptOffset, const CPVT_WordRange* pRange, FX_COLORREF color)
608 {
609 
610 
611 	if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator())
612 	{
613 		if (pEdit->GetFontMap())
614 		{
615 			if (pRange)
616 				pIterator->SetAt(pRange->BeginPos);
617 			else
618 				pIterator->SetAt(0);
619 
620 			CPVT_WordPlace oldplace;
621 
622 			while (pIterator->NextWord())
623 			{
624 				CPVT_WordPlace place = pIterator->GetAt();
625 				if (pRange && place.WordCmp(pRange->EndPos) > 0) break;
626 
627 				CPVT_Word word;
628 				if (pIterator->GetWord(word))
629 				{
630 					CPDF_Rect rcUnderline = GetUnderLineRect(word);
631 					rcUnderline.left += ptOffset.x;
632 					rcUnderline.right += ptOffset.x;
633 					rcUnderline.top += ptOffset.y;
634 					rcUnderline.bottom += ptOffset.y;
635 					AddRectToPageObjects(pPageObjects, color, rcUnderline);
636 				}
637 			}
638 		}
639 	}
640 }
641 
642