Skip to content

Commit

Permalink
fix #31856: add option to trim whitespace from exported PNG
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcSabatella committed Dec 9, 2014
1 parent 76d6063 commit f430751
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 7 deletions.
30 changes: 30 additions & 0 deletions libmscore/element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,36 @@ bool Element::isText() const
;
}

//---------------------------------------------------------
// isPrintable
//---------------------------------------------------------

bool Element::isPrintable() const
{
switch (type()) {
case Element::Type::PAGE:
case Element::Type::SYSTEM:
case Element::Type::MEASURE:
case Element::Type::SEGMENT:
case Element::Type::VBOX:
case Element::Type::HBOX:
case Element::Type::TBOX:
case Element::Type::FBOX:
case Element::Type::SPACER:
case Element::Type::SHADOW_NOTE:
case Element::Type::LASSO:
case Element::Type::RUBBERBAND:
case Element::Type::ELEMENT_LIST:
case Element::Type::STAFF_LIST:
case Element::Type::MEASURE_LIST:
case Element::Type::SELECTION:
case Element::Type::LAYOUT:
return false;
default:
return true;
}
}

//---------------------------------------------------------
// findMeasure
//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions libmscore/element.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ class Element : public QObject {
qreal magS() const;

bool isText() const;
bool isPrintable() const;
virtual bool isSpanner() const { return false; }
virtual bool isSpannerSegment() const { return false; }

Expand Down
31 changes: 31 additions & 0 deletions libmscore/page.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -856,5 +856,36 @@ qreal Page::rm() const
return ((!pf->twosided() || isOdd()) ? pf->oddRightMargin() : pf->evenRightMargin()) * MScore::DPI;
}

//---------------------------------------------------------
// tbbox
// calculates and returns smallest rectangle containing all (visible) page elements
//---------------------------------------------------------

QRectF Page::tbbox()
{
qreal x1 = width();
qreal x2 = 0.0;
qreal y1 = height();
qreal y2 = 0.0;
const QList<const Element*> el = elements();
for (const Element* e : el) {
if (e == this || !e->isPrintable())
continue;
QRectF ebbox = e->pageBoundingRect();
if (ebbox.left() < x1)
x1 = ebbox.left();
if (ebbox.right() > x2)
x2 = ebbox.right();
if (ebbox.top() < y1)
y1 = ebbox.top();
if (ebbox.bottom() > y2)
y2 = ebbox.bottom();
}
if (x1 < x2 && y1 < y2)
return QRectF(x1, y1, x2 - x1, y2 - y1);
else
return abbox();
}

}

1 change: 1 addition & 0 deletions libmscore/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class Page : public Element {
MeasureBase* pos2measure(const QPointF&, int* staffIdx, int* pitch,
Segment**, QPointF* offset) const;
QList<const Element*> elements(); ///< list of visible elements
QRectF tbbox(); // tight bounding box, excluding white space
};

extern const PaperSize paperSizes[];
Expand Down
66 changes: 60 additions & 6 deletions mscore/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2161,22 +2161,59 @@ void MuseScore::addImage(Score* score, Element* e)
score->undoAddElement(s);
}

#if 0
//---------------------------------------------------------
// trim
// returns copy of source with whitespace trimmed and margin added
//---------------------------------------------------------

static QRect trim(QImage source, int margin)
{
int w = source.width();
int h = source.height();
int x1 = w;
int x2 = 0;
int y1 = h;
int y2 = 0;
for (int x = 0; x < w; ++x) {
for (int y = 0; y < h; ++y) {
QRgb c = source.pixel(x, y);
if (c != 0 && c != 0xffffffff) {
if (x < x1)
x1 = x;
if (x > x2)
x2 = x;
if (y < y1)
y1 = y;
if (y > y2)
y2 = y;
}
}
}
int x = qMax(x1 - margin, 0);
int y = qMax(y1 - margin, 0);
w = qMin(w, x2 + 1 + margin) - x;
h = qMin(h, y2 + 1 + margin) - y;
return QRect(x, y, w, h);
}
#endif

//---------------------------------------------------------
// savePng
// return true on success
//---------------------------------------------------------

bool MuseScore::savePng(Score* score, const QString& name)
{
return savePng(score, name, false, true, converterDpi, QImage::Format_ARGB32_Premultiplied );
return savePng(score, name, false, preferences.pngTransparent, converterDpi, trimMargin, QImage::Format_ARGB32_Premultiplied);
}

//---------------------------------------------------------
// savePng with options
// return true on success
//---------------------------------------------------------

bool MuseScore::savePng(Score* score, const QString& name, bool screenshot, bool transparent, double convDpi, QImage::Format format)
bool MuseScore::savePng(Score* score, const QString& name, bool screenshot, bool transparent, double convDpi, int trimMargin, QImage::Format format)
{
bool rv = true;
score->setPrinting(!screenshot); // dont print page break symbols etc.
Expand All @@ -2196,7 +2233,13 @@ bool MuseScore::savePng(Score* score, const QString& name, bool screenshot, bool
for (int pageNumber = 0; pageNumber < pages; ++pageNumber) {
Page* page = pl.at(pageNumber);

QRectF r = page->abbox();
QRectF r;
if (trimMargin >= 0) {
QMarginsF margins(trimMargin, trimMargin, trimMargin, trimMargin);
r = page->tbbox() + margins;
}
else
r = page->abbox();
int w = lrint(r.width() * convDpi / MScore::DPI);
int h = lrint(r.height() * convDpi / MScore::DPI);

Expand All @@ -2208,10 +2251,11 @@ bool MuseScore::savePng(Score* score, const QString& name, bool screenshot, bool

double mag = convDpi / MScore::DPI;
QPainter p(&printer);

p.setRenderHint(QPainter::Antialiasing, true);
p.setRenderHint(QPainter::TextAntialiasing, true);
p.scale(mag, mag);
if (trimMargin >= 0)
p.translate(-r.topLeft());

QList<const Element*> pel = page->elements();
qStableSort(pel.begin(), pel.end(), elementLessThan);
Expand Down Expand Up @@ -2378,8 +2422,16 @@ bool MuseScore::saveSvg(Score* score, const QString& saveName)
const PageFormat* pf = cs->pageFormat();
double mag = converterDpi / MScore::DPI;

qreal w = pf->width() * MScore::DPI * score->pages().size();
qreal h = pf->height() * MScore::DPI;
QRectF r;
if (trimMargin >= 0 && score->npages() == 1) {
QMarginsF margins(trimMargin, trimMargin, trimMargin, trimMargin);
r = score->pages().first()->tbbox() + margins;
}
else
r = QRectF(0, 0, pf->width() * MScore::DPI * score->pages().size(), pf->height() * MScore::DPI);
qreal w = r.width();
qreal h = r.height();

printer.setSize(QSize(w * mag, h * mag));
printer.setViewBox(QRectF(0.0, 0.0, w * mag, h * mag));

Expand All @@ -2389,6 +2441,8 @@ bool MuseScore::saveSvg(Score* score, const QString& saveName)
p.setRenderHint(QPainter::Antialiasing, true);
p.setRenderHint(QPainter::TextAntialiasing, true);
p.scale(mag, mag);
if (trimMargin >= 0 && score->npages() == 1)
p.translate(-r.topLeft());

foreach (Page* page, score->pages()) {
QList<const Element*> pel = page->elements();
Expand Down
12 changes: 12 additions & 0 deletions mscore/fotomode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,9 @@ void ScoreView::fotoContextPopup(QContextMenuEvent* ev)
bgAction->setData("set-bg");

popup->addSeparator();
a = new QAction(tr("Auto-resize to page"), this);
a->setData("resizePage");
popup->addAction(a);
for (int i = 0; i < 4; ++i) {
a = new QAction(qApp->translate("fotomode", resizeEntry[i].text), this);
a->setData(resizeEntry[i].label);
Expand Down Expand Up @@ -640,6 +643,15 @@ void ScoreView::fotoContextPopup(QContextMenuEvent* ev)
preferences.dirty = true;
}
}
else if (cmd == "resizePage") {
QRectF r = _foto->rect();
Page* page = point2page(r.center());
if (page) {
r = page->tbbox().translated(page->canvasPos());
_foto->setRect(r);
updateGrips();
}
}
else if (cmd.startsWith("resize")) {
QString size = QSettings().value(QString("fotoSize%1").arg(cmd[6]), "50x40").toString();
qreal w = size.split("x")[0].toDouble();
Expand Down
1 change: 1 addition & 0 deletions mscore/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern bool midiOutputTrace; ///< debug option: dump midi output
extern bool converterMode;
extern double converterDpi;
extern double guiScaling;
extern int trimMargin;

//---------------------------------------------------------
// MsWidget
Expand Down
7 changes: 7 additions & 0 deletions mscore/musescore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ static bool pluginMode = false;
static bool startWithNewScore = false;
double converterDpi = 0;
double guiScaling = 1.0;
int trimMargin = -1;

QString mscoreGlobalShare;

Expand Down Expand Up @@ -1248,6 +1249,7 @@ static void usage()
" -O dump midi output\n"
" -o file export to 'file'; format depends on file extension\n"
" -r dpi set output resolution for image export\n"
" -T margin trim exported image with specified margin (in pixels)\n"
" -x factor set scaling factor for GUI elements\n"
" -S style load style file\n"
" -p name execute named plugin\n"
Expand Down Expand Up @@ -4592,6 +4594,11 @@ int main(int argc, char* av[])
usage();
converterDpi = argv.takeAt(i + 1).toDouble();
break;
case 'T':
if (argv.size() - i < 2)
usage();
trimMargin = argv.takeAt(i + 1).toInt();
break;
case 'x':
if (argv.size() - i < 2)
usage();
Expand Down
2 changes: 1 addition & 1 deletion mscore/musescore.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
bool saveSelection(Score*);
void addImage(Score*, Element*);

bool savePng(Score*, const QString& name, bool screenshot, bool transparent, double convDpi, QImage::Format format);
bool savePng(Score*, const QString& name, bool screenshot, bool transparent, double convDpi, int trimMargin, QImage::Format format);
bool saveAudio(Score*, const QString& name);
bool saveMp3(Score*, const QString& name);
bool saveSvg(Score*, const QString& name);
Expand Down

0 comments on commit f430751

Please sign in to comment.