blob: e050f3400effc03081538eea96356c2ddda83d12 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "../../include/pdfwindow/PDFWindow.h"
8#include "../../include/pdfwindow/PWL_Wnd.h"
9#include "../../include/pdfwindow/PWL_Caret.h"
10#include "../../include/pdfwindow/PWL_Utils.h"
11
12#define PWL_CARET_FLASHINTERVAL 500
13
14//////////////////////////////////////////////////////////////////////
15// Construction/Destruction
16//////////////////////////////////////////////////////////////////////
17
18CPWL_Caret::CPWL_Caret() :
19 m_bFlash(FALSE),
20 m_ptHead(0,0),
21 m_ptFoot(0,0),
22 m_fWidth(0.4f),
23 m_nDelay(0)
24{
25}
26
27CPWL_Caret::~CPWL_Caret()
28{
29}
30
31CFX_ByteString CPWL_Caret::GetClassName() const
32{
33 return "CPWL_Caret";
34}
35
36void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
37{
38 GetCaretApp(sAppStream,CPDF_Point(0.0f,0.0f));
39}
40
41void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
42{
43 if (IsVisible() && m_bFlash)
44 {
45 CPDF_Rect rcRect = GetCaretRect();
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_MOVETO);
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}
83
84void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf & sAppStream,const CPDF_Point & ptOffset)
85{
86 if (IsVisible() && m_bFlash)
87 {
88 CFX_ByteTextBuf sCaret;
89
90 CPDF_Rect rcRect = GetCaretRect();
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.top - 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}
109
110CFX_ByteString CPWL_Caret::GetCaretAppearanceStream(const CPDF_Point & ptOffset)
111{
112 CFX_ByteTextBuf sCaret;
113 GetCaretApp(sCaret,ptOffset);
114 return sCaret.GetByteString();
115}
116
117void CPWL_Caret::TimerProc()
118{
119 if (m_nDelay > 0)
120 {
121 m_nDelay--;
122 }
123 else
124 {
125 m_bFlash = !m_bFlash;
126 InvalidateRect();
127 }
128}
129
130CPDF_Rect CPWL_Caret::GetCaretRect() const
131{
132 return CPDF_Rect(m_ptFoot.x,
133 m_ptFoot.y,
Lei Zhang60f507b2015-06-13 00:41:00 -0700134 m_ptHead.x + m_fWidth,
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135 m_ptHead.y);
136}
137
138void CPWL_Caret::SetCaret(FX_BOOL bVisible, const CPDF_Point & ptHead, const CPDF_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 {
Lei Zhang60f507b2015-06-13 00:41:00 -0700147 m_ptHead = ptHead;
148 m_ptFoot = ptFoot;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700149
150 m_bFlash = TRUE;
151 //Move(GetCaretRect(),FALSE,TRUE);
152 Move(m_rcInvalid, FALSE, TRUE);
153 }
154 }
155 else
156 {
Lei Zhang60f507b2015-06-13 00:41:00 -0700157 m_ptHead = ptHead;
158 m_ptFoot = ptFoot;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700159
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 {
Lei Zhang60f507b2015-06-13 00:41:00 -0700172 m_ptHead = CPDF_Point(0, 0);
173 m_ptFoot = CPDF_Point(0, 0);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174
175 m_bFlash = FALSE;
176 if (IsVisible())
177 {
178 EndTimer();
179 CPWL_Wnd::SetVisible(FALSE);
180 }
181 }
182}
183
184void 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