File: Canvas.h

package info (click to toggle)
dasher 5.0.0~beta~repack2-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 70,872 kB
  • sloc: xml: 181,314; cpp: 70,860; java: 8,020; python: 3,579; makefile: 939; sh: 324; ansic: 223; perl: 71
file content (259 lines) | stat: -rw-r--r-- 7,483 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#ifndef __canvas_h__
#define __canvas_h__

#include <cstdlib>

#include "../DasherCore/DasherScreen.h"
#include "../DasherCore/DasherTypes.h"

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <pango/pango.h>
#include <map>

#include <iostream>

#if WITH_CAIRO

#define BEGIN_DRAWING_BACKEND				\
  cairo_save(cr)

#define END_DRAWING_BACKEND				\
  cairo_restore(cr)

#define SET_COLOR_BACKEND(c)				\
  cairo_set_source(cr, cairo_colours[(c)])

#else /* WITHOUT_CAIRO */

#define BEGIN_DRAWING_BACKEND				\
  GdkGCValues origvalues;				\
  gdk_gc_get_values(graphics_context,&origvalues)

#define END_DRAWING_BACKEND				\
  gdk_gc_set_values(graphics_context,&origvalues,GDK_GC_FOREGROUND)

#define SET_COLOR_BACKEND(c)				\
  do {							\
    GdkColor _c = colours[(c)];				\
    gdk_colormap_alloc_color(colormap, &_c, FALSE, TRUE);	\
    gdk_gc_set_foreground (graphics_context, &_c);	\
  } while (0)

#endif /* WITH_CAIRO */

// Some other useful macros (for all backends)

#define BEGIN_DRAWING					\
  BEGIN_DRAWING_BACKEND

#define END_DRAWING					\
  END_DRAWING_BACKEND

#define SET_COLOR(c)					\
  SET_COLOR_BACKEND(c)

/// CCanvas
///
/// Method definitions for CCanvas, implementing the CDasherScreen
/// interface.  Please think very carefully before implementing new
/// functionality in this class. Anything which isn't a 'drawing
/// primitive' should really not be here - higher level drawing
/// functions belong in CDasherView.

class CCanvas:public Dasher::CLabelListScreen {

public:
  typedef Dasher::screenint screenint;
  /// Creates a new canvas - initially of zero size, so drawing
  /// operations won't do anything until a call to resize() is made.
  /// \param pCanvas The GTK drawing area used by the canvas
  ///

  CCanvas(GtkWidget *pCanvas);
  ~CCanvas();

  ///
  /// GTK signal handler for exposure of the canvas - cause a redraw to the screen from the buffer.
  ///

  bool ExposeEvent( GtkWidget *pWidget, GdkEventExpose *pEvent);


  // CDasherScreen methods

  ///
  /// Set the font used to render the Dasher display
  /// \param Name The name of the font.
  /// \todo This needs to be reimplemented for 4.0
  /// \deprecated In Linux - now handled by the pango cache, but need to think how this fits in with Windows
  ///  

  void SetFont(const std::string &strName);

  ///Make a label for use with this screen; caches Pango layout information inside it.
  CDasherScreen::Label *MakeLabel(const std::string &strText, unsigned int iWrapSize=0) override;

  ///
  /// Return the physical extent of a given string being rendered at a given size.
  /// \param String The string to be rendered
  /// \param Width Pointer to a variable to be filled with the width
  /// \param Height Pointer to a variable to be filled with the height
  /// \param Size Size at which the string will be rendered (units?)
  ///

  std::pair<screenint,screenint> TextSize(CDasherScreen::Label *label, unsigned int Size) override;

  ///
  /// Draw a text string
  /// \param String The string to be rendered
  /// \param x1 The x coordinate at which to draw the text (be more precise)
  /// \param y1 The y coordinate at which to draw the text (be more precise)
  /// \param Size The size at which to render the rectangle (units?)
  ///

  void DrawString(CDasherScreen::Label *label, screenint x1, screenint y1, unsigned int Size, int iColor) override;

  ///
  /// Draw a rectangle
  /// \param x1 x coordiate of the top left corner
  /// \param y1 y coordiate of the top left corner
  /// \param x2 x coordiate of the bottom right corner
  /// \param y2 y coordiate of the bottom right corner
  /// \param Color Colour to fill the rectangle (-1 = don't fill)
  /// \param iOutlineColour Colour to draw the outline (-1 = use default)
  /// \param iThickness line width of outline (<=0 = don't outline)
  ///
  void DrawRectangle(screenint x1, screenint y1, screenint x2, screenint y2, int Color, int iOutlineColour, int iThickness) override;

  void DrawCircle(screenint iCX, screenint iCY, screenint iR, int iFillColour, int iLineColour, int iThickness) override;

  ///
  /// Send a marker to indicate phases of the redraw process. This is
  /// done so that we can do tripple buffering to minimise the amount
  /// of costly font rendering which needs to be done. Marker 1
  /// indicates that start of a new frame. Marker 2 indicates that we
  /// are now drawing decoration (such as mouse cursors etc.) rather
  /// than tne background. Only marker 2 will be send while Dasher is
  /// paused.
  /// \param iMarker ID of the marker being sent.
  ///

  void SendMarker(int iMarker) override;

  /// 
  /// Draw a coloured polyline
  /// \param Points Array of vertices
  /// \param Number Size of 'Points' array
  /// \param Colour Colour with which to draw the line
  ///

  void Polyline(point * Points, int Number, int iWidth, int Colour) override;

  /// 
  /// Draw a closed polygon (linking last vertex back to first)
  /// @param fillColour colour to fill; -1 => don't fill
  /// @param outlineColour colour to draw outline...
  /// @param iWidth ...and line thickness; -1 => don't draw outline
  ///

  void Polygon(point *Points, int Number, int fillColour, int outlineColour, int iWidth) override;

  /// 
  /// Marks the end of the display process - at this point the offscreen buffer is copied onscreen.
  ///

  void Display() override;

  ///
  /// Update the colour definitions
  /// \param Colours New colours to use
  ///

  void SetColourScheme(const Dasher::CColourIO::ColourInfo *pColourScheme) override;

  /// 
  /// Gets the location and size of our canvas.
  /// Returns true on success, false otherwise.
  bool GetCanvasSize(GdkRectangle *pRectangle);

  // Redeclare to make public and adjust cairo/gdk surface sizes
  void resize(screenint w,screenint h);
  // Returns true if cursor is over visible part of this window.
  bool IsWindowUnderCursor() override;

private:

  ///
  /// The GTK drawing area for the canvas
  ///

  GtkWidget *m_pCanvas;

  void InitSurfaces();
  void DestroySurfaces();
#if WITH_CAIRO

  cairo_surface_t *m_pDisplaySurface;
  cairo_surface_t *m_pDecorationSurface;
  //cairo_surface_t *m_pOnscreenSurface;

  cairo_surface_t *m_pOffscreenbuffer;

#else

  ///
  /// The offscreen buffer containing the 'background'
  ///

  GdkPixmap *m_pDisplayBuffer;

  /// 
  /// The offscreen buffer containing the full display. This is
  /// constructed by first copying the display buffer across and then
  /// drawing decorations such as the mouse cursor on top.
  ///

  GdkPixmap *m_pDecorationBuffer;

  ///
  /// The onscreen buffer - copied onscreen whenever an expose event occurs.
  ///

  //GdkPixmap *m_pOnscreenBuffer;

  ///
  /// Pointer to which of the offscreen buffers is currently active.
  ///

  GdkPixmap *m_pOffscreenBuffer;
  //GdkPixmap *m_pDummyBuffer;

#endif

  std::string m_strFontName;
  std::map<unsigned int,PangoFontDescription *> m_mFonts;

  class CPangoLabel : public CLabelListScreen::Label {
  public:
    CPangoLabel(CCanvas *pCanvas, const std::string &strText, unsigned int iWrapFontSize)
    : CLabelListScreen::Label(pCanvas, strText, iWrapFontSize) {
    }
    std::map<unsigned int,PangoLayout *> m_mLayouts;
  };

  PangoLayout *GetLayout(CPangoLabel *label, unsigned int iFontSize);

#if WITH_CAIRO
  cairo_t *display_cr;
  cairo_t *decoration_cr;

  cairo_t *cr; // offscreen
  cairo_pattern_t **cairo_colours;
#else
  GdkColor *colours;
#endif  

};

#endif