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