MuseScore/omr/omrview.cpp
Andres Fernandez de Prado 33dff96a20 This commit contains changes required for MuseScore to compile under MSVC with no warnings.
This commit contains changes required for MuseScore to compile under MSVC with no warnings.

MuseScore is being compiled with the /W4 setting (warning level 4), which is similar to -wall -wextra on clang. This generates lots of warnings on MSVC, mainly for non-standard constructs and for constructs which might be bugs or might lead to bugs.

Most warnings are in the following categories:
- Name hiding: a variable hides a variable with the same name on a larger scope (or a field, or a function parameter). This can easily lead to bugs, and it is a best practice to avoid hiding variable names (see recommendation ES.12 in the C++ Core Guidelines by Stroustrop & Sutter (http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-reuse : ES.12: Do not reuse names in nested scopes)
- Narrowing conversion: a numeric conversion results in loss of significant digits (for example, double -> float). The general recommendation is to use a cast to indicate this is designed behaviour.
- Unreachable code: in several instances, there is unreachable code. The unreachable code is commented out.
- (Potentially) uninitialized local variable. Just initialized the vars.
- foreach(,) -> for(:): this does not generate a warning per-se (only a few of these generate warnings due to name hiding), but changed in keeping with "MuseScore Coding Rules" (https://musescore.org/en/handbook/musescore-coding-rules#Loops), which tells explicitly "Use C++11's "for" instead of Qt's "foreach":" ... "If you happen to be fixing some code and see a "foreach", please change that loop into a "for"."

Most changes are in the categories indicated above. The next listing shows detailed changes for files which are *not* of the aforementioned types.

- all.h: Disable warning C4127 (conditional expression is constant - generated in Qt header file qvector.h)
- awl/aslider.h: unreachable code.
- awl/knob.cpp: name hiding
- awl/mslider.cpp: name hiding
- awl/slider.cpp: name hiding
- bww2mxml/parser.cpp: name hiding
- effects/compressor/compressor.cpp: narrowing conversion
- effects/zita1/zitagui.cpp: name hiding
- fluid/fluid.cpp: foreach replacement. Name hiding.
- fluid/mod.cpp: name hiding.
- fluid/sfont.cpp: foreach replacement. Name hiding. Initialize vars.
- fluid/voice.cpp: Name hiding.
- libmscore/accidental.cpp: Name hiding.
- libmscore/ambitus.cpp: Initialize vars.
- libmscore/barline.cpp: Name hiding. Unreachable code.
- libmscore/beam.cpp: Name hiding.
- libmscore/chordrest.cpp: Unreachable code.
- libmscore/scorefile.cpp: Name hiding.
- manual/genManual.cpp: Name hiding. foreach replacement.
- midi/midifile.cpp: Name hiding. Unreachable code.
- omr/importpdf.cpp: Name hiding. foreach replacement.
- omr/omr.cpp: Name hiding. foreach replacement.
- omr/omrpage.cpp: Name hiding. foreach replacement.
- omr/omrview.cpp: Name hiding. foreach replacement.
- synthesizer/event.cpp: Unreachable code.
- zerberus\channel.cpp: Narrowing conversion.
- zerberus\instrument.cpp: Name hiding.
- zerberus\sfz.cpp: Name hiding.
- zerberus\voice.h: Suppress warning C4201: "nonstandard extension used: nameless struct/union"
- zerberus\zerberus.cpp: Name hiding. Unreferenced parameter.
- zerberus\zerberusgui.cpp: Name hiding.
2018-08-03 09:15:42 +02:00

453 lines
14 KiB
C++

//=============================================================================
// MusE Reader
// Music Score Reader
// $Id$
//
// Copyright (C) 2010 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#include "mscore/globals.h"
#include "omrview.h"
#include "omr.h"
#include "libmscore/page.h"
#include "omrpage.h"
#include "libmscore/score.h"
#include "mscore/scoreview.h"
#include "libmscore/sym.h"
#include "libmscore/mscore.h"
namespace Ms {
//---------------------------------------------------------
// OmrView
//---------------------------------------------------------
OmrView::OmrView(ScoreView* sv, QWidget* parent)
: QWidget(parent)
{
setFocusPolicy(Qt::StrongFocus);
setAttribute(Qt::WA_InputMethodEnabled);
setAttribute(Qt::WA_KeyCompression);
setMouseTracking(true);
_omr = 0;
_scoreView = sv;
double m = .25;
_fotoMode = false;
_matrix = QTransform(m, 0.0, 0.0, m, 0.0, 0.0);
xoff = yoff = 0;
_showLines = false;
_showBarlines = true;
_showSlices = true;
_showStaves = true;
}
//---------------------------------------------------------
// setOmr
//---------------------------------------------------------
void OmrView::setOmr(Omr* s)
{
delete _omr;
_omr = s;
if (s == 0 || s->numPages() == 0) {
maxTiles = 0;
return;
}
int n = s->numPages();
OmrPage* page = _omr->page(0);
const QImage& i = page->image();
Score* score = _scoreView->score();
double mag = _omr->spatium() / score->spatium();
pageWidth = lrint(score->styleD(Sid::pageWidth) * mag * DPI);
int htiles = ((pageWidth + TILE_W - 1) / TILE_W);
pageWidth = htiles * TILE_W;
int vtiles = (i.height() + TILE_H - 1) / TILE_H;
maxTiles = n * htiles * vtiles;
}
//---------------------------------------------------------
// initTile
//---------------------------------------------------------
void OmrView::initTile(Tile* t)
{
int page1 = t->r.x() / pageWidth;
if (page1 < 0)
page1 = 0;
int n = _omr->numPages();
if (page1 >= n)
return;
t->page = _omr->page(page1);
t->pageNo = page1;
const QImage& i = t->page->image();
int xoffset = 0; // (pageWidth - i.width()) / 2;
int x = t->r.x() - (t->pageNo * pageWidth) - xoffset;
t->pm = QPixmap::fromImage(i.copy(x, t->r.y(), TILE_W, TILE_H));
}
//---------------------------------------------------------
// Tile
//---------------------------------------------------------
Tile::Tile()
: no(0), r(0, 0, TILE_W, TILE_H), pm(TILE_W, TILE_H)
{
}
//---------------------------------------------------------
// paintEvent
//---------------------------------------------------------
void OmrView::paintEvent(QPaintEvent* event)
{
if (_omr == 0)
return;
QPainter p(this);
p.setTransform(_matrix);
QRect r(event->rect());
//
// remove unused tiles
//
QRect rr = _matrix.inverted().mapRect(QRectF(r)).toRect();
rr.adjust(-1, -1, 2, 2);
QList<Tile*> nl;
for(Tile* t : usedTiles) {
if (t->r.intersects(rr))
nl.append(t);
else
freeTiles.append(t);
}
#if QT_VERSION >= 0x040800
usedTiles.swap(nl);
#else
QList<Tile*> tmp = nl;
nl = usedTiles;
usedTiles = tmp;
#endif
//
// add visible tiles
//
Score* score = _scoreView->score();
double sSpatium = score->spatium();
double spatium = _omr->spatium();
double mag = spatium / sSpatium;
int w = pageWidth;
int h = lrint(score->styleD(Sid::pageHeight) * mag * DPI);
int n = _omr->numPages();
int nx = (w * n) / TILE_W;
int ny = (h + TILE_H - 1) / TILE_H;
int y1 = rr.y() / TILE_H;
int y2 = (rr.y() + rr.height() + TILE_H - 1) / TILE_H;
int x1 = rr.x() / TILE_W;
int x2 = (rr.x() + rr.width() + TILE_W -1) / TILE_W;
if (x1 < 0)
x1 = 0;
if (y1 < 0)
y1 = 0;
if (x2 > nx)
x2 = nx;
if (y2 > ny)
y2 = ny;
for (int y = y1; y < y2; ++y) {
for (int x = x1; x < x2; ++x) {
int no = nx * y + x;
if (no < 0 || no >= maxTiles)
continue;
int i;
for (i = 0; i < usedTiles.size(); ++i) {
if (usedTiles[i]->no == no)
break;
}
if (i == usedTiles.size()) {
// create new tile
Tile* t = freeTiles.isEmpty() ? new Tile : freeTiles.pop();
t->no = no;
t->r = QRect(x * TILE_W, y * TILE_H, TILE_W, TILE_H);
initTile(t);
usedTiles.append(t);
}
}
}
int minPage = 9000;
int maxPage = 0;
for(const Tile* t : usedTiles) {
p.drawPixmap(t->r, t->pm);
if (t->pageNo < minPage)
minPage = t->pageNo;
if (t->pageNo > maxPage)
maxPage = t->pageNo;
}
for (int pageNo = minPage; pageNo <= maxPage; ++pageNo) {
OmrPage* page = _omr->page(pageNo);
p.save();
p.translate(w * pageNo, 0);
if (_showLines) {
p.setPen(QPen(QColor(255, 0, 0, 80), 1.0));
for(QLine l : page->sl())
p.drawLine(QLineF(l.x1()+.5, l.y1()+.5, l.x2()+.5, l.y2()+.5));
}
if (_showSlices) {
for(const QRect r1 : page->slices())
p.fillRect(r1, QBrush(QColor(0, 100, 100, 50)));
}
if (_showStaves) {
for(const OmrSystem& s : page->systems()) { // staves
for(const OmrStaff& r1 : s.staves())
p.fillRect(r1, QBrush(QColor(0, 0, 100, 50)));
}
}
for (const OmrSystem& system : page->systems()) {
if (_showBarlines) {
p.setPen(QPen(Qt::blue, 3.0));
for(const QLineF& l : system.barLines)
for(int w1 = 0; w1 < 10; w1++)
p.drawLine(l.x1()+w1, l.y1(), l.x2()+w1, l.y2() ); //add width to barline
}
for (const OmrStaff& staff : system.staves()) {
for (const OmrNote* n1 : staff.notes()) {
if (n1->sym == SymId::noteheadBlack)
p.setPen(QPen(QColor(255, 0, 0), 2.0));
else
p.setPen(QPen(QColor(0, 0, 255), 2.0));
p.drawRect(*n1);
}
}
}
p.restore();
}
if (fotoMode()) {
// TODO
p.setBrush(QColor(0, 0, 50, 50));
QPen pen(QColor(0, 0, 255));
// always 2 pixel width
qreal w1 = 2.0 / p.matrix().m11();
pen.setWidthF(w1);
p.setPen(pen);
p.drawRect(_foto);
}
}
//---------------------------------------------------------
// mousePressEvent
//---------------------------------------------------------
void OmrView::mousePressEvent(QMouseEvent* e)
{
startDrag = e->pos();
}
//---------------------------------------------------------
// mouseMoveEvent
//---------------------------------------------------------
void OmrView::mouseMoveEvent(QMouseEvent* e)
{
if (QApplication::mouseButtons()) {
QPoint delta = e->pos() - startDrag;
int dx = delta.x();
int dy = delta.y();
xoff += dx;
yoff += dy;
_matrix.setMatrix(_matrix.m11(), _matrix.m12(), _matrix.m13(), _matrix.m21(),
_matrix.m22(), _matrix.m23(), _matrix.dx()+dx, _matrix.dy()+dy, _matrix.m33());
scroll(dx, dy, QRect(0, 0, width(), height()));
startDrag = e->pos();
}
}
//---------------------------------------------------------
// setMag
//---------------------------------------------------------
void OmrView::setMag(double nmag)
{
qreal m = mag();
if (nmag == m)
return;
double deltamag = nmag / m;
_matrix.setMatrix(nmag, _matrix.m12(), _matrix.m13(), _matrix.m21(),
nmag, _matrix.m23(), _matrix.dx()*deltamag, _matrix.dy()*deltamag, _matrix.m33());
}
//---------------------------------------------------------
// zoom
//---------------------------------------------------------
void OmrView::zoom(int step, const QPoint& pos)
{
QTransform imatrix(_matrix.inverted());
QPointF p1 = imatrix.map(QPointF(pos));
double _scale = mag();
if (step > 0) {
for (int i = 0; i < step; ++i)
_scale *= 1.1;
}
else {
for (int i = 0; i < -step; ++i)
_scale /= 1.1;
}
if (_scale > 16.0)
_scale = 16.0;
else if (_scale < 0.05)
_scale = 0.05;
setMag(_scale);
QPointF p2 = imatrix.map(QPointF(pos));
QPointF p3 = p2 - p1;
int dx = lrint(p3.x() * _scale);
int dy = lrint(p3.y() * _scale);
_matrix.setMatrix(_matrix.m11(), _matrix.m12(), _matrix.m13(), _matrix.m21(),
_matrix.m22(), _matrix.m23(), _matrix.dx()+dx, _matrix.dy()+dy, _matrix.m33());
scroll(dx, dy, QRect(0, 0, width(), height()));
update();
}
//---------------------------------------------------------
// wheelEvent
//---------------------------------------------------------
void OmrView::wheelEvent(QWheelEvent* event)
{
if (event->modifiers() & Qt::ControlModifier) {
QApplication::sendPostedEvents(this, 0);
zoom(event->delta() / 120, event->pos());
return;
}
int dx = 0;
int dy = 0;
if (event->modifiers() & Qt::ShiftModifier || event->orientation() == Qt::Horizontal) {
//
// scroll horizontal
//
int n = width() / 10;
if (n < 2)
n = 2;
dx = event->delta() * n / 120;
}
else {
//
// scroll vertical
//
int n = height() / 10;
if (n < 2)
n = 2;
dy = event->delta() * n / 120;
}
_matrix.setMatrix(_matrix.m11(), _matrix.m12(), _matrix.m13(), _matrix.m21(),
_matrix.m22(), _matrix.m23(), _matrix.dx()+dx, _matrix.dy()+dy, _matrix.m33());
scroll(dx, dy, QRect(0, 0, width(), height()));
}
//---------------------------------------------------------
// setScale
//---------------------------------------------------------
void OmrView::setScale(double v)
{
double spatium = _omr->spatium();
setMag(v/spatium);
update();
}
//---------------------------------------------------------
// setOffset
//---------------------------------------------------------
void OmrView::setOffset(double x, double y)
{
Score* score = _omr->score();
double sSpatium = score->spatium() * _scoreView->matrix().m11();
double spatium = _omr->spatium() * _matrix.m11();
double nx = x / sSpatium * spatium + xoff;
double ny = y / sSpatium * spatium + yoff;
double ox = _matrix.dx();
double oy = _matrix.dy();
_matrix.setMatrix(_matrix.m11(), _matrix.m12(), _matrix.m13(), _matrix.m21(),
_matrix.m22(), _matrix.m23(), nx, ny, _matrix.m33());
scroll(ox-nx, oy-ny, QRect(0, 0, width(), height()));
update();
}
//---------------------------------------------------------
// contextMenuEvent
//---------------------------------------------------------
void OmrView::contextMenuEvent(QContextMenuEvent*)
{
printf("context menu\n");
}
//---------------------------------------------------------
// setShowBarlines
//---------------------------------------------------------
void OmrView::setShowBarlines(bool val)
{
_showBarlines = val;
update();
}
//---------------------------------------------------------
// setShowSlices
//---------------------------------------------------------
void OmrView::setShowSlices(bool val)
{
_showSlices = val;
update();
}
//---------------------------------------------------------
// setShowStaves
//---------------------------------------------------------
void OmrView::setShowStaves(bool val)
{
_showStaves = val;
update();
}
}