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