| 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 "../../include/pdfwindow/PDFWindow.h" | 7 #include "../../include/pdfwindow/PDFWindow.h" |
| 8 #include "../../include/pdfwindow/PWL_Wnd.h" | 8 #include "../../include/pdfwindow/PWL_Wnd.h" |
| 9 #include "../../include/pdfwindow/PWL_Caret.h" | 9 #include "../../include/pdfwindow/PWL_Caret.h" |
| 10 #include "../../include/pdfwindow/PWL_Utils.h" | 10 #include "../../include/pdfwindow/PWL_Utils.h" |
| 11 | 11 |
| 12 #define PWL_CARET_FLASHINTERVAL»» 500 | 12 #define PWL_CARET_FLASHINTERVAL 500 |
| 13 | 13 |
| 14 ////////////////////////////////////////////////////////////////////// | 14 ////////////////////////////////////////////////////////////////////// |
| 15 // Construction/Destruction | 15 // Construction/Destruction |
| 16 ////////////////////////////////////////////////////////////////////// | 16 ////////////////////////////////////////////////////////////////////// |
| 17 | 17 |
| 18 CPWL_Caret::CPWL_Caret() : | 18 CPWL_Caret::CPWL_Caret() |
| 19 » m_bFlash(FALSE), | 19 : m_bFlash(FALSE), |
| 20 » m_ptHead(0,0), | 20 m_ptHead(0, 0), |
| 21 » m_ptFoot(0,0), | 21 m_ptFoot(0, 0), |
| 22 » m_fWidth(0.4f), | 22 m_fWidth(0.4f), |
| 23 » m_nDelay(0) | 23 m_nDelay(0) {} |
| 24 { | 24 |
| 25 CPWL_Caret::~CPWL_Caret() {} |
| 26 |
| 27 CFX_ByteString CPWL_Caret::GetClassName() const { |
| 28 return "CPWL_Caret"; |
| 25 } | 29 } |
| 26 | 30 |
| 27 CPWL_Caret::~CPWL_Caret() | 31 void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { |
| 28 { | 32 GetCaretApp(sAppStream, CPDF_Point(0.0f, 0.0f)); |
| 29 } | 33 } |
| 30 | 34 |
| 31 CFX_ByteString CPWL_Caret::GetClassName() const | 35 void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, |
| 32 { | 36 CPDF_Matrix* pUser2Device) { |
| 33 » return "CPWL_Caret"; | 37 if (IsVisible() && m_bFlash) { |
| 38 CPDF_Rect rcRect = GetCaretRect(); |
| 39 CPDF_Rect rcClip = GetClipRect(); |
| 40 |
| 41 CFX_PathData path; |
| 42 |
| 43 path.SetPointCount(2); |
| 44 |
| 45 FX_FLOAT fCaretX = rcRect.left + m_fWidth * 0.5f; |
| 46 FX_FLOAT fCaretTop = rcRect.top; |
| 47 FX_FLOAT fCaretBottom = rcRect.bottom; |
| 48 |
| 49 if (!rcClip.IsEmpty()) { |
| 50 rcRect.Intersect(rcClip); |
| 51 if (!rcRect.IsEmpty()) { |
| 52 fCaretTop = rcRect.top; |
| 53 fCaretBottom = rcRect.bottom; |
| 54 path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO); |
| 55 path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO); |
| 56 } else { |
| 57 return; |
| 58 } |
| 59 } else { |
| 60 path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO); |
| 61 path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO); |
| 62 } |
| 63 |
| 64 CFX_GraphStateData gsd; |
| 65 gsd.m_LineWidth = m_fWidth; |
| 66 |
| 67 pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255, 0, 0, 0), |
| 68 FXFILL_ALTERNATE); |
| 69 } |
| 34 } | 70 } |
| 35 | 71 |
| 36 void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream) | 72 void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf& sAppStream, |
| 37 { | 73 const CPDF_Point& ptOffset) { |
| 38 » GetCaretApp(sAppStream,CPDF_Point(0.0f,0.0f)); | 74 if (IsVisible() && m_bFlash) { |
| 75 CFX_ByteTextBuf sCaret; |
| 76 |
| 77 CPDF_Rect rcRect = GetCaretRect(); |
| 78 CPDF_Rect rcClip = GetClipRect(); |
| 79 |
| 80 rcRect = CPWL_Utils::OffsetRect(rcRect, ptOffset.x, ptOffset.y); |
| 81 rcClip = CPWL_Utils::OffsetRect(rcClip, ptOffset.x, ptOffset.y); |
| 82 |
| 83 sCaret << "q\n"; |
| 84 if (!rcClip.IsEmpty()) { |
| 85 sCaret << rcClip.left << " " << rcClip.bottom + 2.5f << " " |
| 86 << rcClip.right - rcClip.left << " " |
| 87 << rcClip.top - rcClip.bottom - 4.5f << " re W n\n"; |
| 88 } |
| 89 sCaret << m_fWidth << " w\n0 G\n"; |
| 90 sCaret << rcRect.left + m_fWidth / 2 << " " << rcRect.bottom << " m\n"; |
| 91 sCaret << rcRect.left + m_fWidth / 2 << " " << rcRect.top << " l S\nQ\n"; |
| 92 |
| 93 sAppStream << sCaret; |
| 94 } |
| 39 } | 95 } |
| 40 | 96 |
| 41 void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUse
r2Device) | 97 CFX_ByteString CPWL_Caret::GetCaretAppearanceStream( |
| 42 { | 98 const CPDF_Point& ptOffset) { |
| 43 » if (IsVisible() && m_bFlash) | 99 CFX_ByteTextBuf sCaret; |
| 44 » { | 100 GetCaretApp(sCaret, ptOffset); |
| 45 » » CPDF_Rect rcRect = GetCaretRect(); | 101 return sCaret.GetByteString(); |
| 46 » » CPDF_Rect rcClip = GetClipRect(); | |
| 47 | |
| 48 » » CFX_PathData path; | |
| 49 | |
| 50 » » path.SetPointCount(2); | |
| 51 | |
| 52 » » FX_FLOAT fCaretX = rcRect.left + m_fWidth * 0.5f; | |
| 53 » » FX_FLOAT fCaretTop = rcRect.top; | |
| 54 » » FX_FLOAT fCaretBottom = rcRect.bottom; | |
| 55 | |
| 56 » » if (!rcClip.IsEmpty()) | |
| 57 » » { | |
| 58 » » » rcRect.Intersect(rcClip); | |
| 59 » » » if (!rcRect.IsEmpty()) | |
| 60 » » » { | |
| 61 » » » » fCaretTop = rcRect.top; | |
| 62 » » » » fCaretBottom = rcRect.bottom; | |
| 63 » » » » path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOV
ETO); | |
| 64 » » » » path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO
); | |
| 65 » » » } | |
| 66 » » » else | |
| 67 » » » { | |
| 68 » » » » return; | |
| 69 » » » } | |
| 70 » » } | |
| 71 » » else | |
| 72 » » { | |
| 73 » » » path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO); | |
| 74 » » » path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO); | |
| 75 » » } | |
| 76 | |
| 77 » » CFX_GraphStateData gsd; | |
| 78 » » gsd.m_LineWidth = m_fWidth; | |
| 79 | |
| 80 » » pDevice->DrawPath(&path, pUser2Device, &gsd,0, ArgbEncode(255,0
,0,0), FXFILL_ALTERNATE); | |
| 81 » } | |
| 82 } | 102 } |
| 83 | 103 |
| 84 void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf & sAppStream,const CPDF_Point & ptO
ffset) | 104 void CPWL_Caret::TimerProc() { |
| 85 { | 105 if (m_nDelay > 0) { |
| 86 » if (IsVisible() && m_bFlash) | 106 m_nDelay--; |
| 87 » { | 107 } else { |
| 88 » » CFX_ByteTextBuf sCaret; | 108 m_bFlash = !m_bFlash; |
| 89 | 109 InvalidateRect(); |
| 90 » » CPDF_Rect rcRect = GetCaretRect(); | 110 } |
| 91 » » CPDF_Rect rcClip = GetClipRect(); | |
| 92 | |
| 93 » » rcRect = CPWL_Utils::OffsetRect(rcRect,ptOffset.x,ptOffset.y); | |
| 94 » » rcClip = CPWL_Utils::OffsetRect(rcClip,ptOffset.x,ptOffset.y); | |
| 95 | |
| 96 » » sCaret << "q\n"; | |
| 97 » » if (!rcClip.IsEmpty()) | |
| 98 » » { | |
| 99 » » » sCaret << rcClip.left << " " << rcClip.bottom + 2.5f <<
" " | |
| 100 » » » » << rcClip.right - rcClip.left << " " << rcClip.t
op - rcClip.bottom - 4.5f << " re W n\n"; | |
| 101 » » } | |
| 102 » » sCaret << m_fWidth << " w\n0 G\n"; | |
| 103 » » sCaret << rcRect.left + m_fWidth/2 << " " << rcRect.bottom << "
m\n"; | |
| 104 » » sCaret << rcRect.left + m_fWidth/2 << " " << rcRect.top << " l S
\nQ\n"; | |
| 105 | |
| 106 » » sAppStream << sCaret; | |
| 107 » } | |
| 108 } | 111 } |
| 109 | 112 |
| 110 CFX_ByteString CPWL_Caret::GetCaretAppearanceStream(const CPDF_Point & ptOffset) | 113 CPDF_Rect CPWL_Caret::GetCaretRect() const { |
| 111 { | 114 return CPDF_Rect(m_ptFoot.x, m_ptFoot.y, m_ptHead.x + m_fWidth, m_ptHead.y); |
| 112 » CFX_ByteTextBuf sCaret; | |
| 113 » GetCaretApp(sCaret,ptOffset); | |
| 114 » return sCaret.GetByteString(); | |
| 115 } | 115 } |
| 116 | 116 |
| 117 void CPWL_Caret::TimerProc() | 117 void CPWL_Caret::SetCaret(FX_BOOL bVisible, |
| 118 { | 118 const CPDF_Point& ptHead, |
| 119 » if (m_nDelay > 0) | 119 const CPDF_Point& ptFoot) { |
| 120 » { | 120 if (bVisible) { |
| 121 » » m_nDelay--; | 121 if (IsVisible()) { |
| 122 » } | 122 if (m_ptHead.x != ptHead.x || m_ptHead.y != ptHead.y || |
| 123 » else | 123 m_ptFoot.x != ptFoot.x || m_ptFoot.y != ptFoot.y) { |
| 124 » { | 124 m_ptHead = ptHead; |
| 125 » » m_bFlash = !m_bFlash; | 125 m_ptFoot = ptFoot; |
| 126 » » InvalidateRect(); | 126 |
| 127 » } | 127 m_bFlash = TRUE; |
| 128 // Move(GetCaretRect(),FALSE,TRUE); |
| 129 Move(m_rcInvalid, FALSE, TRUE); |
| 130 } |
| 131 } else { |
| 132 m_ptHead = ptHead; |
| 133 m_ptFoot = ptFoot; |
| 134 |
| 135 EndTimer(); |
| 136 BeginTimer(PWL_CARET_FLASHINTERVAL); |
| 137 |
| 138 CPWL_Wnd::SetVisible(TRUE); |
| 139 m_bFlash = TRUE; |
| 140 |
| 141 // Move(GetCaretRect(),FALSE,TRUE); |
| 142 Move(m_rcInvalid, FALSE, TRUE); |
| 143 } |
| 144 } else { |
| 145 m_ptHead = CPDF_Point(0, 0); |
| 146 m_ptFoot = CPDF_Point(0, 0); |
| 147 |
| 148 m_bFlash = FALSE; |
| 149 if (IsVisible()) { |
| 150 EndTimer(); |
| 151 CPWL_Wnd::SetVisible(FALSE); |
| 152 } |
| 153 } |
| 128 } | 154 } |
| 129 | 155 |
| 130 CPDF_Rect CPWL_Caret::GetCaretRect() const | 156 void CPWL_Caret::InvalidateRect(CPDF_Rect* pRect) { |
| 131 { | 157 if (pRect) { |
| 132 » return CPDF_Rect(m_ptFoot.x, | 158 CPDF_Rect rcRefresh = CPWL_Utils::InflateRect(*pRect, 0.5f); |
| 133 » » » m_ptFoot.y, | 159 rcRefresh.top += 1; |
| 134 » » » m_ptHead.x + m_fWidth, | 160 rcRefresh.bottom -= 1; |
| 135 » » » m_ptHead.y); | 161 |
| 162 CPWL_Wnd::InvalidateRect(&rcRefresh); |
| 163 } else |
| 164 CPWL_Wnd::InvalidateRect(pRect); |
| 136 } | 165 } |
| 137 | |
| 138 void CPWL_Caret::SetCaret(FX_BOOL bVisible, const CPDF_Point & ptHead, const CPD
F_Point & ptFoot) | |
| 139 { | |
| 140 if (bVisible) | |
| 141 { | |
| 142 if (IsVisible()) | |
| 143 { | |
| 144 if (m_ptHead.x != ptHead.x || m_ptHead.y != ptHead.y || | |
| 145 m_ptFoot.x != ptFoot.x || m_ptFoot.y !=
ptFoot.y) | |
| 146 { | |
| 147 m_ptHead = ptHead; | |
| 148 m_ptFoot = ptFoot; | |
| 149 | |
| 150 m_bFlash = TRUE; | |
| 151 //Move(GetCaretRect(),FALSE,TRUE); | |
| 152 Move(m_rcInvalid, FALSE, TRUE); | |
| 153 } | |
| 154 } | |
| 155 else | |
| 156 { | |
| 157 m_ptHead = ptHead; | |
| 158 m_ptFoot = ptFoot; | |
| 159 | |
| 160 EndTimer(); | |
| 161 BeginTimer(PWL_CARET_FLASHINTERVAL); | |
| 162 | |
| 163 CPWL_Wnd::SetVisible(TRUE); | |
| 164 m_bFlash = TRUE; | |
| 165 | |
| 166 //Move(GetCaretRect(),FALSE,TRUE); | |
| 167 Move(m_rcInvalid, FALSE, TRUE); | |
| 168 } | |
| 169 } | |
| 170 else | |
| 171 { | |
| 172 m_ptHead = CPDF_Point(0, 0); | |
| 173 m_ptFoot = CPDF_Point(0, 0); | |
| 174 | |
| 175 m_bFlash = FALSE; | |
| 176 if (IsVisible()) | |
| 177 { | |
| 178 EndTimer(); | |
| 179 CPWL_Wnd::SetVisible(FALSE); | |
| 180 } | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 void CPWL_Caret::InvalidateRect(CPDF_Rect * pRect) | |
| 185 { | |
| 186 if (pRect) | |
| 187 { | |
| 188 CPDF_Rect rcRefresh = CPWL_Utils::InflateRect(*pRect,0.5f); | |
| 189 rcRefresh.top += 1; | |
| 190 rcRefresh.bottom -= 1; | |
| 191 | |
| 192 CPWL_Wnd::InvalidateRect(&rcRefresh); | |
| 193 } | |
| 194 else | |
| 195 CPWL_Wnd::InvalidateRect(pRect); | |
| 196 } | |
| 197 | |
| OLD | NEW |