1 // Aseprite UI Library
2 // Copyright (C) 2001-2018  David Capello
3 //
4 // This file is released under the terms of the MIT license.
5 // Read LICENSE.txt for more information.
6 
7 #ifndef UI_GRAPHICS_H_INCLUDED
8 #define UI_GRAPHICS_H_INCLUDED
9 #pragma once
10 
11 #include "base/disable_copying.h"
12 #include "base/shared_ptr.h"
13 #include "base/string.h"
14 #include "gfx/color.h"
15 #include "gfx/point.h"
16 #include "gfx/rect.h"
17 #include "gfx/size.h"
18 
19 #include <string>
20 
21 namespace gfx {
22   class Region;
23 }
24 
25 namespace she {
26   class DrawTextDelegate;
27   class Font;
28   class Surface;
29 }
30 
31 namespace ui {
32 
33   // Class to render a widget in the screen.
34   class Graphics {
35   public:
36     enum class DrawMode {
37       Solid,
38       Xor,
39       Checked,
40     };
41 
42     Graphics(she::Surface* surface, int dx, int dy);
43     ~Graphics();
44 
45     int width() const;
46     int height() const;
47 
getInternalSurface()48     she::Surface* getInternalSurface() { return m_surface; }
getInternalDeltaX()49     int getInternalDeltaX() { return m_dx; }
getInternalDeltaY()50     int getInternalDeltaY() { return m_dy; }
51 
52     int getSaveCount() const;
53     gfx::Rect getClipBounds() const;
54     void saveClip();
55     void restoreClip();
56     bool clipRect(const gfx::Rect& rc);
57 
58     void setDrawMode(DrawMode mode, int param = 0,
59                      const gfx::Color a = gfx::ColorNone,
60                      const gfx::Color b = gfx::ColorNone);
61 
62     gfx::Color getPixel(int x, int y);
63     void putPixel(gfx::Color color, int x, int y);
64 
65     void drawHLine(gfx::Color color, int x, int y, int w);
66     void drawVLine(gfx::Color color, int x, int y, int h);
67     void drawLine(gfx::Color color, const gfx::Point& a, const gfx::Point& b);
68 
69     void drawRect(gfx::Color color, const gfx::Rect& rc);
70     void fillRect(gfx::Color color, const gfx::Rect& rc);
71     void fillRegion(gfx::Color color, const gfx::Region& rgn);
72     void fillAreaBetweenRects(gfx::Color color,
73       const gfx::Rect& outer, const gfx::Rect& inner);
74 
75     void drawSurface(she::Surface* surface, int x, int y);
76     void drawRgbaSurface(she::Surface* surface, int x, int y);
77     void drawRgbaSurface(she::Surface* surface, int srcx, int srcy, int dstx, int dsty, int w, int h);
78     void drawRgbaSurface(she::Surface* surface,
79                          const gfx::Rect& srcRect,
80                          const gfx::Rect& dstRect);
81     void drawColoredRgbaSurface(she::Surface* surface, gfx::Color color, int x, int y);
82     void drawColoredRgbaSurface(she::Surface* surface, gfx::Color color, int srcx, int srcy, int dstx, int dsty, int w, int h);
83 
84     void blit(she::Surface* src, int srcx, int srcy, int dstx, int dsty, int w, int h);
85 
86     // ======================================================================
87     // FONT & TEXT
88     // ======================================================================
89 
font()90     she::Font* font() { return m_font; }
91     void setFont(she::Font* font);
92 
93     void drawText(base::utf8_const_iterator it,
94                   const base::utf8_const_iterator& end,
95                   gfx::Color fg, gfx::Color bg, const gfx::Point& pt,
96                   she::DrawTextDelegate* delegate);
97     void drawText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Point& pt);
98     void drawUIText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Point& pt, const int mnemonic);
99     void drawAlignedUIText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Rect& rc, const int align);
100 
101     gfx::Size measureUIText(const std::string& str);
102     static int measureUITextLength(const std::string& str, she::Font* font);
103     gfx::Size fitString(const std::string& str, int maxWidth, int align);
104 
105   private:
106     gfx::Size doUIStringAlgorithm(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Rect& rc, int align, bool draw);
107     void dirty(const gfx::Rect& bounds);
108 
109     she::Surface* m_surface;
110     int m_dx;
111     int m_dy;
112     gfx::Rect m_clipBounds;
113     she::Font* m_font;
114     gfx::Rect m_dirtyBounds;
115   };
116 
117   // Class to draw directly in the screen.
118   class ScreenGraphics : public Graphics {
119   public:
120     ScreenGraphics();
121     virtual ~ScreenGraphics();
122   };
123 
124   // Class to temporary set the Graphics' clip region to the full
125   // extend.
126   class SetClip {
127   public:
SetClip(Graphics * g)128     SetClip(Graphics* g)
129       : m_graphics(g)
130       , m_oldClip(g->getClipBounds())
131       , m_oldCount(g->getSaveCount()) {
132       if (m_oldCount > 1)
133         m_graphics->restoreClip();
134     }
135 
~SetClip()136     ~SetClip() {
137       if (m_oldCount > 1) {
138         m_graphics->saveClip();
139         m_graphics->clipRect(m_oldClip);
140       }
141     }
142 
143   private:
144     Graphics* m_graphics;
145     gfx::Rect m_oldClip;
146     int m_oldCount;
147 
148     DISABLE_COPYING(SetClip);
149   };
150 
151   // Class to temporary set the Graphics' clip region to a sub-rectangle
152   // (in the life-time of the IntersectClip instance).
153   class IntersectClip {
154   public:
IntersectClip(Graphics * g,const gfx::Rect & rc)155     IntersectClip(Graphics* g, const gfx::Rect& rc)
156       : m_graphics(g) {
157       m_graphics->saveClip();
158       m_notEmpty = m_graphics->clipRect(rc);
159     }
160 
~IntersectClip()161     ~IntersectClip() {
162       m_graphics->restoreClip();
163     }
164 
165     operator bool() const { return m_notEmpty; }
166 
167   private:
168     Graphics* m_graphics;
169     bool m_notEmpty;
170 
171     DISABLE_COPYING(IntersectClip);
172   };
173 
174   class CheckedDrawMode {
175   public:
CheckedDrawMode(Graphics * g,int param,const gfx::Color a,const gfx::Color b)176     CheckedDrawMode(Graphics* g, int param,
177                     const gfx::Color a,
178                     const gfx::Color b) : m_graphics(g) {
179       m_graphics->setDrawMode(Graphics::DrawMode::Checked, param, a, b);
180     }
181 
~CheckedDrawMode()182     ~CheckedDrawMode() {
183       m_graphics->setDrawMode(Graphics::DrawMode::Solid);
184     }
185 
186   private:
187     Graphics* m_graphics;
188 
189     DISABLE_COPYING(CheckedDrawMode);
190   };
191 
192   typedef base::SharedPtr<Graphics> GraphicsPtr;
193 
194 } // namespace ui
195 
196 #endif
197