LCOV - code coverage report
Current view: top level - muse/framework/draw - bufferedpaintprovider.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 79.3 % 174 138
Test Date: 2026-11-05 04:07:02

            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 : }
        

Generated by: LCOV version 2.0-1