• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
CPWL_Caret()18 CPWL_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 
~CPWL_Caret()27 CPWL_Caret::~CPWL_Caret()
28 {
29 }
30 
GetClassName() const31 CFX_ByteString CPWL_Caret::GetClassName() const
32 {
33 	return "CPWL_Caret";
34 }
35 
GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)36 void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
37 {
38 	GetCaretApp(sAppStream,CPDF_Point(0.0f,0.0f));
39 }
40 
DrawThisAppearance(CFX_RenderDevice * pDevice,CPDF_Matrix * pUser2Device)41 void 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 
GetCaretApp(CFX_ByteTextBuf & sAppStream,const CPDF_Point & ptOffset)84 void 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 
GetCaretAppearanceStream(const CPDF_Point & ptOffset)110 CFX_ByteString CPWL_Caret::GetCaretAppearanceStream(const CPDF_Point & ptOffset)
111 {
112 	CFX_ByteTextBuf sCaret;
113 	GetCaretApp(sCaret,ptOffset);
114 	return sCaret.GetByteString();
115 }
116 
TimerProc()117 void 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 
GetCaretRect() const130 CPDF_Rect CPWL_Caret::GetCaretRect() const
131 {
132 	return CPDF_Rect(m_ptFoot.x,
133 			m_ptFoot.y,
134 			m_ptHead.x + this->m_fWidth,
135 			m_ptHead.y);
136 }
137 
SetCaret(FX_BOOL bVisible,const CPDF_Point & ptHead,const CPDF_Point & ptFoot)138 void 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 			{
147 				this->m_ptHead = ptHead;
148 				this->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 			this->m_ptHead = ptHead;
158 			this->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 		this->m_ptHead = CPDF_Point(0,0);
173 		this->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 
InvalidateRect(CPDF_Rect * pRect)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 
198