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 |