| 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 |