1 // -*- C++ -*-
2 // --------------------------------------------------------------------
3 // ipe::Canvas
4 // --------------------------------------------------------------------
5 /*
6 
7     This file is part of the extensible drawing editor Ipe.
8     Copyright (c) 1993-2020 Otfried Cheong
9 
10     Ipe is free software; you can redistribute it and/or modify it
11     under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 3 of the License, or
13     (at your option) any later version.
14 
15     As a special exception, you have permission to link Ipe with the
16     CGAL library and distribute executables, as long as you follow the
17     requirements of the Gnu General Public License in regard to all of
18     the software in the executable aside from CGAL.
19 
20     Ipe is distributed in the hope that it will be useful, but WITHOUT
21     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
23     License for more details.
24 
25     You should have received a copy of the GNU General Public License
26     along with Ipe; if not, you can find it at
27     "http://www.gnu.org/copyleft/gpl.html", or write to the Free
28     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 
30 */
31 
32 #ifndef IPECANVAS_H
33 #define IPECANVAS_H
34 
35 #include "ipelib.h"
36 
37 // --------------------------------------------------------------------
38 
39 // Avoid including cairo.h
40 typedef struct _cairo cairo_t;
41 typedef struct _cairo_surface cairo_surface_t;
42 
43 // --------------------------------------------------------------------
44 
45 namespace ipe {
46 
47   class Fonts;
48   class Tool;
49   class PdfResources;
50 
51   // --------------------------------------------------------------------
52 
53   class CanvasObserver {
54   public:
55     virtual ~CanvasObserver();
56     // kind = 0: precise pan, 1: osx 'imprecise' pan, 2: zoom
57     virtual void canvasObserverWheelMoved(double xDegrees,
58 					  double yDegrees,
59 					  int kind);
60     virtual void canvasObserverMouseAction(int button);
61     virtual void canvasObserverPositionChanged();
62     virtual void canvasObserverToolChanged(bool hasTool);
63     virtual void canvasObserverSizeChanged();
64   };
65 
66   class CanvasBase {
67 
68   public:
69     //! Keyboard modifiers
70     enum TModifiers { EShift = 0x100, EControl = 0x200,
71 		      EAlt = 0x400, EMeta = 0x800,
72 		      ECommand = 0x1000 };
73 
74     enum TCursor { EStandardCursor, EHandCursor, ECrossCursor,
75 		   EDotCursor };
76 
77     /*! In pretty display, no dashed lines are drawn around text
78       objects, and if Latex font data is not available, no text is
79       drawn at all. */
80     struct Style {
81       Color paperColor;
82       Color primarySelectionColor;
83       Color secondarySelectionColor;
84       bool pretty;
85       bool classicGrid;
86       double thinLine;
87       double thickLine;
88       int thinStep;
89       int thickStep;
90       bool paperClip;
91       bool numberPages;
92     };
93 
94     virtual ~CanvasBase();
95 
96     void setPage(const Page *page, int pno, int view, const Cascade *sheet);
97     void setResources(const PdfResources *resources);
98 
99     //! Return current pan.
pan()100     inline Vector pan() const { return iPan; }
101     //! Return current zoom.
zoom()102     inline double zoom() const { return iZoom; }
103     //! Return current style sheet cascade.
cascade()104     inline const Cascade *cascade() const { return iCascade; }
105     //! Return center of canvas.
center()106     inline Vector center() const {return 0.5 * Vector(iWidth, iHeight); }
107     //! Return last mouse position (snapped!) in user coordinates.
pos()108     inline Vector pos() const { return iMousePos; }
109     //! Return last unsnapped mouse position in user coordinates.
unsnappedPos()110     inline Vector unsnappedPos() const { return iUnsnappedMousePos; }
111     //! Return global mouse position of last mouse press/release.
globalPos()112     inline Vector globalPos() const { return iGlobalPos; }
113     Vector simpleSnapPos() const;
114     //! Return current snapping information.
snap()115     inline const Snap &snap() const { return iSnap; }
116 
117     //! Set ink mode.
setInkMode(bool ink)118     inline void setInkMode(bool ink) { isInkMode = ink; }
119 
120     //! Return current additional modifiers.
additionalModifiers()121     inline int additionalModifiers() const { return iAdditionalModifiers; }
122     void setAdditionalModifiers(int mod);
123 
124     //! Has an attempt been made to use a Type3 font?
125     bool type3Font();
126 
127     Vector devToUser(const Vector &arg) const;
128     Vector userToDev(const Vector &arg) const;
129 
130     void setCanvasStyle(const Style &style);
131     //! Return canvas style
canvasStyle()132     Style canvasStyle() const { return iStyle; }
133     void setPan(const Vector &v);
134     void setZoom(double zoom);
135     void setSnap(const Snap &s);
136     void setDimmed(bool dimmed);
137     void setAutoOrigin(const Vector &v);
138 
139     Matrix canvasTfm() const;
140 
141     void setObserver(CanvasObserver *observer);
142 
143     void setFifiVisible(bool visible);
144     void setSelectionVisible(bool visible);
145 
146     void setTool(Tool *tool);
147     void finishTool();
148 
tool()149     Tool *tool() { return iTool; }
150 
151     void update();
152     void updateTool();
153 
canvasWidth()154     int canvasWidth() const { return iWidth; }
canvasHeight()155     int canvasHeight() const { return iHeight; }
156 
157     virtual void setCursor(TCursor cursor, double w = 1.0,
158 			   Color *color = nullptr) = 0;
159 
160     static int selectPageOrView(Document *doc, int page = -1,
161 				int startIndex = 0,
162 				int pageWidth = 240,
163 				int width = 600, int height = 480);
164 
165     virtual void invalidate(int x, int y, int w, int h) = 0;
166 
167   protected:
168     CanvasBase();
169     void drawPaper(cairo_t *cc);
170     void drawFrame(cairo_t *cc);
171     void drawAxes(cairo_t *cc);
172     void drawGrid(cairo_t *cc);
173     void drawObjects(cairo_t *cc);
174     void drawTool(Painter &painter);
175     void snapToPaperAndFrame();
176     void refreshSurface();
177     void computeFifi(double x, double y);
178     void drawFifi(cairo_t *cr);
179 
180     virtual void invalidate() = 0;
181 
182   protected:
183     CanvasObserver *iObserver;
184     Tool *iTool;
185     const Page *iPage;
186     int iPageNumber;
187     int iView;
188     const Cascade *iCascade;
189 
190     Style iStyle;
191 
192     Vector iPan;
193     double iZoom;
194     Snap iSnap;
195     bool iDimmed;
196     bool iAutoSnap;
197     Vector iAutoOrigin;
198     int iAdditionalModifiers;
199     bool isInkMode;
200 
201     bool iRepaintObjects;
202     double iWidth, iHeight;
203     double iBWidth, iBHeight; // size of backing store
204     cairo_surface_t *iSurface;
205 
206     Vector iUnsnappedMousePos;
207     Vector iMousePos;
208     Vector iGlobalPos;
209     Vector iOldFifi;  // last fifi position that has been drawn
210     bool iFifiVisible;
211     Snap::TSnapModes iFifiMode;
212     bool iSelectionVisible;
213 
214     const PdfResources *iResources;
215     std::unique_ptr<Fonts> iFonts;
216     bool iType3Font;
217   };
218 
219 } // namespace
220 
221 // --------------------------------------------------------------------
222 #endif
223