LCOV - code coverage report
Current view: top level - src/notationscene/utilities - engravingitempreviewpainter.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 68 0
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2024 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              : 
      23              : #include "engravingitempreviewpainter.h"
      24              : 
      25              : #include "engraving/dom/masterscore.h"
      26              : #include "engraving/dom/textlinebase.h"
      27              : #include "engraving/rendering/paintoptions.h"
      28              : #include "engraving/style/defaultstyle.h"
      29              : 
      30              : using namespace mu::notation;
      31              : using namespace mu::engraving;
      32              : using namespace muse::draw;
      33              : 
      34              : /// Paint `element` centered inside `params.rect`. If `params.numStaffLines >
      35              : /// 0`, then the element is only centered horizontally; i.e. vertical alignment
      36              : /// is unchanged from the default so that item will appear at the correct height
      37              : /// on the staff.
      38            0 : void EngravingItemPreviewPainter::paintPreview(std::shared_ptr<engraving::rendering::ISingleRenderer> render,
      39              :                                                mu::engraving::EngravingItem* element, PaintParams& params)
      40              : {
      41            0 :     IF_ASSERT_FAILED(element && params.painter) {
      42            0 :         return;
      43              :     }
      44              : 
      45            0 :     Painter* painter = params.painter;
      46            0 :     painter->setPen(params.color);
      47              : 
      48            0 :     PointF rectOrigin = params.rect.center(); // draw element at center of cell by default
      49            0 :     if (params.numStaffLines > 0) {
      50            0 :         const double topLinePos = paintStaff(params); // draw dummy staff lines onto rect.
      51            0 :         rectOrigin.setY(topLinePos); // vertical position relative to staff instead of cell center.
      52              :     }
      53              : 
      54            0 :     painter->translate(rectOrigin);
      55              : 
      56            0 :     painter->translate(params.xoffset * params.spatium, params.yoffset * params.spatium); // additional offset for element only
      57              : 
      58            0 :     const Score* score = element->score()->paletteScore() ? element->score()->paletteScore() : element->score();
      59            0 :     const double sizeRatio = params.spatium / score->style().spatium();
      60            0 :     painter->scale(sizeRatio, sizeRatio); // scale coordinates so element is drawn at correct size
      61              : 
      62              :     // calculate bbox
      63            0 :     render->layoutItem(element);
      64              : 
      65            0 :     PointF elementOrigin = element->ldata()->bbox().center();
      66              : 
      67            0 :     if (params.numStaffLines > 0) {
      68              :         // y = 0 is position of the element's parent.
      69              :         // If the parent is the staff (or a segment on the staff) then
      70              :         // y = 0 corresponds to the position of the top staff line.
      71            0 :         elementOrigin.setY(0.0);
      72              :     }
      73              : 
      74              :     // shift coordinates so element is drawn at correct position
      75            0 :     painter->translate(-elementOrigin);
      76              : 
      77            0 :     paintItem(render, element, params);
      78              : }
      79              : 
      80            0 : void EngravingItemPreviewPainter::paintItem(std::shared_ptr<engraving::rendering::ISingleRenderer> render,
      81              :                                             mu::engraving::EngravingItem* element, PaintParams& params)
      82              : {
      83            0 :     IF_ASSERT_FAILED(element && params.painter) {
      84            0 :         return;
      85              :     }
      86              : 
      87            0 :     const auto doPaint = [&](EngravingItem* item) {
      88            0 :         Painter* painter = params.painter;
      89              : 
      90            0 :         painter->save();
      91            0 :         painter->translate(item->pos()); // necessary for drawing child items
      92              : 
      93            0 :         const Color colorBackup = item->getProperty(Pid::COLOR).value<Color>();
      94            0 :         const Color frameColorBackup = item->getProperty(Pid::FRAME_FG_COLOR).value<Color>();
      95              : 
      96            0 :         if (!params.useElementColors) {
      97            0 :             const Color color = params.color;
      98            0 :             item->setProperty(Pid::COLOR, color);
      99            0 :             item->setProperty(Pid::FRAME_FG_COLOR, color);
     100              :         }
     101              : 
     102            0 :         rendering::PaintOptions opt;
     103            0 :         opt.invertColors = params.colorsInversionEnabled;
     104              :         // The drawing color has been specified explicitly above, so use it as-is:
     105            0 :         opt.ignoreDisplayedDefaultColor = !params.useElementColors;
     106              : 
     107            0 :         render->drawItem(item, painter, opt);
     108              : 
     109            0 :         item->setProperty(Pid::COLOR, colorBackup);
     110            0 :         item->setProperty(Pid::FRAME_FG_COLOR, frameColorBackup);
     111              : 
     112            0 :         painter->restore();
     113            0 :     };
     114              : 
     115            0 :     if (element->isSpanner() && !toSpanner(element)->segmentsEmpty()) {
     116            0 :         SpannerSegment* spannerSeg = toSpanner(element)->frontSegment();
     117            0 :         DO_ASSERT(spannerSeg);
     118            0 :         spannerSeg->scanElements(doPaint);
     119              :     } else {
     120            0 :         element->scanElements(doPaint);
     121              :     }
     122              : }
     123              : 
     124              : /// Paint a staff centered within a QRect and return the distance from the
     125              : /// top of the QRect to the uppermost staff line.
     126            0 : double EngravingItemPreviewPainter::paintStaff(PaintParams& params)
     127              : {
     128            0 :     IF_ASSERT_FAILED(params.painter) {
     129            0 :         return 0.0;
     130              :     }
     131              : 
     132            0 :     Painter* painter = params.painter;
     133            0 :     painter->save();
     134              : 
     135            0 :     Color staffLinesColor(params.color);
     136            0 :     staffLinesColor.setAlpha(127); //reduce alpha of staff lines to half
     137            0 :     Pen pen(staffLinesColor);
     138            0 :     pen.setWidthF(engraving::DefaultStyle::defaultStyle().styleS(Sid::staffLineWidth).val() * params.spatium);
     139            0 :     painter->setPen(pen);
     140              : 
     141            0 :     const double staffHeight = params.spatium * (params.numStaffLines - 1);
     142            0 :     const double topLineDist = params.rect.center().y() - (staffHeight / 2.0);
     143              : 
     144              :     // lines bounded horizontally by edge of target (with small margin)
     145            0 :     constexpr double margin = 3.0;
     146            0 :     const double x1 = params.rect.left() + margin;
     147            0 :     const double x2 = params.rect.right() - margin;
     148              : 
     149              :     // draw staff lines with middle line centered vertically on target
     150            0 :     double y = topLineDist;
     151            0 :     for (int i = 0; i < params.numStaffLines; ++i) {
     152            0 :         painter->drawLine(LineF(x1, y, x2, y));
     153            0 :         y += params.spatium;
     154              :     }
     155              : 
     156            0 :     painter->restore();
     157            0 :     return topLineDist;
     158            0 : }
        

Generated by: LCOV version 2.0-1