Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #include "bufferedpaintprovider.h"
23 :
24 : #include "utils/drawlogger.h"
25 : #include "log.h"
26 :
27 : using namespace muse;
28 : using namespace muse::draw;
29 :
30 7 : BufferedPaintProvider::BufferedPaintProvider()
31 : {
32 7 : m_drawObjectsLogger = new DrawObjectsLogger();
33 7 : clear();
34 7 : }
35 :
36 7 : BufferedPaintProvider::~BufferedPaintProvider()
37 : {
38 7 : delete m_drawObjectsLogger;
39 7 : }
40 :
41 7 : void BufferedPaintProvider::beginTarget(const std::string& name)
42 : {
43 7 : clear();
44 7 : m_buf->name = name;
45 7 : m_stateIsUsed = false;
46 7 : m_currentStateNo = 0;
47 7 : m_buf->states[m_currentStateNo] = DrawData::State(); // default
48 7 : beginObject("target_" + name);
49 7 : m_isActive = true;
50 7 : }
51 :
52 10 : void BufferedPaintProvider::beforeEndTargetHook(Painter*)
53 : {
54 10 : }
55 :
56 10 : bool BufferedPaintProvider::endTarget(bool endDraw)
57 : {
58 : UNUSED(endDraw);
59 10 : if (m_isActive) {
60 7 : m_isActive = false;
61 7 : endObject();
62 : }
63 10 : return true;
64 : }
65 :
66 0 : bool BufferedPaintProvider::isActive() const
67 : {
68 0 : return m_isActive;
69 : }
70 :
71 15 : void BufferedPaintProvider::beginObject(const std::string& name)
72 : {
73 : // no begin any objects
74 15 : if (m_itemLevel < 0) {
75 7 : m_buf->item.name = name;
76 7 : m_buf->item.datas.emplace_back(); // default state
77 7 : m_itemLevel = 0;
78 7 : return;
79 : }
80 :
81 : // add new object
82 8 : DrawData::Item& parent = editableItem();
83 8 : DrawData::Item& ch = parent.chilren.emplace_back(name);
84 :
85 8 : ++m_itemLevel;
86 :
87 8 : ensureItemInit(ch);
88 :
89 : #ifdef MUSE_MODULE_DRAW_TRACE
90 : //m_drawObjectsLogger->beginObject(name);
91 : #endif
92 : }
93 :
94 15 : void BufferedPaintProvider::endObject()
95 : {
96 16 : TRACEFUNC;
97 15 : IF_ASSERT_FAILED(m_itemLevel > -1) {
98 0 : return;
99 : }
100 :
101 15 : DrawData::Item& obj = editableItem();
102 :
103 : // remove default state or state without data
104 15 : if (obj.datas.back().empty()) {
105 12 : obj.datas.pop_back();
106 : }
107 :
108 15 : --m_itemLevel;
109 :
110 : #ifdef MUSE_MODULE_DRAW_TRACE
111 : //m_drawObjectsLogger->endObject();
112 : #endif
113 15 : }
114 :
115 1062 : void BufferedPaintProvider::ensureItemInit(DrawData::Item& item) const
116 : {
117 1062 : if (item.datas.empty()) {
118 8 : item.datas.emplace_back(); // default data
119 8 : item.datas.back().state = m_currentStateNo; // current state
120 : }
121 1062 : }
122 :
123 0 : const DrawData::Item& BufferedPaintProvider::currentItem() const
124 : {
125 0 : DrawData::Item* itemPtr = &m_buf->item;
126 0 : for (int i = 0; i < m_itemLevel; ++i) {
127 0 : itemPtr = &itemPtr->chilren.back();
128 : }
129 :
130 0 : DrawData::Item& item = *itemPtr;
131 :
132 0 : ensureItemInit(item);
133 :
134 0 : return item;
135 : }
136 :
137 733 : DrawData::Item& BufferedPaintProvider::editableItem()
138 : {
139 733 : DrawData::Item* itemPtr = &m_buf->item;
140 1453 : for (int i = 0; i < m_itemLevel; ++i) {
141 720 : itemPtr = &itemPtr->chilren.back();
142 : }
143 :
144 733 : DrawData::Item& item = *itemPtr;
145 :
146 733 : ensureItemInit(item);
147 :
148 733 : return item;
149 : }
150 :
151 0 : const DrawData::Data& BufferedPaintProvider::currentData() const
152 : {
153 0 : return currentItem().datas.back();
154 : }
155 :
156 219 : const DrawData::State& BufferedPaintProvider::currentState() const
157 : {
158 219 : return m_buf->states.at(m_currentStateNo);
159 : }
160 :
161 389 : DrawData::Data& BufferedPaintProvider::editableData()
162 : {
163 389 : m_stateIsUsed = true;
164 389 : return editableItem().datas.back();
165 : }
166 :
167 1551 : DrawData::State& BufferedPaintProvider::editableState()
168 : {
169 : {
170 1551 : if (!m_stateIsUsed) {
171 1230 : return m_buf->states[m_currentStateNo];
172 : }
173 : }
174 :
175 : // make new state
176 : {
177 321 : const DrawData::State& current = m_buf->states.at(m_currentStateNo);
178 321 : m_currentStateNo++;
179 321 : m_buf->states[m_currentStateNo] = current;
180 : }
181 :
182 : // make new data if current not empty
183 : {
184 321 : DrawData::Item& item = editableItem();
185 321 : ensureItemInit(item);
186 321 : if (!item.datas.back().empty()) {
187 320 : item.datas.emplace_back();
188 320 : item.datas.back().state = m_currentStateNo;
189 : }
190 : }
191 :
192 321 : m_stateIsUsed = false;
193 :
194 321 : return m_buf->states[m_currentStateNo];
195 : }
196 :
197 5 : void BufferedPaintProvider::setAntialiasing(bool arg)
198 : {
199 5 : editableState().isAntialiasing = arg;
200 5 : }
201 :
202 0 : void BufferedPaintProvider::setCompositionMode(CompositionMode mode)
203 : {
204 0 : editableState().compositionMode = mode;
205 0 : }
206 :
207 6 : void BufferedPaintProvider::setWindow(const RectF&)
208 : {
209 6 : }
210 :
211 7 : void BufferedPaintProvider::setViewport(const RectF& viewport)
212 : {
213 7 : m_buf->viewport = viewport;
214 7 : }
215 :
216 396 : void BufferedPaintProvider::setFont(const Font& f)
217 : {
218 396 : editableState().font = f;
219 396 : }
220 :
221 198 : const Font& BufferedPaintProvider::font() const
222 : {
223 198 : return currentState().font;
224 : }
225 :
226 315 : void BufferedPaintProvider::setPen(const Pen& pen)
227 : {
228 315 : editableState().pen = pen;
229 315 : }
230 :
231 0 : void BufferedPaintProvider::setNoPen()
232 : {
233 0 : editableState().pen.setStyle(PenStyle::NoPen);
234 0 : }
235 :
236 4 : const Pen& BufferedPaintProvider::pen() const
237 : {
238 4 : return currentState().pen;
239 : }
240 :
241 10 : void BufferedPaintProvider::setBrush(const Brush& brush)
242 : {
243 10 : editableState().brush = brush;
244 10 : }
245 :
246 4 : const Brush& BufferedPaintProvider::brush() const
247 : {
248 4 : return currentState().brush;
249 : }
250 :
251 238 : void BufferedPaintProvider::save()
252 : {
253 238 : }
254 :
255 238 : void BufferedPaintProvider::restore()
256 : {
257 238 : }
258 :
259 198 : double BufferedPaintProvider::deviceLogicalDpi() const
260 : {
261 198 : return 360;
262 : }
263 :
264 825 : void BufferedPaintProvider::setTransform(const Transform& transform)
265 : {
266 825 : DrawData::State& st = editableState();
267 825 : st.transform = transform;
268 825 : }
269 :
270 7 : const Transform& BufferedPaintProvider::transform() const
271 : {
272 7 : return currentState().transform;
273 : }
274 :
275 : // drawing functions
276 :
277 6 : void BufferedPaintProvider::drawPath(const PainterPath& path)
278 : {
279 6 : const DrawData::State& st = currentState();
280 6 : DrawMode mode = DrawMode::StrokeAndFill;
281 6 : if (st.pen.style() == PenStyle::NoPen) {
282 4 : mode = DrawMode::Fill;
283 2 : } else if (st.brush.style() == BrushStyle::NoBrush) {
284 0 : mode = DrawMode::Stroke;
285 : }
286 12 : editableData().paths.push_back({ path, st.pen, st.brush, mode });
287 12 : }
288 :
289 185 : void BufferedPaintProvider::drawPolygon(const PointF* points, size_t pointCount, PolygonMode mode)
290 : {
291 185 : PolygonF pol(pointCount);
292 555 : for (size_t i = 0; i < pointCount; ++i) {
293 370 : pol[i] = PointF(points[i].x(), points[i].y());
294 : }
295 185 : editableData().polygons.push_back(DrawPolygon { pol, mode });
296 185 : }
297 :
298 198 : void BufferedPaintProvider::drawText(const PointF& point, const String& text)
299 : {
300 198 : editableData().texts.push_back(DrawText { DrawText::Point, RectF(point, SizeF()), {}, {}, text });
301 198 : }
302 :
303 0 : void BufferedPaintProvider::drawText(const RectF& rect, Alignment alignment, TextFlags textFlags, const String& text)
304 : {
305 0 : editableData().texts.push_back(DrawText { DrawText::Rect, rect, alignment, textFlags, text });
306 0 : }
307 :
308 198 : void BufferedPaintProvider::drawSymbol(const PointF& point, char32_t ucs4Code)
309 : {
310 198 : drawText(point, String::fromUcs4(&ucs4Code, 1));
311 198 : }
312 :
313 0 : void BufferedPaintProvider::drawPixmap(const PointF& p, const Pixmap& pm)
314 : {
315 0 : editableData().pixmaps.push_back(DrawPixmap { DrawPixmap::Single, RectF(p, SizeF()), pm, PointF() });
316 0 : }
317 :
318 0 : void BufferedPaintProvider::drawTiledPixmap(const RectF& rect, const Pixmap& pm, const PointF& offset)
319 : {
320 0 : editableData().pixmaps.push_back(DrawPixmap { DrawPixmap::Tiled, rect, pm, offset });
321 0 : }
322 :
323 : #ifndef NO_QT_SUPPORT
324 0 : void BufferedPaintProvider::drawPixmap(const PointF& p, const QPixmap& pm)
325 : {
326 0 : editableData().pixmaps.push_back(DrawPixmap { DrawPixmap::Single, RectF(p, SizeF()), Pixmap::fromQPixmap(pm), PointF() });
327 0 : }
328 :
329 0 : void BufferedPaintProvider::drawTiledPixmap(const RectF& rect, const QPixmap& pm, const PointF& offset)
330 : {
331 0 : editableData().pixmaps.push_back(DrawPixmap { DrawPixmap::Tiled, rect, Pixmap::fromQPixmap(pm), offset });
332 0 : }
333 :
334 : #endif
335 :
336 8 : bool BufferedPaintProvider::hasClipping() const
337 : {
338 8 : return false;
339 : }
340 :
341 4 : void BufferedPaintProvider::setClipRect(const RectF& rect)
342 : {
343 : UNUSED(rect);
344 4 : }
345 :
346 0 : void BufferedPaintProvider::setMask(const RectF& background, const std::vector<RectF>& maskRects)
347 : {
348 : UNUSED(background);
349 : UNUSED(maskRects);
350 0 : }
351 :
352 8 : void BufferedPaintProvider::setClipping(bool enable)
353 : {
354 : UNUSED(enable);
355 8 : }
356 :
357 7 : DrawDataPtr BufferedPaintProvider::drawData() const
358 : {
359 7 : return m_buf;
360 : }
361 :
362 14 : void BufferedPaintProvider::clear()
363 : {
364 14 : m_buf = std::make_shared<DrawData>();
365 14 : m_itemLevel = -1;
366 14 : }
|