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/include/fxedit/fxet_edit.h" | 7 #include "fpdfsdk/include/fxedit/fxet_edit.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 CFX_Edit_Refresh::CFX_Edit_Refresh() {} | 148 CFX_Edit_Refresh::CFX_Edit_Refresh() {} |
149 | 149 |
150 CFX_Edit_Refresh::~CFX_Edit_Refresh() {} | 150 CFX_Edit_Refresh::~CFX_Edit_Refresh() {} |
151 | 151 |
152 void CFX_Edit_Refresh::BeginRefresh() { | 152 void CFX_Edit_Refresh::BeginRefresh() { |
153 m_RefreshRects.Empty(); | 153 m_RefreshRects.Empty(); |
154 m_OldLineRects = m_NewLineRects; | 154 m_OldLineRects = m_NewLineRects; |
155 } | 155 } |
156 | 156 |
157 void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange, | 157 void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange, |
158 const CPDF_Rect& rect) { | 158 const CFX_FloatRect& rect) { |
159 m_NewLineRects.Add(linerange, rect); | 159 m_NewLineRects.Add(linerange, rect); |
160 } | 160 } |
161 | 161 |
162 void CFX_Edit_Refresh::NoAnalyse() { | 162 void CFX_Edit_Refresh::NoAnalyse() { |
163 { | 163 { |
164 for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++) | 164 for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++) |
165 if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i)) | 165 if (CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i)) |
166 m_RefreshRects.Add(pOldRect->m_rcLine); | 166 m_RefreshRects.Add(pOldRect->m_rcLine); |
167 } | 167 } |
168 | 168 |
169 { | 169 { |
170 for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++) | 170 for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++) |
171 if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i)) | 171 if (CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i)) |
172 m_RefreshRects.Add(pNewRect->m_rcLine); | 172 m_RefreshRects.Add(pNewRect->m_rcLine); |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 void CFX_Edit_Refresh::Analyse(int32_t nAlignment) { | 176 void CFX_Edit_Refresh::Analyse(int32_t nAlignment) { |
177 FX_BOOL bLineTopChanged = FALSE; | 177 FX_BOOL bLineTopChanged = FALSE; |
178 CPDF_Rect rcResult; | 178 CFX_FloatRect rcResult; |
179 FX_FLOAT fWidthDiff; | 179 FX_FLOAT fWidthDiff; |
180 | 180 |
181 int32_t szMax = std::max(m_OldLineRects.GetSize(), m_NewLineRects.GetSize()); | 181 int32_t szMax = std::max(m_OldLineRects.GetSize(), m_NewLineRects.GetSize()); |
182 int32_t i = 0; | 182 int32_t i = 0; |
183 | 183 |
184 while (i < szMax) { | 184 while (i < szMax) { |
185 CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i); | 185 CFX_Edit_LineRect* pOldRect = m_OldLineRects.GetAt(i); |
186 CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i); | 186 CFX_Edit_LineRect* pNewRect = m_NewLineRects.GetAt(i); |
187 | 187 |
188 if (pOldRect) { | 188 if (pOldRect) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 } | 233 } |
234 } else { | 234 } else { |
235 if (pNewRect) { | 235 if (pNewRect) { |
236 m_RefreshRects.Add(pNewRect->m_rcLine); | 236 m_RefreshRects.Add(pNewRect->m_rcLine); |
237 } | 237 } |
238 } | 238 } |
239 i++; | 239 i++; |
240 } | 240 } |
241 } | 241 } |
242 | 242 |
243 void CFX_Edit_Refresh::AddRefresh(const CPDF_Rect& rect) { | 243 void CFX_Edit_Refresh::AddRefresh(const CFX_FloatRect& rect) { |
244 m_RefreshRects.Add(rect); | 244 m_RefreshRects.Add(rect); |
245 } | 245 } |
246 | 246 |
247 const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const { | 247 const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const { |
248 return &m_RefreshRects; | 248 return &m_RefreshRects; |
249 } | 249 } |
250 | 250 |
251 void CFX_Edit_Refresh::EndRefresh() { | 251 void CFX_Edit_Refresh::EndRefresh() { |
252 m_RefreshRects.Empty(); | 252 m_RefreshRects.Empty(); |
253 } | 253 } |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 return m_pVT; | 807 return m_pVT; |
808 } | 808 } |
809 | 809 |
810 IFX_Edit_FontMap* CFX_Edit::GetFontMap() { | 810 IFX_Edit_FontMap* CFX_Edit::GetFontMap() { |
811 if (m_pVTProvide) | 811 if (m_pVTProvide) |
812 return m_pVTProvide->GetFontMap(); | 812 return m_pVTProvide->GetFontMap(); |
813 | 813 |
814 return NULL; | 814 return NULL; |
815 } | 815 } |
816 | 816 |
817 void CFX_Edit::SetPlateRect(const CPDF_Rect& rect, FX_BOOL bPaint) { | 817 void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect, FX_BOOL bPaint) { |
818 m_pVT->SetPlateRect(rect); | 818 m_pVT->SetPlateRect(rect); |
819 m_ptScrollPos = CPDF_Point(rect.left, rect.top); | 819 m_ptScrollPos = CFX_FloatPoint(rect.left, rect.top); |
820 if (bPaint) | 820 if (bPaint) |
821 Paint(); | 821 Paint(); |
822 } | 822 } |
823 | 823 |
824 void CFX_Edit::SetAlignmentH(int32_t nFormat, FX_BOOL bPaint) { | 824 void CFX_Edit::SetAlignmentH(int32_t nFormat, FX_BOOL bPaint) { |
825 m_pVT->SetAlignment(nFormat); | 825 m_pVT->SetAlignment(nFormat); |
826 if (bPaint) | 826 if (bPaint) |
827 Paint(); | 827 Paint(); |
828 } | 828 } |
829 | 829 |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 } | 1624 } |
1625 | 1625 |
1626 FX_WORD CFX_Edit::GetPasswordChar() const { | 1626 FX_WORD CFX_Edit::GetPasswordChar() const { |
1627 return m_pVT->GetPasswordChar(); | 1627 return m_pVT->GetPasswordChar(); |
1628 } | 1628 } |
1629 | 1629 |
1630 int32_t CFX_Edit::GetCharArray() const { | 1630 int32_t CFX_Edit::GetCharArray() const { |
1631 return m_pVT->GetCharArray(); | 1631 return m_pVT->GetCharArray(); |
1632 } | 1632 } |
1633 | 1633 |
1634 CPDF_Rect CFX_Edit::GetPlateRect() const { | 1634 CFX_FloatRect CFX_Edit::GetPlateRect() const { |
1635 return m_pVT->GetPlateRect(); | 1635 return m_pVT->GetPlateRect(); |
1636 } | 1636 } |
1637 | 1637 |
1638 CPDF_Rect CFX_Edit::GetContentRect() const { | 1638 CFX_FloatRect CFX_Edit::GetContentRect() const { |
1639 return VTToEdit(m_pVT->GetContentRect()); | 1639 return VTToEdit(m_pVT->GetContentRect()); |
1640 } | 1640 } |
1641 | 1641 |
1642 int32_t CFX_Edit::GetHorzScale() const { | 1642 int32_t CFX_Edit::GetHorzScale() const { |
1643 return m_pVT->GetHorzScale(); | 1643 return m_pVT->GetHorzScale(); |
1644 } | 1644 } |
1645 | 1645 |
1646 FX_FLOAT CFX_Edit::GetCharSpace() const { | 1646 FX_FLOAT CFX_Edit::GetCharSpace() const { |
1647 return m_pVT->GetCharSpace(); | 1647 return m_pVT->GetCharSpace(); |
1648 } | 1648 } |
1649 | 1649 |
1650 CPVT_WordRange CFX_Edit::GetWholeWordRange() const { | 1650 CPVT_WordRange CFX_Edit::GetWholeWordRange() const { |
1651 if (m_pVT->IsValid()) | 1651 if (m_pVT->IsValid()) |
1652 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace()); | 1652 return CPVT_WordRange(m_pVT->GetBeginWordPlace(), m_pVT->GetEndWordPlace()); |
1653 | 1653 |
1654 return CPVT_WordRange(); | 1654 return CPVT_WordRange(); |
1655 } | 1655 } |
1656 | 1656 |
1657 CPVT_WordRange CFX_Edit::GetVisibleWordRange() const { | 1657 CPVT_WordRange CFX_Edit::GetVisibleWordRange() const { |
1658 if (m_bEnableOverflow) | 1658 if (m_bEnableOverflow) |
1659 return GetWholeWordRange(); | 1659 return GetWholeWordRange(); |
1660 | 1660 |
1661 if (m_pVT->IsValid()) { | 1661 if (m_pVT->IsValid()) { |
1662 CPDF_Rect rcPlate = m_pVT->GetPlateRect(); | 1662 CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); |
1663 | 1663 |
1664 CPVT_WordPlace place1 = | 1664 CPVT_WordPlace place1 = m_pVT->SearchWordPlace( |
1665 m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.left, rcPlate.top))); | 1665 EditToVT(CFX_FloatPoint(rcPlate.left, rcPlate.top))); |
1666 CPVT_WordPlace place2 = m_pVT->SearchWordPlace( | 1666 CPVT_WordPlace place2 = m_pVT->SearchWordPlace( |
1667 EditToVT(CPDF_Point(rcPlate.right, rcPlate.bottom))); | 1667 EditToVT(CFX_FloatPoint(rcPlate.right, rcPlate.bottom))); |
1668 | 1668 |
1669 return CPVT_WordRange(place1, place2); | 1669 return CPVT_WordRange(place1, place2); |
1670 } | 1670 } |
1671 | 1671 |
1672 return CPVT_WordRange(); | 1672 return CPVT_WordRange(); |
1673 } | 1673 } |
1674 | 1674 |
1675 CPVT_WordPlace CFX_Edit::SearchWordPlace(const CPDF_Point& point) const { | 1675 CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_FloatPoint& point) const { |
1676 if (m_pVT->IsValid()) { | 1676 if (m_pVT->IsValid()) { |
1677 return m_pVT->SearchWordPlace(EditToVT(point)); | 1677 return m_pVT->SearchWordPlace(EditToVT(point)); |
1678 } | 1678 } |
1679 | 1679 |
1680 return CPVT_WordPlace(); | 1680 return CPVT_WordPlace(); |
1681 } | 1681 } |
1682 | 1682 |
1683 void CFX_Edit::Paint() { | 1683 void CFX_Edit::Paint() { |
1684 if (m_pVT->IsValid()) { | 1684 if (m_pVT->IsValid()) { |
1685 RearrangeAll(); | 1685 RearrangeAll(); |
(...skipping 19 matching lines...) Expand all Loading... |
1705 m_pVT->UpdateWordPlace(m_wpCaret); | 1705 m_pVT->UpdateWordPlace(m_wpCaret); |
1706 m_pVT->RearrangePart(range); | 1706 m_pVT->RearrangePart(range); |
1707 m_pVT->UpdateWordPlace(m_wpCaret); | 1707 m_pVT->UpdateWordPlace(m_wpCaret); |
1708 SetScrollInfo(); | 1708 SetScrollInfo(); |
1709 SetContentChanged(); | 1709 SetContentChanged(); |
1710 } | 1710 } |
1711 } | 1711 } |
1712 | 1712 |
1713 void CFX_Edit::SetContentChanged() { | 1713 void CFX_Edit::SetContentChanged() { |
1714 if (m_bNotify && m_pNotify) { | 1714 if (m_bNotify && m_pNotify) { |
1715 CPDF_Rect rcContent = m_pVT->GetContentRect(); | 1715 CFX_FloatRect rcContent = m_pVT->GetContentRect(); |
1716 if (rcContent.Width() != m_rcOldContent.Width() || | 1716 if (rcContent.Width() != m_rcOldContent.Width() || |
1717 rcContent.Height() != m_rcOldContent.Height()) { | 1717 rcContent.Height() != m_rcOldContent.Height()) { |
1718 if (!m_bNotifyFlag) { | 1718 if (!m_bNotifyFlag) { |
1719 m_bNotifyFlag = TRUE; | 1719 m_bNotifyFlag = TRUE; |
1720 m_pNotify->IOnContentChange(rcContent); | 1720 m_pNotify->IOnContentChange(rcContent); |
1721 m_bNotifyFlag = FALSE; | 1721 m_bNotifyFlag = FALSE; |
1722 } | 1722 } |
1723 m_rcOldContent = rcContent; | 1723 m_rcOldContent = rcContent; |
1724 } | 1724 } |
1725 } | 1725 } |
(...skipping 18 matching lines...) Expand all Loading... |
1744 m_SelState.Default(); | 1744 m_SelState.Default(); |
1745 Refresh(RP_OPTIONAL, &wrTemp); | 1745 Refresh(RP_OPTIONAL, &wrTemp); |
1746 } | 1746 } |
1747 } | 1747 } |
1748 } | 1748 } |
1749 | 1749 |
1750 FX_BOOL CFX_Edit::IsSelected() const { | 1750 FX_BOOL CFX_Edit::IsSelected() const { |
1751 return m_SelState.IsExist(); | 1751 return m_SelState.IsExist(); |
1752 } | 1752 } |
1753 | 1753 |
1754 CPDF_Point CFX_Edit::VTToEdit(const CPDF_Point& point) const { | 1754 CFX_FloatPoint CFX_Edit::VTToEdit(const CFX_FloatPoint& point) const { |
1755 CPDF_Rect rcContent = m_pVT->GetContentRect(); | 1755 CFX_FloatRect rcContent = m_pVT->GetContentRect(); |
1756 CPDF_Rect rcPlate = m_pVT->GetPlateRect(); | 1756 CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); |
1757 | 1757 |
1758 FX_FLOAT fPadding = 0.0f; | 1758 FX_FLOAT fPadding = 0.0f; |
1759 | 1759 |
1760 switch (m_nAlignment) { | 1760 switch (m_nAlignment) { |
1761 case 0: | 1761 case 0: |
1762 fPadding = 0.0f; | 1762 fPadding = 0.0f; |
1763 break; | 1763 break; |
1764 case 1: | 1764 case 1: |
1765 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; | 1765 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; |
1766 break; | 1766 break; |
1767 case 2: | 1767 case 2: |
1768 fPadding = rcPlate.Height() - rcContent.Height(); | 1768 fPadding = rcPlate.Height() - rcContent.Height(); |
1769 break; | 1769 break; |
1770 } | 1770 } |
1771 | 1771 |
1772 return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left), | 1772 return CFX_FloatPoint(point.x - (m_ptScrollPos.x - rcPlate.left), |
1773 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top)); | 1773 point.y - (m_ptScrollPos.y + fPadding - rcPlate.top)); |
1774 } | 1774 } |
1775 | 1775 |
1776 CPDF_Point CFX_Edit::EditToVT(const CPDF_Point& point) const { | 1776 CFX_FloatPoint CFX_Edit::EditToVT(const CFX_FloatPoint& point) const { |
1777 CPDF_Rect rcContent = m_pVT->GetContentRect(); | 1777 CFX_FloatRect rcContent = m_pVT->GetContentRect(); |
1778 CPDF_Rect rcPlate = m_pVT->GetPlateRect(); | 1778 CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); |
1779 | 1779 |
1780 FX_FLOAT fPadding = 0.0f; | 1780 FX_FLOAT fPadding = 0.0f; |
1781 | 1781 |
1782 switch (m_nAlignment) { | 1782 switch (m_nAlignment) { |
1783 case 0: | 1783 case 0: |
1784 fPadding = 0.0f; | 1784 fPadding = 0.0f; |
1785 break; | 1785 break; |
1786 case 1: | 1786 case 1: |
1787 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; | 1787 fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f; |
1788 break; | 1788 break; |
1789 case 2: | 1789 case 2: |
1790 fPadding = rcPlate.Height() - rcContent.Height(); | 1790 fPadding = rcPlate.Height() - rcContent.Height(); |
1791 break; | 1791 break; |
1792 } | 1792 } |
1793 | 1793 |
1794 return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left), | 1794 return CFX_FloatPoint(point.x + (m_ptScrollPos.x - rcPlate.left), |
1795 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top)); | 1795 point.y + (m_ptScrollPos.y + fPadding - rcPlate.top)); |
1796 } | 1796 } |
1797 | 1797 |
1798 CPDF_Rect CFX_Edit::VTToEdit(const CPDF_Rect& rect) const { | 1798 CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const { |
1799 CPDF_Point ptLeftBottom = VTToEdit(CPDF_Point(rect.left, rect.bottom)); | 1799 CFX_FloatPoint ptLeftBottom = |
1800 CPDF_Point ptRightTop = VTToEdit(CPDF_Point(rect.right, rect.top)); | 1800 VTToEdit(CFX_FloatPoint(rect.left, rect.bottom)); |
| 1801 CFX_FloatPoint ptRightTop = VTToEdit(CFX_FloatPoint(rect.right, rect.top)); |
1801 | 1802 |
1802 return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y); | 1803 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, |
| 1804 ptRightTop.y); |
1803 } | 1805 } |
1804 | 1806 |
1805 CPDF_Rect CFX_Edit::EditToVT(const CPDF_Rect& rect) const { | 1807 CFX_FloatRect CFX_Edit::EditToVT(const CFX_FloatRect& rect) const { |
1806 CPDF_Point ptLeftBottom = EditToVT(CPDF_Point(rect.left, rect.bottom)); | 1808 CFX_FloatPoint ptLeftBottom = |
1807 CPDF_Point ptRightTop = EditToVT(CPDF_Point(rect.right, rect.top)); | 1809 EditToVT(CFX_FloatPoint(rect.left, rect.bottom)); |
| 1810 CFX_FloatPoint ptRightTop = EditToVT(CFX_FloatPoint(rect.right, rect.top)); |
1808 | 1811 |
1809 return CPDF_Rect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y); | 1812 return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, |
| 1813 ptRightTop.y); |
1810 } | 1814 } |
1811 | 1815 |
1812 void CFX_Edit::SetScrollInfo() { | 1816 void CFX_Edit::SetScrollInfo() { |
1813 if (m_bNotify && m_pNotify) { | 1817 if (m_bNotify && m_pNotify) { |
1814 CPDF_Rect rcPlate = m_pVT->GetPlateRect(); | 1818 CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); |
1815 CPDF_Rect rcContent = m_pVT->GetContentRect(); | 1819 CFX_FloatRect rcContent = m_pVT->GetContentRect(); |
1816 | 1820 |
1817 if (!m_bNotifyFlag) { | 1821 if (!m_bNotifyFlag) { |
1818 m_bNotifyFlag = TRUE; | 1822 m_bNotifyFlag = TRUE; |
1819 m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right, rcContent.left, | 1823 m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right, rcContent.left, |
1820 rcContent.right, rcPlate.Width() / 3, | 1824 rcContent.right, rcPlate.Width() / 3, |
1821 rcPlate.Width()); | 1825 rcPlate.Width()); |
1822 | 1826 |
1823 m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top, | 1827 m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top, |
1824 rcContent.bottom, rcContent.top, | 1828 rcContent.bottom, rcContent.top, |
1825 rcPlate.Height() / 3, rcPlate.Height()); | 1829 rcPlate.Height() / 3, rcPlate.Height()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 if (!m_bNotifyFlag) { | 1865 if (!m_bNotifyFlag) { |
1862 m_bNotifyFlag = TRUE; | 1866 m_bNotifyFlag = TRUE; |
1863 m_pNotify->IOnSetScrollPosY(fy); | 1867 m_pNotify->IOnSetScrollPosY(fy); |
1864 m_bNotifyFlag = FALSE; | 1868 m_bNotifyFlag = FALSE; |
1865 } | 1869 } |
1866 } | 1870 } |
1867 } | 1871 } |
1868 } | 1872 } |
1869 } | 1873 } |
1870 | 1874 |
1871 void CFX_Edit::SetScrollPos(const CPDF_Point& point) { | 1875 void CFX_Edit::SetScrollPos(const CFX_FloatPoint& point) { |
1872 SetScrollPosX(point.x); | 1876 SetScrollPosX(point.x); |
1873 SetScrollPosY(point.y); | 1877 SetScrollPosY(point.y); |
1874 SetScrollLimit(); | 1878 SetScrollLimit(); |
1875 SetCaretInfo(); | 1879 SetCaretInfo(); |
1876 } | 1880 } |
1877 | 1881 |
1878 CPDF_Point CFX_Edit::GetScrollPos() const { | 1882 CFX_FloatPoint CFX_Edit::GetScrollPos() const { |
1879 return m_ptScrollPos; | 1883 return m_ptScrollPos; |
1880 } | 1884 } |
1881 | 1885 |
1882 void CFX_Edit::SetScrollLimit() { | 1886 void CFX_Edit::SetScrollLimit() { |
1883 if (m_pVT->IsValid()) { | 1887 if (m_pVT->IsValid()) { |
1884 CPDF_Rect rcContent = m_pVT->GetContentRect(); | 1888 CFX_FloatRect rcContent = m_pVT->GetContentRect(); |
1885 CPDF_Rect rcPlate = m_pVT->GetPlateRect(); | 1889 CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); |
1886 | 1890 |
1887 if (rcPlate.Width() > rcContent.Width()) { | 1891 if (rcPlate.Width() > rcContent.Width()) { |
1888 SetScrollPosX(rcPlate.left); | 1892 SetScrollPosX(rcPlate.left); |
1889 } else { | 1893 } else { |
1890 if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) { | 1894 if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left)) { |
1891 SetScrollPosX(rcContent.left); | 1895 SetScrollPosX(rcContent.left); |
1892 } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x, | 1896 } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x, |
1893 rcContent.right - rcPlate.Width())) { | 1897 rcContent.right - rcPlate.Width())) { |
1894 SetScrollPosX(rcContent.right - rcPlate.Width()); | 1898 SetScrollPosX(rcContent.right - rcPlate.Width()); |
1895 } | 1899 } |
1896 } | 1900 } |
1897 | 1901 |
1898 if (rcPlate.Height() > rcContent.Height()) { | 1902 if (rcPlate.Height() > rcContent.Height()) { |
1899 SetScrollPosY(rcPlate.top); | 1903 SetScrollPosY(rcPlate.top); |
1900 } else { | 1904 } else { |
1901 if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y, | 1905 if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y, |
1902 rcContent.bottom + rcPlate.Height())) { | 1906 rcContent.bottom + rcPlate.Height())) { |
1903 SetScrollPosY(rcContent.bottom + rcPlate.Height()); | 1907 SetScrollPosY(rcContent.bottom + rcPlate.Height()); |
1904 } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top)) { | 1908 } else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top)) { |
1905 SetScrollPosY(rcContent.top); | 1909 SetScrollPosY(rcContent.top); |
1906 } | 1910 } |
1907 } | 1911 } |
1908 } | 1912 } |
1909 } | 1913 } |
1910 | 1914 |
1911 void CFX_Edit::ScrollToCaret() { | 1915 void CFX_Edit::ScrollToCaret() { |
1912 SetScrollLimit(); | 1916 SetScrollLimit(); |
1913 | 1917 |
1914 if (m_pVT->IsValid()) { | 1918 if (m_pVT->IsValid()) { |
1915 CPDF_Point ptHead(0, 0); | 1919 CFX_FloatPoint ptHead(0, 0); |
1916 CPDF_Point ptFoot(0, 0); | 1920 CFX_FloatPoint ptFoot(0, 0); |
1917 | 1921 |
1918 if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) { | 1922 if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) { |
1919 pIterator->SetAt(m_wpCaret); | 1923 pIterator->SetAt(m_wpCaret); |
1920 | 1924 |
1921 CPVT_Word word; | 1925 CPVT_Word word; |
1922 CPVT_Line line; | 1926 CPVT_Line line; |
1923 if (pIterator->GetWord(word)) { | 1927 if (pIterator->GetWord(word)) { |
1924 ptHead.x = word.ptWord.x + word.fWidth; | 1928 ptHead.x = word.ptWord.x + word.fWidth; |
1925 ptHead.y = word.ptWord.y + word.fAscent; | 1929 ptHead.y = word.ptWord.y + word.fAscent; |
1926 ptFoot.x = word.ptWord.x + word.fWidth; | 1930 ptFoot.x = word.ptWord.x + word.fWidth; |
1927 ptFoot.y = word.ptWord.y + word.fDescent; | 1931 ptFoot.y = word.ptWord.y + word.fDescent; |
1928 } else if (pIterator->GetLine(line)) { | 1932 } else if (pIterator->GetLine(line)) { |
1929 ptHead.x = line.ptLine.x; | 1933 ptHead.x = line.ptLine.x; |
1930 ptHead.y = line.ptLine.y + line.fLineAscent; | 1934 ptHead.y = line.ptLine.y + line.fLineAscent; |
1931 ptFoot.x = line.ptLine.x; | 1935 ptFoot.x = line.ptLine.x; |
1932 ptFoot.y = line.ptLine.y + line.fLineDescent; | 1936 ptFoot.y = line.ptLine.y + line.fLineDescent; |
1933 } | 1937 } |
1934 } | 1938 } |
1935 | 1939 |
1936 CPDF_Point ptHeadEdit = VTToEdit(ptHead); | 1940 CFX_FloatPoint ptHeadEdit = VTToEdit(ptHead); |
1937 CPDF_Point ptFootEdit = VTToEdit(ptFoot); | 1941 CFX_FloatPoint ptFootEdit = VTToEdit(ptFoot); |
1938 | 1942 |
1939 CPDF_Rect rcPlate = m_pVT->GetPlateRect(); | 1943 CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); |
1940 | 1944 |
1941 if (!FX_EDIT_IsFloatEqual(rcPlate.left, rcPlate.right)) { | 1945 if (!FX_EDIT_IsFloatEqual(rcPlate.left, rcPlate.right)) { |
1942 if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) || | 1946 if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) || |
1943 FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left)) { | 1947 FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left)) { |
1944 SetScrollPosX(ptHead.x); | 1948 SetScrollPosX(ptHead.x); |
1945 } else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right)) { | 1949 } else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right)) { |
1946 SetScrollPosX(ptHead.x - rcPlate.Width()); | 1950 SetScrollPosX(ptHead.x - rcPlate.Width()); |
1947 } | 1951 } |
1948 } | 1952 } |
1949 | 1953 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 m_pVT->UpdateWordPlace(wpEnd); | 2000 m_pVT->UpdateWordPlace(wpEnd); |
1997 pIterator->SetAt(wpBegin); | 2001 pIterator->SetAt(wpBegin); |
1998 | 2002 |
1999 CPVT_Line lineinfo; | 2003 CPVT_Line lineinfo; |
2000 do { | 2004 do { |
2001 if (!pIterator->GetLine(lineinfo)) | 2005 if (!pIterator->GetLine(lineinfo)) |
2002 break; | 2006 break; |
2003 if (lineinfo.lineplace.LineCmp(wpEnd) > 0) | 2007 if (lineinfo.lineplace.LineCmp(wpEnd) > 0) |
2004 break; | 2008 break; |
2005 | 2009 |
2006 CPDF_Rect rcLine(lineinfo.ptLine.x, | 2010 CFX_FloatRect rcLine(lineinfo.ptLine.x, |
2007 lineinfo.ptLine.y + lineinfo.fLineDescent, | 2011 lineinfo.ptLine.y + lineinfo.fLineDescent, |
2008 lineinfo.ptLine.x + lineinfo.fLineWidth, | 2012 lineinfo.ptLine.x + lineinfo.fLineWidth, |
2009 lineinfo.ptLine.y + lineinfo.fLineAscent); | 2013 lineinfo.ptLine.y + lineinfo.fLineAscent); |
2010 | 2014 |
2011 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd), | 2015 m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace, lineinfo.lineEnd), |
2012 VTToEdit(rcLine)); | 2016 VTToEdit(rcLine)); |
2013 } while (pIterator->NextLine()); | 2017 } while (pIterator->NextLine()); |
2014 } | 2018 } |
2015 } | 2019 } |
2016 } | 2020 } |
2017 | 2021 |
2018 void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange& wr) { | 2022 void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange& wr) { |
2019 if (m_pVT->IsValid()) { | 2023 if (m_pVT->IsValid()) { |
(...skipping 11 matching lines...) Expand all Loading... |
2031 while (pIterator->NextWord()) { | 2035 while (pIterator->NextWord()) { |
2032 place = pIterator->GetAt(); | 2036 place = pIterator->GetAt(); |
2033 if (place.WordCmp(wrTemp.EndPos) > 0) | 2037 if (place.WordCmp(wrTemp.EndPos) > 0) |
2034 break; | 2038 break; |
2035 | 2039 |
2036 pIterator->GetWord(wordinfo); | 2040 pIterator->GetWord(wordinfo); |
2037 pIterator->GetLine(lineinfo); | 2041 pIterator->GetLine(lineinfo); |
2038 | 2042 |
2039 if (place.LineCmp(wrTemp.BeginPos) == 0 || | 2043 if (place.LineCmp(wrTemp.BeginPos) == 0 || |
2040 place.LineCmp(wrTemp.EndPos) == 0) { | 2044 place.LineCmp(wrTemp.EndPos) == 0) { |
2041 CPDF_Rect rcWord(wordinfo.ptWord.x, | 2045 CFX_FloatRect rcWord(wordinfo.ptWord.x, |
2042 lineinfo.ptLine.y + lineinfo.fLineDescent, | 2046 lineinfo.ptLine.y + lineinfo.fLineDescent, |
2043 wordinfo.ptWord.x + wordinfo.fWidth, | 2047 wordinfo.ptWord.x + wordinfo.fWidth, |
2044 lineinfo.ptLine.y + lineinfo.fLineAscent); | 2048 lineinfo.ptLine.y + lineinfo.fLineAscent); |
2045 | 2049 |
2046 m_Refresh.AddRefresh(VTToEdit(rcWord)); | 2050 m_Refresh.AddRefresh(VTToEdit(rcWord)); |
2047 } else { | 2051 } else { |
2048 CPDF_Rect rcLine(lineinfo.ptLine.x, | 2052 CFX_FloatRect rcLine(lineinfo.ptLine.x, |
2049 lineinfo.ptLine.y + lineinfo.fLineDescent, | 2053 lineinfo.ptLine.y + lineinfo.fLineDescent, |
2050 lineinfo.ptLine.x + lineinfo.fLineWidth, | 2054 lineinfo.ptLine.x + lineinfo.fLineWidth, |
2051 lineinfo.ptLine.y + lineinfo.fLineAscent); | 2055 lineinfo.ptLine.y + lineinfo.fLineAscent); |
2052 | 2056 |
2053 m_Refresh.AddRefresh(VTToEdit(rcLine)); | 2057 m_Refresh.AddRefresh(VTToEdit(rcLine)); |
2054 | 2058 |
2055 pIterator->NextLine(); | 2059 pIterator->NextLine(); |
2056 } | 2060 } |
2057 } | 2061 } |
2058 } | 2062 } |
2059 } | 2063 } |
2060 } | 2064 } |
2061 | 2065 |
(...skipping 12 matching lines...) Expand all Loading... |
2074 while (pIterator->NextWord()) { | 2078 while (pIterator->NextWord()) { |
2075 place = pIterator->GetAt(); | 2079 place = pIterator->GetAt(); |
2076 if (place.WordCmp(wrTemp.EndPos) > 0) | 2080 if (place.WordCmp(wrTemp.EndPos) > 0) |
2077 break; | 2081 break; |
2078 | 2082 |
2079 pIterator->GetWord(wordinfo); | 2083 pIterator->GetWord(wordinfo); |
2080 pIterator->GetLine(lineinfo); | 2084 pIterator->GetLine(lineinfo); |
2081 | 2085 |
2082 if (place.LineCmp(wrTemp.BeginPos) == 0 || | 2086 if (place.LineCmp(wrTemp.BeginPos) == 0 || |
2083 place.LineCmp(wrTemp.EndPos) == 0) { | 2087 place.LineCmp(wrTemp.EndPos) == 0) { |
2084 CPDF_Rect rcWord(wordinfo.ptWord.x, | 2088 CFX_FloatRect rcWord(wordinfo.ptWord.x, |
2085 lineinfo.ptLine.y + lineinfo.fLineDescent, | 2089 lineinfo.ptLine.y + lineinfo.fLineDescent, |
2086 wordinfo.ptWord.x + wordinfo.fWidth, | 2090 wordinfo.ptWord.x + wordinfo.fWidth, |
2087 lineinfo.ptLine.y + lineinfo.fLineAscent); | 2091 lineinfo.ptLine.y + lineinfo.fLineAscent); |
2088 | 2092 |
2089 if (m_bNotify && m_pNotify) { | 2093 if (m_bNotify && m_pNotify) { |
2090 if (!m_bNotifyFlag) { | 2094 if (!m_bNotifyFlag) { |
2091 m_bNotifyFlag = TRUE; | 2095 m_bNotifyFlag = TRUE; |
2092 CPDF_Rect rcRefresh = VTToEdit(rcWord); | 2096 CFX_FloatRect rcRefresh = VTToEdit(rcWord); |
2093 m_pNotify->IOnInvalidateRect(&rcRefresh); | 2097 m_pNotify->IOnInvalidateRect(&rcRefresh); |
2094 m_bNotifyFlag = FALSE; | 2098 m_bNotifyFlag = FALSE; |
2095 } | 2099 } |
2096 } | 2100 } |
2097 } else { | 2101 } else { |
2098 CPDF_Rect rcLine(lineinfo.ptLine.x, | 2102 CFX_FloatRect rcLine(lineinfo.ptLine.x, |
2099 lineinfo.ptLine.y + lineinfo.fLineDescent, | 2103 lineinfo.ptLine.y + lineinfo.fLineDescent, |
2100 lineinfo.ptLine.x + lineinfo.fLineWidth, | 2104 lineinfo.ptLine.x + lineinfo.fLineWidth, |
2101 lineinfo.ptLine.y + lineinfo.fLineAscent); | 2105 lineinfo.ptLine.y + lineinfo.fLineAscent); |
2102 | 2106 |
2103 if (m_bNotify && m_pNotify) { | 2107 if (m_bNotify && m_pNotify) { |
2104 if (!m_bNotifyFlag) { | 2108 if (!m_bNotifyFlag) { |
2105 m_bNotifyFlag = TRUE; | 2109 m_bNotifyFlag = TRUE; |
2106 CPDF_Rect rcRefresh = VTToEdit(rcLine); | 2110 CFX_FloatRect rcRefresh = VTToEdit(rcLine); |
2107 m_pNotify->IOnInvalidateRect(&rcRefresh); | 2111 m_pNotify->IOnInvalidateRect(&rcRefresh); |
2108 m_bNotifyFlag = FALSE; | 2112 m_bNotifyFlag = FALSE; |
2109 } | 2113 } |
2110 } | 2114 } |
2111 | 2115 |
2112 pIterator->NextLine(); | 2116 pIterator->NextLine(); |
2113 } | 2117 } |
2114 } | 2118 } |
2115 } | 2119 } |
2116 } | 2120 } |
2117 | 2121 |
2118 void CFX_Edit::SetCaret(const CPVT_WordPlace& place) { | 2122 void CFX_Edit::SetCaret(const CPVT_WordPlace& place) { |
2119 m_wpOldCaret = m_wpCaret; | 2123 m_wpOldCaret = m_wpCaret; |
2120 m_wpCaret = place; | 2124 m_wpCaret = place; |
2121 } | 2125 } |
2122 | 2126 |
2123 void CFX_Edit::SetCaretInfo() { | 2127 void CFX_Edit::SetCaretInfo() { |
2124 if (m_bNotify && m_pNotify) { | 2128 if (m_bNotify && m_pNotify) { |
2125 if (!m_bNotifyFlag) { | 2129 if (!m_bNotifyFlag) { |
2126 CPDF_Point ptHead(0.0f, 0.0f), ptFoot(0.0f, 0.0f); | 2130 CFX_FloatPoint ptHead(0.0f, 0.0f), ptFoot(0.0f, 0.0f); |
2127 | 2131 |
2128 if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) { | 2132 if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator()) { |
2129 pIterator->SetAt(m_wpCaret); | 2133 pIterator->SetAt(m_wpCaret); |
2130 CPVT_Word word; | 2134 CPVT_Word word; |
2131 CPVT_Line line; | 2135 CPVT_Line line; |
2132 if (pIterator->GetWord(word)) { | 2136 if (pIterator->GetWord(word)) { |
2133 ptHead.x = word.ptWord.x + word.fWidth; | 2137 ptHead.x = word.ptWord.x + word.fWidth; |
2134 ptHead.y = word.ptWord.y + word.fAscent; | 2138 ptHead.y = word.ptWord.y + word.fAscent; |
2135 ptFoot.x = word.ptWord.x + word.fWidth; | 2139 ptFoot.x = word.ptWord.x + word.fWidth; |
2136 ptFoot.y = word.ptWord.y + word.fDescent; | 2140 ptFoot.y = word.ptWord.y + word.fDescent; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2188 SelectNone(); | 2192 SelectNone(); |
2189 SetCaret(m_pVT->WordIndexToWordPlace(nPos)); | 2193 SetCaret(m_pVT->WordIndexToWordPlace(nPos)); |
2190 m_SelState.Set(m_wpCaret, m_wpCaret); | 2194 m_SelState.Set(m_wpCaret, m_wpCaret); |
2191 | 2195 |
2192 ScrollToCaret(); | 2196 ScrollToCaret(); |
2193 SetCaretOrigin(); | 2197 SetCaretOrigin(); |
2194 SetCaretInfo(); | 2198 SetCaretInfo(); |
2195 } | 2199 } |
2196 } | 2200 } |
2197 | 2201 |
2198 void CFX_Edit::OnMouseDown(const CPDF_Point& point, | 2202 void CFX_Edit::OnMouseDown(const CFX_FloatPoint& point, |
2199 FX_BOOL bShift, | 2203 FX_BOOL bShift, |
2200 FX_BOOL bCtrl) { | 2204 FX_BOOL bCtrl) { |
2201 if (m_pVT->IsValid()) { | 2205 if (m_pVT->IsValid()) { |
2202 SelectNone(); | 2206 SelectNone(); |
2203 SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); | 2207 SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); |
2204 m_SelState.Set(m_wpCaret, m_wpCaret); | 2208 m_SelState.Set(m_wpCaret, m_wpCaret); |
2205 | 2209 |
2206 ScrollToCaret(); | 2210 ScrollToCaret(); |
2207 SetCaretOrigin(); | 2211 SetCaretOrigin(); |
2208 SetCaretInfo(); | 2212 SetCaretInfo(); |
2209 } | 2213 } |
2210 } | 2214 } |
2211 | 2215 |
2212 void CFX_Edit::OnMouseMove(const CPDF_Point& point, | 2216 void CFX_Edit::OnMouseMove(const CFX_FloatPoint& point, |
2213 FX_BOOL bShift, | 2217 FX_BOOL bShift, |
2214 FX_BOOL bCtrl) { | 2218 FX_BOOL bCtrl) { |
2215 if (m_pVT->IsValid()) { | 2219 if (m_pVT->IsValid()) { |
2216 SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); | 2220 SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); |
2217 | 2221 |
2218 if (m_wpCaret != m_wpOldCaret) { | 2222 if (m_wpCaret != m_wpOldCaret) { |
2219 m_SelState.SetEndPos(m_wpCaret); | 2223 m_SelState.SetEndPos(m_wpCaret); |
2220 | 2224 |
2221 ScrollToCaret(); | 2225 ScrollToCaret(); |
2222 CPVT_WordRange wr(m_wpOldCaret, m_wpCaret); | 2226 CPVT_WordRange wr(m_wpOldCaret, m_wpCaret); |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2846 int32_t nTotalWords = m_pVT->GetTotalWords(); | 2850 int32_t nTotalWords = m_pVT->GetTotalWords(); |
2847 int32_t nLimitChar = m_pVT->GetLimitChar(); | 2851 int32_t nLimitChar = m_pVT->GetLimitChar(); |
2848 int32_t nCharArray = m_pVT->GetCharArray(); | 2852 int32_t nCharArray = m_pVT->GetCharArray(); |
2849 | 2853 |
2850 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) || | 2854 return IsTextOverflow() || (nLimitChar > 0 && nTotalWords >= nLimitChar) || |
2851 (nCharArray > 0 && nTotalWords >= nCharArray); | 2855 (nCharArray > 0 && nTotalWords >= nCharArray); |
2852 } | 2856 } |
2853 | 2857 |
2854 FX_BOOL CFX_Edit::IsTextOverflow() const { | 2858 FX_BOOL CFX_Edit::IsTextOverflow() const { |
2855 if (!m_bEnableScroll && !m_bEnableOverflow) { | 2859 if (!m_bEnableScroll && !m_bEnableOverflow) { |
2856 CPDF_Rect rcPlate = m_pVT->GetPlateRect(); | 2860 CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); |
2857 CPDF_Rect rcContent = m_pVT->GetContentRect(); | 2861 CFX_FloatRect rcContent = m_pVT->GetContentRect(); |
2858 | 2862 |
2859 if (m_pVT->IsMultiLine() && GetTotalLines() > 1) { | 2863 if (m_pVT->IsMultiLine() && GetTotalLines() > 1) { |
2860 if (FX_EDIT_IsFloatBigger(rcContent.Height(), rcPlate.Height())) | 2864 if (FX_EDIT_IsFloatBigger(rcContent.Height(), rcPlate.Height())) |
2861 return TRUE; | 2865 return TRUE; |
2862 } | 2866 } |
2863 | 2867 |
2864 if (FX_EDIT_IsFloatBigger(rcContent.Width(), rcPlate.Width())) | 2868 if (FX_EDIT_IsFloatBigger(rcContent.Width(), rcPlate.Width())) |
2865 return TRUE; | 2869 return TRUE; |
2866 } | 2870 } |
2867 | 2871 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3021 if (m_bOprNotify && m_pOprNotify) | 3025 if (m_bOprNotify && m_pOprNotify) |
3022 m_pOprNotify->OnAddUndo(pEditUndoItem); | 3026 m_pOprNotify->OnAddUndo(pEditUndoItem); |
3023 } | 3027 } |
3024 } | 3028 } |
3025 | 3029 |
3026 void CFX_Edit::AddUndoItem(IFX_Edit_UndoItem* pUndoItem) { | 3030 void CFX_Edit::AddUndoItem(IFX_Edit_UndoItem* pUndoItem) { |
3027 m_Undo.AddItem(pUndoItem); | 3031 m_Undo.AddItem(pUndoItem); |
3028 if (m_bOprNotify && m_pOprNotify) | 3032 if (m_bOprNotify && m_pOprNotify) |
3029 m_pOprNotify->OnAddUndo(pUndoItem); | 3033 m_pOprNotify->OnAddUndo(pUndoItem); |
3030 } | 3034 } |
OLD | NEW |