OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" | 7 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" |
8 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobjectholder.h" | 8 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobjectholder.h" |
9 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h" | 9 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h" |
10 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" | 10 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" |
11 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" | 11 #include "core/fpdfapi/fpdf_render/include/cpdf_renderoptions.h" |
12 #include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h" | 12 #include "core/fpdfapi/fpdf_render/include/cpdf_textrenderer.h" |
13 #include "core/fpdfdoc/include/cpvt_word.h" | 13 #include "core/fpdfdoc/include/cpvt_word.h" |
14 #include "core/fpdfdoc/include/ipvt_fontmap.h" | 14 #include "core/fpdfdoc/include/ipvt_fontmap.h" |
15 #include "core/fxge/include/fx_ge.h" | 15 #include "core/fxge/include/fx_ge.h" |
16 #include "fpdfsdk/cfx_systemhandler.h" | 16 #include "fpdfsdk/cfx_systemhandler.h" |
17 #include "fpdfsdk/fxedit/include/fx_edit.h" | 17 #include "fpdfsdk/fxedit/include/fx_edit.h" |
18 #include "fpdfsdk/fxedit/include/fxet_edit.h" | 18 #include "fpdfsdk/fxedit/include/fxet_edit.h" |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 CFX_FloatRect GetUnderLineRect(const CPVT_Word& word) { | |
23 return CFX_FloatRect(word.ptWord.x, word.ptWord.y + word.fDescent * 0.5f, | |
24 word.ptWord.x + word.fWidth, | |
25 word.ptWord.y + word.fDescent * 0.25f); | |
26 } | |
27 | |
28 CFX_FloatRect GetCrossoutRect(const CPVT_Word& word) { | |
29 return CFX_FloatRect(word.ptWord.x, | |
30 word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f + | |
31 word.fDescent * 0.25f, | |
32 word.ptWord.x + word.fWidth, | |
33 word.ptWord.y + (word.fAscent + word.fDescent) * 0.5f); | |
34 } | |
35 | |
36 void DrawTextString(CFX_RenderDevice* pDevice, | 22 void DrawTextString(CFX_RenderDevice* pDevice, |
37 const CFX_FloatPoint& pt, | 23 const CFX_FloatPoint& pt, |
38 CPDF_Font* pFont, | 24 CPDF_Font* pFont, |
39 FX_FLOAT fFontSize, | 25 FX_FLOAT fFontSize, |
40 CFX_Matrix* pUser2Device, | 26 CFX_Matrix* pUser2Device, |
41 const CFX_ByteString& str, | 27 const CFX_ByteString& str, |
42 FX_ARGB crTextFill, | 28 FX_ARGB crTextFill, |
43 FX_ARGB crTextStroke, | 29 FX_ARGB crTextStroke, |
44 int32_t nHorzScale) { | 30 int32_t nHorzScale) { |
45 FX_FLOAT x = pt.x, y = pt.y; | 31 FX_FLOAT x = pt.x, y = pt.y; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 crTextStroke, &gsd, &ro); | 73 crTextStroke, &gsd, &ro); |
88 } else { | 74 } else { |
89 CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, | 75 CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, |
90 pUser2Device, str, crTextFill, 0, | 76 pUser2Device, str, crTextFill, 0, |
91 nullptr, &ro); | 77 nullptr, &ro); |
92 } | 78 } |
93 } | 79 } |
94 } | 80 } |
95 } | 81 } |
96 | 82 |
97 void AddRectToPageObjects(CPDF_PageObjectHolder* pObjectHolder, | |
98 FX_COLORREF crFill, | |
99 const CFX_FloatRect& rcFill) { | |
100 std::unique_ptr<CPDF_PathObject> pPathObj(new CPDF_PathObject); | |
101 CFX_PathData* pPathData = pPathObj->m_Path.GetModify(); | |
102 pPathData->AppendRect(rcFill.left, rcFill.bottom, rcFill.right, rcFill.top); | |
103 | |
104 FX_FLOAT rgb[3]; | |
105 rgb[0] = FXARGB_R(crFill) / 255.0f; | |
106 rgb[1] = FXARGB_G(crFill) / 255.0f; | |
107 rgb[2] = FXARGB_B(crFill) / 255.0f; | |
108 pPathObj->m_ColorState.SetFillColor( | |
109 CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3); | |
110 | |
111 pPathObj->m_FillType = FXFILL_ALTERNATE; | |
112 pPathObj->m_bStroke = FALSE; | |
113 pObjectHolder->GetPageObjectList()->push_back(std::move(pPathObj)); | |
114 } | |
115 | |
116 CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjectHolder* pObjectHolder, | 83 CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjectHolder* pObjectHolder, |
117 FX_COLORREF crText, | 84 FX_COLORREF crText, |
118 CPDF_Font* pFont, | 85 CPDF_Font* pFont, |
119 FX_FLOAT fFontSize, | 86 FX_FLOAT fFontSize, |
120 FX_FLOAT fCharSpace, | 87 FX_FLOAT fCharSpace, |
121 int32_t nHorzScale, | 88 int32_t nHorzScale, |
122 const CFX_FloatPoint& point, | 89 const CFX_FloatPoint& point, |
123 const CFX_ByteString& text) { | 90 const CFX_ByteString& text) { |
124 std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject); | 91 std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject); |
125 CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify(); | 92 CPDF_TextStateData* pTextStateData = pTxtObj->m_TextState.GetModify(); |
(...skipping 19 matching lines...) Expand all Loading... |
145 pTxtObj->SetPosition(point.x, point.y); | 112 pTxtObj->SetPosition(point.x, point.y); |
146 pTxtObj->SetText(text); | 113 pTxtObj->SetText(text); |
147 | 114 |
148 CPDF_TextObject* pRet = pTxtObj.get(); | 115 CPDF_TextObject* pRet = pTxtObj.get(); |
149 pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj)); | 116 pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj)); |
150 return pRet; | 117 return pRet; |
151 } | 118 } |
152 | 119 |
153 } // namespace | 120 } // namespace |
154 | 121 |
155 void IFX_Edit::DrawUnderline(CFX_RenderDevice* pDevice, | |
156 CFX_Matrix* pUser2Device, | |
157 IFX_Edit* pEdit, | |
158 FX_COLORREF color, | |
159 const CFX_FloatRect& rcClip, | |
160 const CFX_FloatPoint& ptOffset, | |
161 const CPVT_WordRange* pRange) { | |
162 pDevice->SaveState(); | |
163 | |
164 if (!rcClip.IsEmpty()) { | |
165 CFX_FloatRect rcTemp = rcClip; | |
166 pUser2Device->TransformRect(rcTemp); | |
167 pDevice->SetClip_Rect(rcTemp.ToFxRect()); | |
168 } | |
169 | |
170 IFX_Edit_Iterator* pIterator = pEdit->GetIterator(); | |
171 if (pEdit->GetFontMap()) { | |
172 if (pRange) | |
173 pIterator->SetAt(pRange->BeginPos); | |
174 else | |
175 pIterator->SetAt(0); | |
176 | |
177 while (pIterator->NextWord()) { | |
178 CPVT_WordPlace place = pIterator->GetAt(); | |
179 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
180 break; | |
181 | |
182 CPVT_Word word; | |
183 if (pIterator->GetWord(word)) { | |
184 CFX_PathData pathUnderline; | |
185 CFX_FloatRect rcUnderline = GetUnderLineRect(word); | |
186 rcUnderline.left += ptOffset.x; | |
187 rcUnderline.right += ptOffset.x; | |
188 rcUnderline.top += ptOffset.y; | |
189 rcUnderline.bottom += ptOffset.y; | |
190 pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, | |
191 rcUnderline.right, rcUnderline.top); | |
192 | |
193 pDevice->DrawPath(&pathUnderline, pUser2Device, nullptr, color, 0, | |
194 FXFILL_WINDING); | |
195 } | |
196 } | |
197 } | |
198 | |
199 pDevice->RestoreState(false); | |
200 } | |
201 | |
202 void IFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, | 122 void IFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, |
203 CFX_Matrix* pUser2Device, | 123 CFX_Matrix* pUser2Device, |
204 IFX_Edit* pEdit, | 124 IFX_Edit* pEdit, |
205 FX_COLORREF crTextFill, | 125 FX_COLORREF crTextFill, |
206 FX_COLORREF crTextStroke, | 126 FX_COLORREF crTextStroke, |
207 const CFX_FloatRect& rcClip, | 127 const CFX_FloatRect& rcClip, |
208 const CFX_FloatPoint& ptOffset, | 128 const CFX_FloatPoint& ptOffset, |
209 const CPVT_WordRange* pRange, | 129 const CPVT_WordRange* pRange, |
210 CFX_SystemHandler* pSystemHandler, | 130 CFX_SystemHandler* pSystemHandler, |
211 void* pFFLData) { | 131 void* pFFLData) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 DrawTextString( | 236 DrawTextString( |
317 pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), | 237 pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), |
318 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, | 238 pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, |
319 sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale); | 239 sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale); |
320 } | 240 } |
321 } | 241 } |
322 | 242 |
323 pDevice->RestoreState(false); | 243 pDevice->RestoreState(false); |
324 } | 244 } |
325 | 245 |
326 void IFX_Edit::DrawRichEdit(CFX_RenderDevice* pDevice, | |
327 CFX_Matrix* pUser2Device, | |
328 IFX_Edit* pEdit, | |
329 const CFX_FloatRect& rcClip, | |
330 const CFX_FloatPoint& ptOffset, | |
331 const CPVT_WordRange* pRange) { | |
332 CPVT_WordRange wrSelect = pEdit->GetSelectWordRange(); | |
333 | |
334 FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0); | |
335 FX_COLORREF crOld = crCurText; | |
336 FX_BOOL bSelect = FALSE; | |
337 const FX_COLORREF crWhite = ArgbEncode(255, 255, 255, 255); | |
338 const FX_COLORREF crSelBK = ArgbEncode(255, 0, 51, 113); | |
339 | |
340 CFX_ByteTextBuf sTextBuf; | |
341 CPVT_WordProps wp; | |
342 CFX_FloatPoint ptBT(0.0f, 0.0f); | |
343 | |
344 pDevice->SaveState(); | |
345 | |
346 if (!rcClip.IsEmpty()) { | |
347 CFX_FloatRect rcTemp = rcClip; | |
348 pUser2Device->TransformRect(rcTemp); | |
349 pDevice->SetClip_Rect(rcTemp.ToFxRect()); | |
350 } | |
351 | |
352 IFX_Edit_Iterator* pIterator = pEdit->GetIterator(); | |
353 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) { | |
354 if (pRange) | |
355 pIterator->SetAt(pRange->BeginPos); | |
356 else | |
357 pIterator->SetAt(0); | |
358 | |
359 CPVT_WordPlace oldplace; | |
360 | |
361 while (pIterator->NextWord()) { | |
362 CPVT_WordPlace place = pIterator->GetAt(); | |
363 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
364 break; | |
365 | |
366 CPVT_Word word; | |
367 if (pIterator->GetWord(word)) { | |
368 word.WordProps.fFontSize = word.fFontSize; | |
369 | |
370 crCurText = ArgbEncode(255, word.WordProps.dwWordColor); | |
371 | |
372 if (wrSelect.IsExist()) { | |
373 bSelect = place.WordCmp(wrSelect.BeginPos) > 0 && | |
374 place.WordCmp(wrSelect.EndPos) <= 0; | |
375 if (bSelect) { | |
376 crCurText = crWhite; | |
377 } | |
378 } | |
379 | |
380 if (bSelect) { | |
381 CPVT_Line line; | |
382 pIterator->GetLine(line); | |
383 | |
384 CFX_PathData pathSelBK; | |
385 pathSelBK.AppendRect(word.ptWord.x + ptOffset.x, | |
386 line.ptLine.y + line.fLineDescent + ptOffset.y, | |
387 word.ptWord.x + word.fWidth + ptOffset.x, | |
388 line.ptLine.y + line.fLineAscent + ptOffset.y); | |
389 | |
390 pDevice->DrawPath(&pathSelBK, pUser2Device, nullptr, crSelBK, 0, | |
391 FXFILL_WINDING); | |
392 } | |
393 | |
394 if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || | |
395 word.WordProps.nHorzScale != 100 || | |
396 FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 || | |
397 crOld != crCurText) { | |
398 if (sTextBuf.GetLength() > 0) { | |
399 DrawTextString( | |
400 pDevice, | |
401 CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), | |
402 pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, pUser2Device, | |
403 sTextBuf.MakeString(), crOld, 0, wp.nHorzScale); | |
404 | |
405 sTextBuf.Clear(); | |
406 } | |
407 wp = word.WordProps; | |
408 ptBT = word.ptWord; | |
409 crOld = crCurText; | |
410 } | |
411 | |
412 sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, | |
413 word.Word, 0) | |
414 .AsStringC(); | |
415 | |
416 if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) { | |
417 CFX_PathData pathUnderline; | |
418 CFX_FloatRect rcUnderline = GetUnderLineRect(word); | |
419 pathUnderline.AppendRect(rcUnderline.left, rcUnderline.bottom, | |
420 rcUnderline.right, rcUnderline.top); | |
421 | |
422 pDevice->DrawPath(&pathUnderline, pUser2Device, nullptr, crCurText, 0, | |
423 FXFILL_WINDING); | |
424 } | |
425 | |
426 if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) { | |
427 CFX_PathData pathCrossout; | |
428 CFX_FloatRect rcCrossout = GetCrossoutRect(word); | |
429 pathCrossout.AppendRect(rcCrossout.left, rcCrossout.bottom, | |
430 rcCrossout.right, rcCrossout.top); | |
431 | |
432 pDevice->DrawPath(&pathCrossout, pUser2Device, nullptr, crCurText, 0, | |
433 FXFILL_WINDING); | |
434 } | |
435 | |
436 oldplace = place; | |
437 } | |
438 } | |
439 | |
440 if (sTextBuf.GetLength() > 0) { | |
441 DrawTextString( | |
442 pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), | |
443 pFontMap->GetPDFFont(wp.nFontIndex), wp.fFontSize, pUser2Device, | |
444 sTextBuf.MakeString(), crOld, 0, wp.nHorzScale); | |
445 } | |
446 } | |
447 | |
448 pDevice->RestoreState(false); | |
449 } | |
450 | |
451 void IFX_Edit::GeneratePageObjects( | 246 void IFX_Edit::GeneratePageObjects( |
452 CPDF_PageObjectHolder* pObjectHolder, | 247 CPDF_PageObjectHolder* pObjectHolder, |
453 IFX_Edit* pEdit, | 248 IFX_Edit* pEdit, |
454 const CFX_FloatPoint& ptOffset, | 249 const CFX_FloatPoint& ptOffset, |
455 const CPVT_WordRange* pRange, | 250 const CPVT_WordRange* pRange, |
456 FX_COLORREF crText, | 251 FX_COLORREF crText, |
457 CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) { | 252 CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) { |
458 FX_FLOAT fFontSize = pEdit->GetFontSize(); | 253 FX_FLOAT fFontSize = pEdit->GetFontSize(); |
459 | 254 |
460 int32_t nOldFontIndex = -1; | 255 int32_t nOldFontIndex = -1; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 } | 297 } |
503 | 298 |
504 if (sTextBuf.GetLength() > 0) { | 299 if (sTextBuf.GetLength() > 0) { |
505 ObjArray.Add(AddTextObjToPageObjects( | 300 ObjArray.Add(AddTextObjToPageObjects( |
506 pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, | 301 pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, |
507 0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), | 302 0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), |
508 sTextBuf.MakeString())); | 303 sTextBuf.MakeString())); |
509 } | 304 } |
510 } | 305 } |
511 } | 306 } |
512 | |
513 void IFX_Edit::GenerateRichPageObjects( | |
514 CPDF_PageObjectHolder* pObjectHolder, | |
515 IFX_Edit* pEdit, | |
516 const CFX_FloatPoint& ptOffset, | |
517 const CPVT_WordRange* pRange, | |
518 CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) { | |
519 FX_COLORREF crCurText = ArgbEncode(255, 0, 0, 0); | |
520 FX_COLORREF crOld = crCurText; | |
521 | |
522 CFX_ByteTextBuf sTextBuf; | |
523 CPVT_WordProps wp; | |
524 CFX_FloatPoint ptBT(0.0f, 0.0f); | |
525 | |
526 ObjArray.RemoveAll(); | |
527 | |
528 IFX_Edit_Iterator* pIterator = pEdit->GetIterator(); | |
529 if (IPVT_FontMap* pFontMap = pEdit->GetFontMap()) { | |
530 if (pRange) | |
531 pIterator->SetAt(pRange->BeginPos); | |
532 else | |
533 pIterator->SetAt(0); | |
534 | |
535 CPVT_WordPlace oldplace; | |
536 | |
537 while (pIterator->NextWord()) { | |
538 CPVT_WordPlace place = pIterator->GetAt(); | |
539 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
540 break; | |
541 | |
542 CPVT_Word word; | |
543 if (pIterator->GetWord(word)) { | |
544 word.WordProps.fFontSize = word.fFontSize; | |
545 | |
546 crCurText = ArgbEncode(255, word.WordProps.dwWordColor); | |
547 | |
548 if (place.LineCmp(oldplace) != 0 || word.WordProps.fCharSpace > 0.0f || | |
549 word.WordProps.nHorzScale != 100 || | |
550 FXSYS_memcmp(&word.WordProps, &wp, sizeof(CPVT_WordProps)) != 0 || | |
551 crOld != crCurText) { | |
552 if (sTextBuf.GetLength() > 0) { | |
553 ObjArray.Add(AddTextObjToPageObjects( | |
554 pObjectHolder, crOld, pFontMap->GetPDFFont(wp.nFontIndex), | |
555 wp.fFontSize, wp.fCharSpace, wp.nHorzScale, | |
556 CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), | |
557 sTextBuf.MakeString())); | |
558 | |
559 sTextBuf.Clear(); | |
560 } | |
561 | |
562 wp = word.WordProps; | |
563 ptBT = word.ptWord; | |
564 crOld = crCurText; | |
565 } | |
566 | |
567 sTextBuf << GetPDFWordString(pFontMap, word.WordProps.nFontIndex, | |
568 word.Word, 0) | |
569 .AsStringC(); | |
570 | |
571 if (word.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) { | |
572 CFX_FloatRect rcUnderline = GetUnderLineRect(word); | |
573 rcUnderline.left += ptOffset.x; | |
574 rcUnderline.right += ptOffset.x; | |
575 rcUnderline.top += ptOffset.y; | |
576 rcUnderline.bottom += ptOffset.y; | |
577 | |
578 AddRectToPageObjects(pObjectHolder, crCurText, rcUnderline); | |
579 } | |
580 | |
581 if (word.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) { | |
582 CFX_FloatRect rcCrossout = GetCrossoutRect(word); | |
583 rcCrossout.left += ptOffset.x; | |
584 rcCrossout.right += ptOffset.x; | |
585 rcCrossout.top += ptOffset.y; | |
586 rcCrossout.bottom += ptOffset.y; | |
587 | |
588 AddRectToPageObjects(pObjectHolder, crCurText, rcCrossout); | |
589 } | |
590 | |
591 oldplace = place; | |
592 } | |
593 } | |
594 | |
595 if (sTextBuf.GetLength() > 0) { | |
596 ObjArray.Add(AddTextObjToPageObjects( | |
597 pObjectHolder, crOld, pFontMap->GetPDFFont(wp.nFontIndex), | |
598 wp.fFontSize, wp.fCharSpace, wp.nHorzScale, | |
599 CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), | |
600 sTextBuf.MakeString())); | |
601 } | |
602 } | |
603 } | |
604 | |
605 void IFX_Edit::GenerateUnderlineObjects(CPDF_PageObjectHolder* pObjectHolder, | |
606 IFX_Edit* pEdit, | |
607 const CFX_FloatPoint& ptOffset, | |
608 const CPVT_WordRange* pRange, | |
609 FX_COLORREF color) { | |
610 IFX_Edit_Iterator* pIterator = pEdit->GetIterator(); | |
611 if (pEdit->GetFontMap()) { | |
612 if (pRange) | |
613 pIterator->SetAt(pRange->BeginPos); | |
614 else | |
615 pIterator->SetAt(0); | |
616 | |
617 CPVT_WordPlace oldplace; | |
618 | |
619 while (pIterator->NextWord()) { | |
620 CPVT_WordPlace place = pIterator->GetAt(); | |
621 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
622 break; | |
623 | |
624 CPVT_Word word; | |
625 if (pIterator->GetWord(word)) { | |
626 CFX_FloatRect rcUnderline = GetUnderLineRect(word); | |
627 rcUnderline.left += ptOffset.x; | |
628 rcUnderline.right += ptOffset.x; | |
629 rcUnderline.top += ptOffset.y; | |
630 rcUnderline.bottom += ptOffset.y; | |
631 AddRectToPageObjects(pObjectHolder, color, rcUnderline); | |
632 } | |
633 } | |
634 } | |
635 } | |
OLD | NEW |