LCOV - code coverage report
Current view: top level - src/engraving/rendering/editmode - editmoderenderer.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 193 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) 2025 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 "editmoderenderer.h"
      23              : 
      24              : #include "draw/painter.h"
      25              : 
      26              : #include "iengravingconfiguration.h" // IWYU pragma: keep
      27              : #include "dom/engravingitem.h"
      28              : #include "dom/barline.h"
      29              : #include "dom/dynamic.h"
      30              : #include "dom/slurtie.h"
      31              : #include "dom/textbase.h"
      32              : #include "rendering/score/tdraw.h"
      33              : 
      34              : using namespace mu::engraving::rendering::editmode;
      35              : using namespace mu::engraving;
      36              : using namespace muse::draw;
      37              : 
      38            0 : void EditModeRenderer::drawItem(const EngravingItem* item, muse::draw::Painter* painter, const EditData& ed, double currentViewScaling,
      39              :                                 const PaintOptions& opt)
      40              : {
      41            0 :     switch (item->type()) {
      42            0 :     case ElementType::BAR_LINE:
      43            0 :         drawBarline(item_cast<const BarLine*>(item), painter, ed, currentViewScaling, opt);
      44            0 :         break;
      45            0 :     case ElementType::CAPO:
      46            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      47            0 :         break;
      48            0 :     case ElementType::DYNAMIC:
      49            0 :         drawDynamic(item_cast<const Dynamic*>(item), painter, ed, currentViewScaling, opt);
      50            0 :         break;
      51            0 :     case ElementType::EXPRESSION:
      52            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      53            0 :         break;
      54            0 :     case ElementType::FIGURED_BASS:
      55            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      56            0 :         break;
      57            0 :     case ElementType::FINGERING:
      58            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      59            0 :         break;
      60            0 :     case ElementType::GUITAR_BEND_TEXT:
      61            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      62            0 :         break;
      63            0 :     case ElementType::HARMONY:
      64            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      65            0 :         break;
      66            0 :     case ElementType::HARP_DIAGRAM:
      67            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      68            0 :         break;
      69            0 :     case ElementType::INSTRUMENT_CHANGE:
      70            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      71            0 :         break;
      72            0 :     case ElementType::INSTRUMENT_NAME:
      73            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      74            0 :         break;
      75            0 :     case ElementType::JUMP:
      76            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      77            0 :         break;
      78            0 :     case ElementType::LAISSEZ_VIB_SEGMENT:
      79            0 :         drawSlurTieSegment(item_cast<const SlurTieSegment*>(item), painter, ed, currentViewScaling, opt);
      80            0 :         break;
      81            0 :     case ElementType::LYRICS:
      82            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      83            0 :         break;
      84            0 :     case ElementType::MMREST_RANGE:
      85            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      86            0 :         break;
      87            0 :     case ElementType::MARKER:
      88            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      89            0 :         break;
      90            0 :     case ElementType::MEASURE_NUMBER:
      91            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      92            0 :         break;
      93            0 :     case ElementType::PARTIAL_TIE_SEGMENT:
      94            0 :         drawSlurTieSegment(item_cast<const SlurTieSegment*>(item), painter, ed, currentViewScaling, opt);
      95            0 :         break;
      96            0 :     case ElementType::PLAY_COUNT_TEXT:
      97            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
      98            0 :         break;
      99            0 :     case ElementType::PLAYTECH_ANNOTATION:
     100            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     101            0 :         break;
     102            0 :     case ElementType::REHEARSAL_MARK:
     103            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     104            0 :         break;
     105            0 :     case ElementType::SLUR_SEGMENT:
     106              :     case ElementType::TIE_SEGMENT:
     107              :     case ElementType::HAMMER_ON_PULL_OFF_SEGMENT:
     108              :     case ElementType::TAPPING_HALF_SLUR_SEGMENT:
     109            0 :         drawSlurTieSegment(item_cast<const SlurTieSegment*>(item), painter, ed, currentViewScaling, opt);
     110            0 :         break;
     111            0 :     case ElementType::STAFF_TEXT:
     112              :     case ElementType::STAVE_SHARING_LABEL:
     113            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     114            0 :         break;
     115            0 :     case ElementType::STICKING:
     116            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     117            0 :         break;
     118            0 :     case ElementType::STRING_TUNINGS:
     119            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     120            0 :         break;
     121            0 :     case ElementType::SYSTEM_TEXT:
     122            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     123            0 :         break;
     124            0 :     case ElementType::TEMPO_TEXT:
     125            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     126            0 :         break;
     127            0 :     case ElementType::TEXT:
     128            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     129            0 :         break;
     130            0 :     case ElementType::TRIPLET_FEEL:
     131            0 :         drawTextBase(item_cast<const TextBase*>(item), painter, currentViewScaling, opt);
     132            0 :         break;
     133            0 :     default:
     134            0 :         drawEngravingItem(item, painter, ed, currentViewScaling, opt);
     135              :     }
     136            0 : }
     137              : 
     138            0 : void EditModeRenderer::drawEngravingItem(const EngravingItem* item, muse::draw::Painter* painter, const EditData& ed,
     139              :                                          double currentViewScaling, const PaintOptions& opt)
     140              : {
     141              :     UNUSED(currentViewScaling);
     142              : 
     143            0 :     Pen pen(item->configuration()->displayedDefaultColor(opt.invertColors), 0.0);
     144            0 :     painter->setPen(pen);
     145            0 :     for (int i = 0; i < ed.grips; ++i) {
     146            0 :         if (Grip(i) == ed.curGrip) {
     147            0 :             painter->setBrush(item->configuration()->scoreGreyColor());
     148              :         } else {
     149            0 :             painter->setBrush(BrushStyle::NoBrush);
     150              :         }
     151            0 :         painter->drawRect(ed.grip[i]);
     152              :     }
     153            0 : }
     154              : 
     155            0 : void EditModeRenderer::drawBarline(const BarLine* item, muse::draw::Painter* painter, const EditData& ed, double currentViewScaling,
     156              :                                    const PaintOptions& opt)
     157              : {
     158            0 :     drawEngravingItem(item, painter, ed, currentViewScaling, opt);
     159              : 
     160            0 :     const BarLineEditData* bed = static_cast<BarLineEditData*>(ed.getData(item).get());
     161            0 :     BarLine::LayoutData* ldata = const_cast<BarLine::LayoutData*>(item->ldata());
     162            0 :     ldata->y1 += bed->yoff1;
     163            0 :     ldata->y2 += bed->yoff2;
     164            0 :     PointF pos(item->canvasPos());
     165            0 :     painter->translate(pos);
     166              : 
     167            0 :     score::TDraw::drawItem(item, painter, opt);
     168              : 
     169            0 :     ldata->y1 -= bed->yoff1;
     170            0 :     ldata->y2 -= bed->yoff2;
     171            0 :     painter->translate(-pos);
     172            0 : }
     173              : 
     174            0 : void EditModeRenderer::drawDynamic(const Dynamic* item, muse::draw::Painter* painter, const EditData& ed, double currentViewScaling,
     175              :                                    const PaintOptions& opt)
     176              : {
     177            0 :     if (item->cursor() && item->cursor()->editing()) {
     178            0 :         drawTextBase(item, painter, currentViewScaling, opt);
     179            0 :         return;
     180              :     }
     181              : 
     182            0 :     drawEngravingItem(item, painter, ed, currentViewScaling, opt);
     183              : }
     184              : 
     185            0 : void EditModeRenderer::drawSlurTieSegment(const SlurTieSegment* item, muse::draw::Painter* painter, const EditData& ed,
     186              :                                           double currentViewScaling, const PaintOptions& opt)
     187              : {
     188            0 :     PolygonF polygon(7);
     189            0 :     polygon[0] = PointF(ed.grip[int(Grip::START)].center());
     190            0 :     polygon[1] = PointF(ed.grip[int(Grip::BEZIER1)].center());
     191            0 :     polygon[2] = PointF(ed.grip[int(Grip::SHOULDER)].center());
     192            0 :     polygon[3] = PointF(ed.grip[int(Grip::BEZIER2)].center());
     193            0 :     polygon[4] = PointF(ed.grip[int(Grip::END)].center());
     194            0 :     polygon[5] = PointF(ed.grip[int(Grip::DRAG)].center());
     195            0 :     polygon[6] = PointF(ed.grip[int(Grip::START)].center());
     196            0 :     painter->setPen(Pen(item->configuration()->scoreGreyColor(), 0.0));
     197            0 :     painter->drawPolyline(polygon);
     198              : 
     199            0 :     drawEngravingItem(item, painter, ed, currentViewScaling, opt);
     200            0 : }
     201              : 
     202            0 : static void drawTextBaseSelection(const TextBase* item, muse::draw::Painter* painter, const RectF& r)
     203              : {
     204            0 :     painter->save();
     205            0 :     Brush bg(item->configuration()->selectionColor());
     206            0 :     painter->setCompositionMode(CompositionMode::HardLight);
     207            0 :     painter->setBrush(bg);
     208            0 :     painter->setNoPen();
     209            0 :     painter->drawRect(r);
     210            0 :     painter->restore();
     211            0 : }
     212              : 
     213            0 : void EditModeRenderer::drawTextBase(const TextBase* item, muse::draw::Painter* painter, double currentViewScaling,
     214              :                                     const PaintOptions& opt)
     215              : {
     216            0 :     PointF pos(item->canvasPos());
     217            0 :     painter->translate(pos);
     218              : 
     219            0 :     const TextCursor* cursor = item->cursor();
     220            0 :     const TextBase::LayoutData* ldata = item->ldata();
     221            0 :     IF_ASSERT_FAILED(ldata) {
     222            0 :         return;
     223              :     }
     224              : 
     225            0 :     if (cursor->hasSelection()) {
     226            0 :         painter->setBrush(BrushStyle::NoBrush);
     227            0 :         painter->setPen(item->textColor(opt));
     228            0 :         size_t r1 = cursor->selectLine();
     229            0 :         size_t r2 = cursor->row();
     230            0 :         size_t c1 = cursor->selectColumn();
     231            0 :         size_t c2 = cursor->column();
     232              : 
     233            0 :         TextBase::sort(r1, c1, r2, c2);
     234            0 :         size_t row = 0;
     235            0 :         for (const TextBlock& t : ldata->blocks) {
     236            0 :             if (row >= r1 && row <= r2) {
     237            0 :                 RectF br;
     238            0 :                 if (row == r1 && r1 == r2) {
     239            0 :                     br = t.boundingRect(static_cast<int>(c1), static_cast<int>(c2), item);
     240            0 :                 } else if (row == r1) {
     241            0 :                     br = t.boundingRect(static_cast<int>(c1), static_cast<int>(t.columns()), item);
     242            0 :                 } else if (row == r2) {
     243            0 :                     br = t.boundingRect(0, static_cast<int>(c2), item);
     244              :                 } else {
     245            0 :                     br = t.boundingRect();
     246              :                 }
     247            0 :                 br.translate(0.0, t.y());
     248            0 :                 drawTextBaseSelection(item, painter, br);
     249              :             }
     250            0 :             ++row;
     251              :         }
     252              :     }
     253            0 :     painter->setBrush(item->curColor(opt));
     254            0 :     Pen pen(item->curColor(opt));
     255            0 :     pen.setJoinStyle(PenJoinStyle::MiterJoin);
     256            0 :     painter->setPen(pen);
     257              : 
     258            0 :     if (cursor->visible()) {
     259            0 :         painter->drawRect(cursor->cursorRect());
     260              :     }
     261              : 
     262            0 :     painter->translate(-pos);
     263            0 :     painter->setPen(Pen(item->configuration()->frameColor(), 2.0 / currentViewScaling)); // 2 pixel pen size
     264            0 :     painter->setBrush(BrushStyle::NoBrush);
     265              : 
     266            0 :     double m = item->spatium();
     267            0 :     RectF r = item->canvasBoundingRect().adjusted(-m, -m, m, m);
     268              : 
     269            0 :     painter->drawRect(r);
     270            0 : }
     271              : 
     272            0 : void EditModeRenderer::draw(const TextBlock& textBlock, const TextBase* item, muse::draw::Painter* painter)
     273              : {
     274            0 :     painter->translate(0.0, textBlock.y());
     275            0 :     for (const TextFragment& f : textBlock.fragments()) {
     276            0 :         draw(f, item, painter);
     277              :     }
     278            0 :     painter->translate(0.0, -textBlock.y());
     279            0 : }
     280              : 
     281            0 : void EditModeRenderer::draw(const TextFragment& textFragment, const TextBase* item, muse::draw::Painter* painter)
     282              : {
     283            0 :     painter->setFont(textFragment.font(item));
     284            0 :     painter->drawText(textFragment.pos, textFragment.text);
     285            0 : }
        

Generated by: LCOV version 2.0-1