blob: adb296d8e117d506669d5d6371f425e9937088b4 [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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Lei Zhangbde53d22015-11-12 22:21:30 -08007#include "fpdfsdk/include/pdfwindow/PDFWindow.h"
8#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
9#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
10#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070011
Nico Weber9d8ec5a2015-08-04 13:00:21 -070012#define PWL_CARET_FLASHINTERVAL 500
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
14//////////////////////////////////////////////////////////////////////
15// Construction/Destruction
16//////////////////////////////////////////////////////////////////////
17
Nico Weber9d8ec5a2015-08-04 13:00:21 -070018CPWL_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
25CPWL_Caret::~CPWL_Caret() {}
26
27CFX_ByteString CPWL_Caret::GetClassName() const {
28 return "CPWL_Caret";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029}
30
Nico Weber9d8ec5a2015-08-04 13:00:21 -070031void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
32 GetCaretApp(sAppStream, CPDF_Point(0.0f, 0.0f));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033}
34
Nico Weber9d8ec5a2015-08-04 13:00:21 -070035void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice,
36 CPDF_Matrix* pUser2Device) {
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 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070070}
71
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf& sAppStream,
73 const CPDF_Point& ptOffset) {
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 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095}
96
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097CFX_ByteString CPWL_Caret::GetCaretAppearanceStream(
98 const CPDF_Point& ptOffset) {
99 CFX_ByteTextBuf sCaret;
100 GetCaretApp(sCaret, ptOffset);
101 return sCaret.GetByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102}
103
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104void CPWL_Caret::TimerProc() {
105 if (m_nDelay > 0) {
106 m_nDelay--;
107 } else {
108 m_bFlash = !m_bFlash;
109 InvalidateRect();
110 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700111}
112
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113CPDF_Rect CPWL_Caret::GetCaretRect() const {
114 return CPDF_Rect(m_ptFoot.x, m_ptFoot.y, m_ptHead.x + m_fWidth, m_ptHead.y);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700115}
116
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117void CPWL_Caret::SetCaret(FX_BOOL bVisible,
118 const CPDF_Point& ptHead,
119 const CPDF_Point& ptFoot) {
120 if (bVisible) {
121 if (IsVisible()) {
122 if (m_ptHead.x != ptHead.x || m_ptHead.y != ptHead.y ||
123 m_ptFoot.x != ptFoot.x || m_ptFoot.y != ptFoot.y) {
124 m_ptHead = ptHead;
125 m_ptFoot = ptFoot;
126
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 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700154}
155
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156void CPWL_Caret::InvalidateRect(CPDF_Rect* pRect) {
157 if (pRect) {
158 CPDF_Rect rcRefresh = CPWL_Utils::InflateRect(*pRect, 0.5f);
159 rcRefresh.top += 1;
160 rcRefresh.bottom -= 1;
161
162 CPWL_Wnd::InvalidateRect(&rcRefresh);
163 } else
164 CPWL_Wnd::InvalidateRect(pRect);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700165}