From 77f9bff2c229df771a43448a9d5087e042235936 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 29 Aug 2017 11:34:12 -0700 Subject: Reduce rounding errors when Invalidating rects. Instead of using CFX_FloatRect::ToFxRect(), which always rounds down, use GetOuterRect() which correctly rounds up / down depending on the side of the rectangle. Change-Id: I7abd3a65e8c0467ed4303292f26a72737a5d553b Reviewed-on: https://pdfium-review.googlesource.com/12312 Commit-Queue: dsinclair Reviewed-by: dsinclair --- fpdfsdk/cfx_systemhandler.cpp | 12 ++++++------ fpdfsdk/cfx_systemhandler.h | 2 +- fpdfsdk/cpdfsdk_interform.cpp | 14 ++++++++------ fpdfsdk/cpdfsdk_pageview.cpp | 4 ++-- fpdfsdk/formfiller/cffl_formfiller.h | 3 ++- fpdfsdk/formfiller/cffl_textfield.cpp | 2 +- fpdfsdk/pwl/cpwl_wnd.cpp | 15 +++++---------- fpdfsdk/pwl/cpwl_wnd.h | 2 +- 8 files changed, 26 insertions(+), 28 deletions(-) diff --git a/fpdfsdk/cfx_systemhandler.cpp b/fpdfsdk/cfx_systemhandler.cpp index 6281b1be91..c8b1ef4b04 100644 --- a/fpdfsdk/cfx_systemhandler.cpp +++ b/fpdfsdk/cfx_systemhandler.cpp @@ -40,7 +40,8 @@ CFX_SystemHandler::CFX_SystemHandler(CPDFSDK_FormFillEnvironment* pFormFillEnv) CFX_SystemHandler::~CFX_SystemHandler() {} -void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect) { +void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget, + const CFX_FloatRect& rect) { CPDFSDK_PageView* pPageView = widget->GetPageView(); UnderlyingPageType* pPage = widget->GetUnderlyingPage(); if (!pPage || !pPageView) @@ -51,14 +52,13 @@ void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect) { CFX_Matrix device2page = page2device.GetInverse(); - CFX_PointF left_top = device2page.Transform( - CFX_PointF(static_cast(rect.left), static_cast(rect.top))); - CFX_PointF right_bottom = device2page.Transform(CFX_PointF( - static_cast(rect.right), static_cast(rect.bottom))); + CFX_PointF left_top = device2page.Transform(CFX_PointF(rect.left, rect.top)); + CFX_PointF right_bottom = + device2page.Transform(CFX_PointF(rect.right, rect.bottom)); CFX_FloatRect rcPDF(left_top.x, right_bottom.y, right_bottom.x, left_top.y); rcPDF.Normalize(); - m_pFormFillEnv->Invalidate(pPage, rcPDF.ToFxRect()); + m_pFormFillEnv->Invalidate(pPage, rcPDF.GetOuterRect()); } void CFX_SystemHandler::OutputSelectedRect(CFFL_FormFiller* pFormFiller, diff --git a/fpdfsdk/cfx_systemhandler.h b/fpdfsdk/cfx_systemhandler.h index 7402ac3c4f..c5da75579b 100644 --- a/fpdfsdk/cfx_systemhandler.h +++ b/fpdfsdk/cfx_systemhandler.h @@ -53,7 +53,7 @@ class CFX_SystemHandler { explicit CFX_SystemHandler(CPDFSDK_FormFillEnvironment* pFormFillEnv); ~CFX_SystemHandler(); - void InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect); + void InvalidateRect(CPDFSDK_Widget* widget, const CFX_FloatRect& rect); void OutputSelectedRect(CFFL_FormFiller* pFormFiller, CFX_FloatRect& rect); bool IsSelectionImplemented() const; void SetCursor(int32_t nCursorType); diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp index 27db1053c6..b60529df5d 100644 --- a/fpdfsdk/cpdfsdk_interform.cpp +++ b/fpdfsdk/cpdfsdk_interform.cpp @@ -327,12 +327,14 @@ void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) { CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); ASSERT(pFormCtrl); - if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) { - UnderlyingPageType* pPage = pWidget->GetUnderlyingPage(); - m_pFormFillEnv->Invalidate( - pPage, formfiller->GetViewBBox( - m_pFormFillEnv->GetPageView(pPage, false), pWidget)); - } + CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl); + if (!pWidget) + continue; + + UnderlyingPageType* pPage = pWidget->GetUnderlyingPage(); + FX_RECT rect = formfiller->GetViewBBox( + m_pFormFillEnv->GetPageView(pPage, false), pWidget); + m_pFormFillEnv->Invalidate(pPage, rect); } } diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp index c69f0990b1..358f72705d 100644 --- a/fpdfsdk/cpdfsdk_pageview.cpp +++ b/fpdfsdk/cpdfsdk_pageview.cpp @@ -459,12 +459,12 @@ void CPDFSDK_PageView::LoadFXAnnots() { void CPDFSDK_PageView::UpdateRects(const std::vector& rects) { for (const auto& rc : rects) - m_pFormFillEnv->Invalidate(m_page, rc.ToFxRect()); + m_pFormFillEnv->Invalidate(m_page, rc.GetOuterRect()); } void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) { CFX_FloatRect rcWindow = pAnnot->GetRect(); - m_pFormFillEnv->Invalidate(m_page, rcWindow.ToFxRect()); + m_pFormFillEnv->Invalidate(m_page, rcWindow.GetOuterRect()); } int CPDFSDK_PageView::GetPageIndex() const { diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h index 2b276c242e..b5bf1c8197 100644 --- a/fpdfsdk/formfiller/cffl_formfiller.h +++ b/fpdfsdk/formfiller/cffl_formfiller.h @@ -140,7 +140,6 @@ class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler { CPDFSDK_PageView* GetCurPageView(bool renew); void SetChangeMark(); - virtual void InvalidateRect(const FX_RECT& rect); CPDFSDK_Annot* GetSDKAnnot() { return m_pWidget.Get(); } protected: @@ -154,6 +153,8 @@ class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler { // until the PWL_Edit is done with it. pdfium:566 void DestroyWindows(); + void InvalidateRect(const FX_RECT& rect); + CFX_UnownedPtr const m_pFormFillEnv; CFX_UnownedPtr m_pWidget; bool m_bValid; diff --git a/fpdfsdk/formfiller/cffl_textfield.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp index d26b4a5599..f6f768a049 100644 --- a/fpdfsdk/formfiller/cffl_textfield.cpp +++ b/fpdfsdk/formfiller/cffl_textfield.cpp @@ -101,7 +101,7 @@ bool CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot, ASSERT(pPageView); m_bValid = !m_bValid; m_pFormFillEnv->Invalidate(pAnnot->GetUnderlyingPage(), - pAnnot->GetRect().ToFxRect()); + pAnnot->GetRect().GetOuterRect()); if (m_bValid) { if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true)) diff --git a/fpdfsdk/pwl/cpwl_wnd.cpp b/fpdfsdk/pwl/cpwl_wnd.cpp index 0198c63d6a..53c692dada 100644 --- a/fpdfsdk/pwl/cpwl_wnd.cpp +++ b/fpdfsdk/pwl/cpwl_wnd.cpp @@ -18,7 +18,6 @@ namespace { constexpr float kDefaultFontSize = 9.0f; -constexpr int kInvalidationInflate = 2; } // namespace @@ -302,11 +301,9 @@ void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) { } } - FX_RECT rcWin = PWLtoWnd(rcRefresh); - rcWin.left -= kInvalidationInflate; - rcWin.top -= kInvalidationInflate; - rcWin.right += kInvalidationInflate; - rcWin.bottom += kInvalidationInflate; + CFX_FloatRect rcWin = PWLtoWnd(rcRefresh); + rcWin.Inflate(1, 1); + rcWin.Normalize(); if (CFX_SystemHandler* pSH = GetSystemHandler()) { if (CPDFSDK_Widget* widget = static_cast( @@ -737,11 +734,9 @@ CFX_Matrix CPWL_Wnd::GetWindowMatrix() const { return mt; } -FX_RECT CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const { +CFX_FloatRect CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const { CFX_Matrix mt = GetWindowMatrix(); - CFX_FloatRect rcTemp = mt.TransformRect(rect); - return FX_RECT((int32_t)(rcTemp.left + 0.5), (int32_t)(rcTemp.bottom + 0.5), - (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5)); + return mt.TransformRect(rect); } CFX_PointF CPWL_Wnd::ParentToChild(const CFX_PointF& point) const { diff --git a/fpdfsdk/pwl/cpwl_wnd.h b/fpdfsdk/pwl/cpwl_wnd.h index 3c6c2824e2..9c913f1c23 100644 --- a/fpdfsdk/pwl/cpwl_wnd.h +++ b/fpdfsdk/pwl/cpwl_wnd.h @@ -318,7 +318,7 @@ class CPWL_Wnd : public CPWL_TimerHandler, public CFX_Observable { void DrawChildAppearance(CFX_RenderDevice* pDevice, const CFX_Matrix& mtUser2Device); - FX_RECT PWLtoWnd(const CFX_FloatRect& rect) const; + CFX_FloatRect PWLtoWnd(const CFX_FloatRect& rect) const; void AddChild(CPWL_Wnd* pWnd); void RemoveChild(CPWL_Wnd* pWnd); -- cgit v1.2.3