| 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 "fpdfsdk/pdfwindow/PWL_Utils.h" | 7 #include "fpdfsdk/pdfwindow/PWL_Utils.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 return IFX_Edit::GetEditAppearanceStream(pEdit, ptOffset, pRange, bContinuous, | 423 return IFX_Edit::GetEditAppearanceStream(pEdit, ptOffset, pRange, bContinuous, |
| 424 SubWord); | 424 SubWord); |
| 425 } | 425 } |
| 426 | 426 |
| 427 CFX_ByteString CPWL_Utils::GetEditSelAppStream(IFX_Edit* pEdit, | 427 CFX_ByteString CPWL_Utils::GetEditSelAppStream(IFX_Edit* pEdit, |
| 428 const CFX_FloatPoint& ptOffset, | 428 const CFX_FloatPoint& ptOffset, |
| 429 const CPVT_WordRange* pRange) { | 429 const CPVT_WordRange* pRange) { |
| 430 return IFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange); | 430 return IFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange); |
| 431 } | 431 } |
| 432 | 432 |
| 433 static CFX_ByteString GetSquigglyAppearanceStream(FX_FLOAT fStartX, | |
| 434 FX_FLOAT fEndX, | |
| 435 FX_FLOAT fY, | |
| 436 FX_FLOAT fStep) { | |
| 437 CFX_ByteTextBuf sRet; | |
| 438 | |
| 439 sRet << "0 w\n" << fStartX << " " << fY << " m\n"; | |
| 440 | |
| 441 FX_FLOAT fx; | |
| 442 int32_t i; | |
| 443 | |
| 444 for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) { | |
| 445 sRet << fx << " " << fY + (i & 1) * fStep << " l\n"; | |
| 446 } | |
| 447 | |
| 448 sRet << "S\n"; | |
| 449 | |
| 450 return sRet.GetByteString(); | |
| 451 } | |
| 452 | |
| 453 static CFX_ByteString GetWordSpellCheckAppearanceStream( | |
| 454 IFX_Edit_Iterator* pIterator, | |
| 455 const CFX_FloatPoint& ptOffset, | |
| 456 const CPVT_WordRange& wrWord) { | |
| 457 CFX_ByteTextBuf sRet; | |
| 458 | |
| 459 FX_FLOAT fStartX = 0.0f; | |
| 460 FX_FLOAT fEndX = 0.0f; | |
| 461 FX_FLOAT fY = 0.0f; | |
| 462 FX_FLOAT fStep = 0.0f; | |
| 463 | |
| 464 FX_BOOL bBreak = FALSE; | |
| 465 | |
| 466 if (pIterator) { | |
| 467 pIterator->SetAt(wrWord.BeginPos); | |
| 468 | |
| 469 do { | |
| 470 CPVT_WordPlace place = pIterator->GetAt(); | |
| 471 | |
| 472 CPVT_Line line; | |
| 473 if (pIterator->GetLine(line)) { | |
| 474 fY = line.ptLine.y; | |
| 475 fStep = (line.fLineAscent - line.fLineDescent) / 16.0f; | |
| 476 } | |
| 477 | |
| 478 if (place.LineCmp(wrWord.BeginPos) == 0) { | |
| 479 pIterator->SetAt(wrWord.BeginPos); | |
| 480 CPVT_Word word; | |
| 481 if (pIterator->GetWord(word)) { | |
| 482 fStartX = word.ptWord.x; | |
| 483 } | |
| 484 } else { | |
| 485 fStartX = line.ptLine.x; | |
| 486 } | |
| 487 | |
| 488 if (place.LineCmp(wrWord.EndPos) == 0) { | |
| 489 pIterator->SetAt(wrWord.EndPos); | |
| 490 CPVT_Word word; | |
| 491 if (pIterator->GetWord(word)) { | |
| 492 fEndX = word.ptWord.x + word.fWidth; | |
| 493 } | |
| 494 | |
| 495 bBreak = TRUE; | |
| 496 } else { | |
| 497 fEndX = line.ptLine.x + line.fLineWidth; | |
| 498 } | |
| 499 | |
| 500 sRet << GetSquigglyAppearanceStream( | |
| 501 fStartX + ptOffset.x, fEndX + ptOffset.x, fY + ptOffset.y, fStep); | |
| 502 | |
| 503 if (bBreak) | |
| 504 break; | |
| 505 } while (pIterator->NextLine()); | |
| 506 } | |
| 507 | |
| 508 return sRet.GetByteString(); | |
| 509 } | |
| 510 | |
| 511 CFX_ByteString CPWL_Utils::GetSpellCheckAppStream( | |
| 512 IFX_Edit* pEdit, | |
| 513 IPWL_SpellCheck* pSpellCheck, | |
| 514 const CFX_FloatPoint& ptOffset, | |
| 515 const CPVT_WordRange* pRange) { | |
| 516 CFX_ByteTextBuf sRet; | |
| 517 | |
| 518 if (pRange && pRange->IsExist()) { | |
| 519 if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) { | |
| 520 pIterator->SetAt(pRange->BeginPos); | |
| 521 | |
| 522 FX_BOOL bLatinWord = FALSE; | |
| 523 CPVT_WordPlace wpWordStart; | |
| 524 CFX_ByteString sWord; | |
| 525 | |
| 526 CPVT_WordPlace oldplace; | |
| 527 while (pIterator->NextWord()) { | |
| 528 CPVT_WordPlace place = pIterator->GetAt(); | |
| 529 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
| 530 break; | |
| 531 | |
| 532 CPVT_Word word; | |
| 533 if (pIterator->GetWord(word)) { | |
| 534 if (FX_EDIT_ISLATINWORD(word.Word)) { | |
| 535 if (!bLatinWord) { | |
| 536 wpWordStart = place; | |
| 537 bLatinWord = TRUE; | |
| 538 } | |
| 539 | |
| 540 sWord += (char)word.Word; | |
| 541 oldplace = place; | |
| 542 } else { | |
| 543 if (bLatinWord) { | |
| 544 if (!pSpellCheck->CheckWord(sWord)) { | |
| 545 sRet << GetWordSpellCheckAppearanceStream( | |
| 546 pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace)); | |
| 547 pIterator->SetAt(place); | |
| 548 } | |
| 549 bLatinWord = FALSE; | |
| 550 } | |
| 551 | |
| 552 sWord.Empty(); | |
| 553 } | |
| 554 } else { | |
| 555 if (bLatinWord) { | |
| 556 if (!pSpellCheck->CheckWord(sWord)) | |
| 557 sRet << GetWordSpellCheckAppearanceStream( | |
| 558 pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace)); | |
| 559 bLatinWord = FALSE; | |
| 560 sWord.Empty(); | |
| 561 } | |
| 562 } | |
| 563 } | |
| 564 | |
| 565 if (bLatinWord) { | |
| 566 if (!pSpellCheck->CheckWord(sWord)) | |
| 567 sRet << GetWordSpellCheckAppearanceStream( | |
| 568 pIterator, ptOffset, CPVT_WordRange(wpWordStart, oldplace)); | |
| 569 | |
| 570 bLatinWord = FALSE; | |
| 571 sWord.Empty(); | |
| 572 } | |
| 573 } | |
| 574 } | |
| 575 | |
| 576 return sRet.GetByteString(); | |
| 577 } | |
| 578 | |
| 579 CFX_ByteString CPWL_Utils::GetTextAppStream(const CFX_FloatRect& rcBBox, | 433 CFX_ByteString CPWL_Utils::GetTextAppStream(const CFX_FloatRect& rcBBox, |
| 580 IPVT_FontMap* pFontMap, | 434 IPVT_FontMap* pFontMap, |
| 581 const CFX_WideString& sText, | 435 const CFX_WideString& sText, |
| 582 int32_t nAlignmentH, | 436 int32_t nAlignmentH, |
| 583 int32_t nAlignmentV, | 437 int32_t nAlignmentV, |
| 584 FX_FLOAT fFontSize, | 438 FX_FLOAT fFontSize, |
| 585 FX_BOOL bMultiLine, | 439 FX_BOOL bMultiLine, |
| 586 FX_BOOL bAutoReturn, | 440 FX_BOOL bAutoReturn, |
| 587 const CPWL_Color& crText) { | 441 const CPWL_Color& crText) { |
| 588 CFX_ByteTextBuf sRet; | 442 CFX_ByteTextBuf sRet; |
| (...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1601 path.AppendRect(fLeft + fWidth, fBottom + fWidth, fRight - fWidth, | 1455 path.AppendRect(fLeft + fWidth, fBottom + fWidth, fRight - fWidth, |
| 1602 fTop - fWidth); | 1456 fTop - fWidth); |
| 1603 pDevice->DrawPath(&path, pUser2Device, NULL, | 1457 pDevice->DrawPath(&path, pUser2Device, NULL, |
| 1604 PWLColorToFXColor(color, nTransparancy / 2), 0, | 1458 PWLColorToFXColor(color, nTransparancy / 2), 0, |
| 1605 FXFILL_ALTERNATE); | 1459 FXFILL_ALTERNATE); |
| 1606 } break; | 1460 } break; |
| 1607 } | 1461 } |
| 1608 } | 1462 } |
| 1609 } | 1463 } |
| 1610 | 1464 |
| 1611 static void AddSquigglyPath(CFX_PathData& PathData, | |
| 1612 FX_FLOAT fStartX, | |
| 1613 FX_FLOAT fEndX, | |
| 1614 FX_FLOAT fY, | |
| 1615 FX_FLOAT fStep) { | |
| 1616 PathData.AddPointCount(1); | |
| 1617 PathData.SetPoint(PathData.GetPointCount() - 1, fStartX, fY, FXPT_MOVETO); | |
| 1618 | |
| 1619 FX_FLOAT fx; | |
| 1620 int32_t i; | |
| 1621 | |
| 1622 for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) { | |
| 1623 PathData.AddPointCount(1); | |
| 1624 PathData.SetPoint(PathData.GetPointCount() - 1, fx, fY + (i & 1) * fStep, | |
| 1625 FXPT_LINETO); | |
| 1626 } | |
| 1627 } | |
| 1628 | |
| 1629 static void AddSpellCheckObj(CFX_PathData& PathData, | |
| 1630 IFX_Edit* pEdit, | |
| 1631 const CPVT_WordRange& wrWord) { | |
| 1632 FX_FLOAT fStartX = 0.0f; | |
| 1633 FX_FLOAT fEndX = 0.0f; | |
| 1634 FX_FLOAT fY = 0.0f; | |
| 1635 FX_FLOAT fStep = 0.0f; | |
| 1636 | |
| 1637 FX_BOOL bBreak = FALSE; | |
| 1638 | |
| 1639 if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) { | |
| 1640 pIterator->SetAt(wrWord.BeginPos); | |
| 1641 | |
| 1642 do { | |
| 1643 CPVT_WordPlace place = pIterator->GetAt(); | |
| 1644 | |
| 1645 CPVT_Line line; | |
| 1646 if (pIterator->GetLine(line)) { | |
| 1647 fY = line.ptLine.y; | |
| 1648 fStep = (line.fLineAscent - line.fLineDescent) / 16.0f; | |
| 1649 } | |
| 1650 | |
| 1651 if (place.LineCmp(wrWord.BeginPos) == 0) { | |
| 1652 pIterator->SetAt(wrWord.BeginPos); | |
| 1653 CPVT_Word word; | |
| 1654 if (pIterator->GetWord(word)) { | |
| 1655 fStartX = word.ptWord.x; | |
| 1656 } | |
| 1657 } else { | |
| 1658 fStartX = line.ptLine.x; | |
| 1659 } | |
| 1660 | |
| 1661 if (place.LineCmp(wrWord.EndPos) == 0) { | |
| 1662 pIterator->SetAt(wrWord.EndPos); | |
| 1663 CPVT_Word word; | |
| 1664 if (pIterator->GetWord(word)) { | |
| 1665 fEndX = word.ptWord.x + word.fWidth; | |
| 1666 } | |
| 1667 | |
| 1668 bBreak = TRUE; | |
| 1669 } else { | |
| 1670 fEndX = line.ptLine.x + line.fLineWidth; | |
| 1671 } | |
| 1672 | |
| 1673 AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep); | |
| 1674 | |
| 1675 if (bBreak) | |
| 1676 break; | |
| 1677 } while (pIterator->NextLine()); | |
| 1678 } | |
| 1679 } | |
| 1680 | |
| 1681 void CPWL_Utils::DrawEditSpellCheck(CFX_RenderDevice* pDevice, | |
| 1682 CFX_Matrix* pUser2Device, | |
| 1683 IFX_Edit* pEdit, | |
| 1684 const CFX_FloatRect& rcClip, | |
| 1685 const CFX_FloatPoint& ptOffset, | |
| 1686 const CPVT_WordRange* pRange, | |
| 1687 IPWL_SpellCheck* pSpellCheck) { | |
| 1688 const FX_COLORREF crSpell = ArgbEncode(255, 255, 0, 0); | |
| 1689 | |
| 1690 // for spellcheck | |
| 1691 FX_BOOL bLatinWord = FALSE; | |
| 1692 CPVT_WordPlace wpWordStart; | |
| 1693 CFX_ByteString sLatinWord; | |
| 1694 | |
| 1695 CFX_PathData pathSpell; | |
| 1696 | |
| 1697 pDevice->SaveState(); | |
| 1698 | |
| 1699 if (!rcClip.IsEmpty()) { | |
| 1700 CFX_FloatRect rcTemp = rcClip; | |
| 1701 pUser2Device->TransformRect(rcTemp); | |
| 1702 pDevice->SetClip_Rect(rcTemp.ToFxRect()); | |
| 1703 } | |
| 1704 | |
| 1705 if (IFX_Edit_Iterator* pIterator = pEdit->GetIterator()) { | |
| 1706 if (pEdit->GetFontMap()) { | |
| 1707 if (pRange) | |
| 1708 pIterator->SetAt(pRange->BeginPos); | |
| 1709 else | |
| 1710 pIterator->SetAt(0); | |
| 1711 | |
| 1712 CPVT_WordPlace oldplace; | |
| 1713 | |
| 1714 while (pIterator->NextWord()) { | |
| 1715 CPVT_WordPlace place = pIterator->GetAt(); | |
| 1716 if (pRange && place.WordCmp(pRange->EndPos) > 0) | |
| 1717 break; | |
| 1718 | |
| 1719 CPVT_Word word; | |
| 1720 if (pIterator->GetWord(word)) { | |
| 1721 if (FX_EDIT_ISLATINWORD(word.Word)) { | |
| 1722 if (!bLatinWord) { | |
| 1723 wpWordStart = place; | |
| 1724 bLatinWord = TRUE; | |
| 1725 } | |
| 1726 | |
| 1727 sLatinWord += (char)word.Word; | |
| 1728 } else { | |
| 1729 if (bLatinWord) { | |
| 1730 if (!sLatinWord.IsEmpty()) { | |
| 1731 if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) { | |
| 1732 AddSpellCheckObj(pathSpell, pEdit, | |
| 1733 CPVT_WordRange(wpWordStart, oldplace)); | |
| 1734 pIterator->SetAt(place); | |
| 1735 } | |
| 1736 } | |
| 1737 bLatinWord = FALSE; | |
| 1738 } | |
| 1739 | |
| 1740 sLatinWord.Empty(); | |
| 1741 } | |
| 1742 | |
| 1743 oldplace = place; | |
| 1744 } else { | |
| 1745 if (bLatinWord) { | |
| 1746 if (!sLatinWord.IsEmpty()) { | |
| 1747 if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) { | |
| 1748 AddSpellCheckObj(pathSpell, pEdit, | |
| 1749 CPVT_WordRange(wpWordStart, oldplace)); | |
| 1750 pIterator->SetAt(place); | |
| 1751 } | |
| 1752 } | |
| 1753 bLatinWord = FALSE; | |
| 1754 } | |
| 1755 | |
| 1756 sLatinWord.Empty(); | |
| 1757 } | |
| 1758 } | |
| 1759 | |
| 1760 if (!sLatinWord.IsEmpty()) { | |
| 1761 if (pSpellCheck && !pSpellCheck->CheckWord(sLatinWord)) { | |
| 1762 AddSpellCheckObj(pathSpell, pEdit, | |
| 1763 CPVT_WordRange(wpWordStart, oldplace)); | |
| 1764 } | |
| 1765 } | |
| 1766 } | |
| 1767 } | |
| 1768 | |
| 1769 CFX_GraphStateData gsd; | |
| 1770 gsd.m_LineWidth = 0; | |
| 1771 if (pathSpell.GetPointCount() > 0) | |
| 1772 pDevice->DrawPath(&pathSpell, pUser2Device, &gsd, 0, crSpell, | |
| 1773 FXFILL_ALTERNATE); | |
| 1774 | |
| 1775 pDevice->RestoreState(); | |
| 1776 } | |
| 1777 | |
| 1778 FX_BOOL CPWL_Utils::IsBlackOrWhite(const CPWL_Color& color) { | 1465 FX_BOOL CPWL_Utils::IsBlackOrWhite(const CPWL_Color& color) { |
| 1779 switch (color.nColorType) { | 1466 switch (color.nColorType) { |
| 1780 case COLORTYPE_TRANSPARENT: | 1467 case COLORTYPE_TRANSPARENT: |
| 1781 return FALSE; | 1468 return FALSE; |
| 1782 case COLORTYPE_GRAY: | 1469 case COLORTYPE_GRAY: |
| 1783 return color.fColor1 < 0.5f; | 1470 return color.fColor1 < 0.5f; |
| 1784 case COLORTYPE_RGB: | 1471 case COLORTYPE_RGB: |
| 1785 return color.fColor1 + color.fColor2 + color.fColor3 < 1.5f; | 1472 return color.fColor1 + color.fColor2 + color.fColor3 < 1.5f; |
| 1786 case COLORTYPE_CMYK: | 1473 case COLORTYPE_CMYK: |
| 1787 return color.fColor1 + color.fColor2 + color.fColor3 + color.fColor4 > | 1474 return color.fColor1 + color.fColor2 + color.fColor3 + color.fColor4 > |
| (...skipping 1887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3675 break; | 3362 break; |
| 3676 case COLORTYPE_RGB: | 3363 case COLORTYPE_RGB: |
| 3677 CPWL_Utils::ConvertCMYK2RGB(fColor1, fColor2, fColor3, fColor4, | 3364 CPWL_Utils::ConvertCMYK2RGB(fColor1, fColor2, fColor3, fColor4, |
| 3678 fColor1, fColor2, fColor3); | 3365 fColor1, fColor2, fColor3); |
| 3679 break; | 3366 break; |
| 3680 } | 3367 } |
| 3681 break; | 3368 break; |
| 3682 } | 3369 } |
| 3683 nColorType = other_nColorType; | 3370 nColorType = other_nColorType; |
| 3684 } | 3371 } |
| OLD | NEW |