1 /*
2  For general Scribus (>=1.3.2) copyright and licensing information please refer
3  to the COPYING file provided with the program. Following this notice may exist
4  a copyright and/or license notice that predates the release of Scribus 1.3.2
5  for which a new license (GPL+exception) is in place.
6  */
7 /***************************************************************************
8 scribusview.h  -  description
9 -------------------
10     begin                : Fre Apr  6 21:47:55 CEST 2001
11     copyright            : (C) 2001 by Franz Schmid
12     email                : Franz.Schmid@altmuehlnet.de
13 	***************************************************************************/
14 
15 /***************************************************************************
16 *                                                                         *
17 *   This program is free software; you can redistribute it and/or modify  *
18 *   it under the terms of the GNU General Public License as published by  *
19 *   the Free Software Foundation; either version 2 of the License, or     *
20 *   (at your option) any later version.                                   *
21 *                                                                         *
22 ***************************************************************************/
23 
24 #ifndef CANVAS_H
25 #define CANVAS_H
26 
27 #include <QApplication>
28 //#include <QDebug>
29 #include <QPolygon>
30 #include <QRect>
31 #include <QRectF>
32 #include <QWidget>
33 
34 #include "scribusapi.h"
35 
36 #include "commonstrings.h"
37 #include "fpoint.h"
38 #include "fpointarray.h"
39 #include "pageitempointer.h"
40 
41 
42 class ScPage;
43 class PageItem;
44 class ScLayer;
45 class ScPainter;
46 class ScribusDoc;
47 class ScribusView;
48 
49 struct CanvasViewMode
50 {
51 	QList<PageItemPointer> linkedFramesToShow;
52 	QPolygon redrawPolygon;
53 	bool m_MouseButtonPressed {false};
54 	bool operItemMoving {false};
55 	bool operItemResizing {false};
56 	bool operItemSelecting {false};
57 	bool operTextSelecting {false};
58 	bool previewMode {false};
59 	bool viewAsPreview {false};
60 	/** if true, selected objects will not be drawn by drawContents() */
61 	bool drawSelectedItemsWithControls {false};
62 	/** if true, drawContents() will draw framelinks even if View->Show Framelinks is false */
63 	bool drawFramelinksWithContents {false};
64 	// used for buffering:
65 	bool forceRedraw {false};
66 	double scale {1};
67 	int previewVisual {-1};
68 };
69 
70 QDataStream &operator<<(QDataStream & ds, const CanvasViewMode & vm);
71 QDataStream &operator>>(QDataStream & ds, CanvasViewMode & vm);
72 
73 
74 class SCRIBUS_API Canvas : public QWidget
75 {
76 	Q_OBJECT
77 
78 public:
79 	static const int moveWithFullOutlinesThreshold = 21;
80 	static const int moveWithBoxesOnlyThreshold = 41;
81 
82 	Canvas(ScribusDoc* doc, ScribusView* parent);
83 
84 	friend class ScribusView; // for now...
85 	friend class CanvasMode;
86 	friend class CanvasMode_CopyProperties;
87 	friend class CanvasMode_Edit;
88 	friend class CanvasMode_EditArc;
89 	friend class CanvasMode_EditGradient;
90 	friend class CanvasMode_EditMeshGradient;
91 	friend class CanvasMode_EditMeshPatch;
92 	friend class CanvasMode_EditWeldPoint;
93 	friend class CanvasMode_EditPolygon;
94 	friend class CanvasMode_EditSpiral;
95 	friend class CanvasMode_EditTable;
96 	friend class CanvasMode_EyeDropper;
97 	friend class CanvasMode_FrameLinks;
98 	friend class CanvasMode_ImageImport;
99 	friend class CanvasMode_Magnifier;
100 	friend class CanvasMode_NodeEdit;
101 	friend class CanvasMode_ObjImport;
102 	friend class CanvasMode_Panning;
103 	friend class CanvasMode_Normal;
104 	friend class CanvasMode_Rotate;
105 	friend class FreehandMode;
106 	friend class CalligraphicMode;
107 
108 	/* Don't rely on these codes!
109 	 * 2 8 3
110 	 * 7   6
111 	 * 4 5 1
112 	 * But always OUTSIDE < 0, INSIDE >= 0 and any specific handle > 0.
113 	 */
114 	enum FrameHandle {
115 		OUTSIDE = -1,
116 		INSIDE = 0,
117 		NORTHWEST = 2,
118 		NORTH = 8,
119 		NORTHEAST = 3,
120 		EAST = 6,
121 		SOUTHEAST = 1,
122 		SOUTH = 5,
123 		SOUTHWEST = 4,
124 		WEST = 7
125 	};
126 
127 	enum RenderMode {
128 		RENDER_NORMAL,                // update buffer, paint buffer: expensive for large regions
129 		RENDER_BUFFERED,              // just paint buffer: fast, but only controls may change (eg. resize mode)
130 		// in the following two modes, only the selected objects are updated. Might not be exact.
131 		RENDER_SELECTION_SEPARATE,    // paint buffer w/o selection, then paint selection (eg. img edit, nodeedit, rotate, beziercurve)
132 		RENDER_SELECTION_BUFFERED,    // paint buffer w/o selection, update selection buffer, then paint selection buffer (eg. move, text edit)
133 		RENDER_LEGACY
134 	};
135 
136 	void setRenderMode(RenderMode m);
137 
138 	void clearBuffers();              // very expensive
139 
140 	// deprecated:
resetRenderMode()141 	void resetRenderMode() { m_renderMode = RENDER_NORMAL; clearBuffers(); }
setRenderModeFillBuffer()142 	void setRenderModeFillBuffer() { m_renderMode = RENDER_BUFFERED; }
setRenderModeUseBuffer(bool use)143 	void setRenderModeUseBuffer(bool use) { m_renderMode = (use ? RENDER_BUFFERED : RENDER_NORMAL) ; }
144 
scale()145 	double scale() const { return m_viewMode.scale; }
146 	void setScale(double scale);
147 	QPoint canvasToLocal(const FPoint& p) const;
148 	QPoint canvasToGlobal(const FPoint& p) const;
149 	QPoint canvasToLocal(QPointF p) const;
150 	QPoint canvasToGlobal(QPointF p) const;
151 	QRect canvasToLocal(const QRectF& p) const;
152 	QRectF canvasToLocalF(const QRectF& p) const;
153 	QRect canvasToGlobal(const QRectF& p) const;
154 	FPoint localToCanvas(QPoint p) const;
155 //	FPoint localToCanvas(QPointF p) const;
156 	FPoint globalToCanvas(QPoint p) const;
157 //	FPoint globalToCanvas(QPointF p) const;
158 	QRectF globalToCanvas(QRect p) const;
159 //	QRectF globalToCanvas(QRectF p) const;
160 	bool hitsCanvasPoint(QPoint globalPoint, const FPoint& canvasPoint) const;
161 	bool hitsCanvasPoint(QPoint globalPoint, QPointF canvasPoint) const;
162 	bool hitsCanvasPoint(const FPoint& globalPoint, const QPointF& canvasPoint) const;
163 	QRect exposedRect() const;
164 	bool cursorOverTextFrameControl(QPoint globalPos, PageItem* frame);
165 	bool cursorOverFrameControl(QPoint globalPos, const QRectF& targetRect, PageItem* frame);
166 	/** Returns the framehandle or INSIDE if the position falls into the frame. */
167 	FrameHandle frameHitTest(QPointF canvasPoint, PageItem* item) const;
168 	FrameHandle frameHitTest(QPointF canvasPoint, const QRectF& frame) const;
169 	/**
170 		Returns the item under the cursor or nullptr if none found.
171 	 Does *not* change the selection.
172 	 If itemAbove is given, it will look for an item under itemAbove, allowing select under.
173 	 The flag 'allowInGroup' controls if single items within a group or only whole groups are considered.
174 	 The flag 'allowMasterItems' controls if items from a masterpage are considered.
175 	 (this flag is ignored in masterpage mode, since all items are masterpage items then).
176 	 */
177 	PageItem* itemUnderCursor(QPoint globalPos, PageItem* itemAbove=nullptr, bool allowInGroup=false, bool allowMasterItems=false) const;
178 	PageItem* itemInGroup(PageItem* group, const QRectF& mouseArea) const;
179 	PageItem* itemUnderItem(PageItem* item, int& index) const;
180 
redrawPolygon()181 	const QPolygon& redrawPolygon() const { return m_viewMode.redrawPolygon; }
newRedrawPolygon()182 	QPolygon& newRedrawPolygon()
183 	{
184 		m_viewMode.redrawPolygon.clear();
185 		return m_viewMode.redrawPolygon;
186 	}
setForcedRedraw(bool on)187 	void setForcedRedraw(bool on) { m_viewMode.forceRedraw = on; }
isForcedRedraw()188 	bool isForcedRedraw() const { return m_viewMode.forceRedraw; }
setPreviewMode(bool on)189 	void setPreviewMode(bool on) { m_viewMode.previewMode = on; }
isPreviewMode()190 	bool isPreviewMode() const { return m_viewMode.previewMode || m_viewMode.viewAsPreview; }
usePreviewVisual()191 	bool usePreviewVisual() const { return m_viewMode.viewAsPreview && m_viewMode.previewVisual != 0; }
previewVisual()192 	int previewVisual() const { return m_viewMode.previewVisual; }
193 	void setPreviewVisual(int mode);
194 
195 	void DrawMasterItems(ScPainter *painter, ScPage *page, ScLayer& layer, QRect clip);
196 	//notesFramesPass determine if notes frames are drawed or not
197 	void DrawPageItems(ScPainter *painter, ScLayer& layer, QRect clip, bool notesFramesPass);
198 	void paintEvent ( QPaintEvent * p ) override;
199 	void displayXYHUD(QPoint m);
200 	void displayCorrectedXYHUD(QPoint m, double x, double y);
201 	void displayCorrectedSingleHUD(QPoint m, double val, bool isX);
202 	void displayXYHUD(QPoint m, double x, double y);
203 	void displaySizeHUD(QPoint m, double x, double y, bool isLine = false);
204 	void displayRotHUD(QPoint m, double rot);
205 	void displayRealRotHUD(QPoint m, double rot);
206 	/**
207 	 * Displays a tooltip of the format <code>{label}: {N} {unit}</code> where <code>N</code> is
208 	 * @a value converted to the current document unit and <code>unit</code> the current document
209 	 * unit. The tooltip will be displayed nearby the global point @a point.
210 	 */
211 		void displayDoubleHUD(QPoint point, const QString& label, double value);
212 
213 	void setupEditHRuler(PageItem * item, bool forceAndReset = false);
214 
215 private:
216 	void DrawPageBorderSub(ScPainter *p, ScPage *page);
217 	void DrawPageBorder(ScPainter *p, const QRectF& clip, bool master = false);
218 	void DrawPageMarginsGridSub(ScPainter *p, ScPage *page);
219 	void DrawPageMargins(ScPainter *p, const QRectF& clip, bool master = false);
220 	void DrawPageBaselineGridSub(ScPainter *p, ScPage *page);
221 	void DrawPageBaselineGrid(ScPainter *p, const QRectF& clip, bool master = false);
222 	void DrawPageGridSub(ScPainter *p, ScPage *page, const QRectF& clip);
223 	void DrawPageGrid(ScPainter *p, const QRectF& clip, bool master = false);
224 	void DrawPageGuidesSub(ScPainter *p, ScPage *page);
225 	void DrawPageGuides(ScPainter *p, const QRectF& clip, bool master = false);
226 	void DrawPageIndicatorSub(ScPainter *p, ScPage *page);
227 	void DrawPageIndicator(ScPainter *p, const QRectF& clip, bool master = false);
228 	void drawLinkFrameLine(ScPainter* painter, FPoint &start, FPoint &end);
229 	void PaintSizeRect(QRect newRect);
230 	void PaintSizeRect(QPolygon newRect);
231 	void Transform(PageItem *currItem, QPainter *p);
232 	void Transform(PageItem *currItem, QTransform& m);
233 	void TransformM(PageItem *currItem, QPainter *p);
234 	void getGroupRectScreen(double *x, double *y, double *w, double *h);
235 
236 	/**
237 		Enlarges the buffer such that it contains the viewport.
238 	 */
239 	bool adjustBuffer();
240 	/**
241 		Fills the given buffer with contents.
242 	    bufferOrigin and clipRect are in local coordinates
243 	 */
244 	void fillBuffer(QPaintDevice* buffer, QPoint bufferOrigin, QRect clipRect);
245 	void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph);
246 	void drawBackgroundMasterpage(ScPainter* painter, int clipx, int clipy, int clipw, int cliph);
247 	void drawBackgroundPageOutlines(ScPainter* painter, int clipx, int clipy, int clipw, int cliph);
248 	void drawFrameLinks(ScPainter* painter);
249 	void drawControls(QPainter* p);
250 	void drawControlsMovingItemsRect(QPainter* pp);
251 	void drawControlsBezierCurve(QPainter* pp, PageItem* currItem);
252 	void drawControlsMeasurementLine(QPainter* pp);
253 	void drawControlsDrawLine(QPainter* pp);
254 	void drawControlsFreehandLine(QPainter* pp);
255 	void getLinkedFrames(PageItem* currItem);
256 	void getClipPathForPages(FPointArray* PoLine);
257 	void calculateFrameLinkPoints(PageItem* pi1, PageItem* pi2, FPoint& start, FPoint& end);
258 
259 	// create a potentially hidpi pixmap
260 	QPixmap createPixmap(double w, double h);
261 	// draw a potentially hidpi pixmap
262 	void drawPixmap(QPainter &painter, double x, double y, const QPixmap &pixmap, double sx, double sy, double sw, double sh);
263 
264 private:
265 	ScribusDoc* m_doc;
266 	ScribusView* m_view;
267 	CanvasViewMode m_viewMode;
268 
269 	RenderMode m_renderMode;
270 	QPixmap m_buffer;
271 	QRect   m_bufferRect;
272 	QPixmap m_selectionBuffer;
273 	QRect   m_selectionRect;
274 	QPoint  m_oldMinCanvasCoordinate;
275 };
276 
277 
278 #endif
279 
280 
281 
282