Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/rism-digital/verovio int…
Browse files Browse the repository at this point in the history
…o develop

# Conflicts:
#	include/vrv/horizontalaligner.h
#	src/horizontalaligner.cpp
  • Loading branch information
lpugin committed Oct 11, 2024
2 parents cac16d9 + d11c268 commit 66776c2
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 34 deletions.
8 changes: 7 additions & 1 deletion include/vrv/castofffunctor.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,20 @@ class CastOffPagesFunctor : public DocFunctor {
protected:
//
private:
//
/*
* Returns the available height for system drawing on the current page
*/
int GetAvailableDrawingHeight() const;

public:
//
private:
// The page we are taking the content from
Page *m_contentPage;
// The current page
Page *m_currentPage;
// Indicates whether the current page is the first
bool m_firstCastOffPage;
// The cumulated shift (m_drawingYRel of the first system of the current page)
int m_shift;
// The page heights
Expand Down
2 changes: 1 addition & 1 deletion include/vrv/doc.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ class Doc : public Object {
* Extract a timemap from the document to a JSON string.
* Run trough all the layers and fill the timemap file content.
*/
bool ExportTimemap(std::string &output, bool includeRests, bool includeMeasures);
bool ExportTimemap(std::string &output, bool includeRests, bool includeMeasures, bool useFractions);

/**
* Extract expansionMap from the document to JSON string.
Expand Down
16 changes: 12 additions & 4 deletions include/vrv/timemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@

//----------------------------------------------------------------------------

#include "horizontalaligner.h"

//----------------------------------------------------------------------------

#include "jsonxx.h"

namespace vrv {

class Object;
Expand All @@ -28,7 +34,7 @@ class Object;
*/
struct TimemapEntry {
double tempo = -1000.0;
double qstamp;
double tstamp;
std::vector<std::string> notesOn;
std::vector<std::string> notesOff;
std::vector<std::string> restsOn;
Expand Down Expand Up @@ -59,20 +65,22 @@ class Timemap {
/**
* Return (and possibly add) an entry for the given time.
*/
TimemapEntry &GetEntry(double time) { return m_map[time]; }
TimemapEntry &GetEntry(const Fraction &time) { return m_map[time]; }

/**
* Write the current timemap to a JSON string
*/
void ToJson(std::string &output, bool includetRests, bool includetMeasures);
void ToJson(std::string &output, bool includeRests, bool includeMeasures, bool useFractions);

static jsonxx::Array ToArray(const Fraction &fraction);

private:
//
public:
//
private:
/** The map with time values as keys */
std::map<double, TimemapEntry> m_map;
std::map<Fraction, TimemapEntry> m_map;

}; // class Timemap

Expand Down
8 changes: 6 additions & 2 deletions libmei/addons/att.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ std::string Att::StrToStr(std::string str) const

std::string Att::DblToStr(double data) const
{
return StringFormat("%f", data);
std::stringstream sstream;
sstream << round(data * 10000.0) / 10000.0;
return sstream.str();
}

std::string Att::IntToStr(int data) const
Expand Down Expand Up @@ -365,7 +367,9 @@ data_KEYSIGNATURE Att::StrToKeysignature(const std::string &value, bool logWarni

std::string Att::MeasurebeatToStr(data_MEASUREBEAT data) const
{
return StringFormat("%dm+%.4f", data.first, data.second);
std::stringstream sstream;
sstream << data.first << "m+" << round(data.second * 10000.0) / 10000.0;
return sstream.str();
}

data_MEASUREBEAT Att::StrToMeasurebeat(std::string value, bool) const
Expand Down
28 changes: 16 additions & 12 deletions src/castofffunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ CastOffPagesFunctor::CastOffPagesFunctor(Page *contentPage, Doc *doc, Page *curr
{
m_contentPage = contentPage;
m_currentPage = currentPage;
m_shift = 0;
m_firstCastOffPage = true;
m_shift = VRV_UNSET;
m_pageHeight = 0;
m_pgHeadHeight = 0;
m_pgFootHeight = 0;
Expand Down Expand Up @@ -341,19 +342,16 @@ FunctorCode CastOffPagesFunctor::VisitScore(Score *score)

FunctorCode CastOffPagesFunctor::VisitSystem(System *system)
{
int currentShift = m_shift;
// We use m_pageHeadHeight to check if we have passed the first page already
if (m_pgHeadHeight != VRV_UNSET) {
currentShift += m_pgHeadHeight + m_pgFootHeight;
}
else {
currentShift += m_pgHead2Height + m_pgFoot2Height;
// Check if this is the first system
if (m_shift == VRV_UNSET) {
m_shift = system->GetDrawingYRel();
}

const int systemMaxPerPage = m_doc->GetOptions()->m_systemMaxPerPage.GetValue();
const int systemChildCount = m_currentPage->GetChildCount(SYSTEM);
if ((systemMaxPerPage && (systemMaxPerPage == systemChildCount))
|| ((systemChildCount > 0) && (system->GetDrawingYRel() - system->GetHeight() - currentShift < 0))) {
|| ((systemChildCount > 0)
&& (m_shift - system->GetDrawingYRel() + system->GetHeight() > this->GetAvailableDrawingHeight()))) {
// If this is the last system in the list, it doesn't fit the page and it's a leftover system (has just one
// measure) => add the system content to the previous system
Object *nextSystem = m_contentPage->GetNext(system, SYSTEM);
Expand All @@ -367,11 +365,10 @@ FunctorCode CastOffPagesFunctor::VisitSystem(System *system)
}

m_currentPage = new Page();
// Use VRV_UNSET value as a flag
m_pgHeadHeight = VRV_UNSET;
assert(m_doc->GetPages());
m_doc->GetPages()->AddChild(m_currentPage);
m_shift = system->GetDrawingYRel() - m_pageHeight;
m_shift = system->GetDrawingYRel();
m_firstCastOffPage = false;
}

// First add all pending objects
Expand All @@ -391,6 +388,13 @@ FunctorCode CastOffPagesFunctor::VisitSystem(System *system)
return FUNCTOR_SIBLINGS;
}

int CastOffPagesFunctor::GetAvailableDrawingHeight() const
{
const int pageHeadAndFootHeight
= m_firstCastOffPage ? (m_pgHeadHeight + m_pgFootHeight) : (m_pgHead2Height + m_pgFoot2Height);
return m_pageHeight - pageHeadAndFootHeight;
}

//----------------------------------------------------------------------------
// CastOffEncodingFunctor
//----------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions src/doc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ void Doc::ExportMIDI(smf::MidiFile *midiFile)
}
}

bool Doc::ExportTimemap(std::string &output, bool includeRests, bool includeMeasures)
bool Doc::ExportTimemap(std::string &output, bool includeRests, bool includeMeasures, bool useFractions)
{
if (!this->HasTimemap()) {
// generate MIDI timemap before progressing
Expand All @@ -558,7 +558,7 @@ bool Doc::ExportTimemap(std::string &output, bool includeRests, bool includeMeas
generateTimemap.SetCueExclusion(this->GetOptions()->m_midiNoCue.GetValue());
this->Process(generateTimemap);

timemap.ToJson(output, includeRests, includeMeasures);
timemap.ToJson(output, includeRests, includeMeasures, useFractions);

return true;
}
Expand Down
12 changes: 6 additions & 6 deletions src/midifunctor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,11 +955,11 @@ void GenerateTimemapFunctor::AddTimemapEntry(const Object *object)

/*********** start values ***********/

TimemapEntry &startEntry = m_timemap->GetEntry(realTimeStart);
TimemapEntry &startEntry = m_timemap->GetEntry(scoreTimeStart);

// Should check if value for realTimeStart already exists and if so, then
// ensure that it is equal to scoreTimeStart:
startEntry.qstamp = scoreTimeStart.ToDouble();
startEntry.tstamp = realTimeStart;

// Store the element ID in list to turn on at given time - note or rest
if (!isRest) startEntry.notesOn.push_back(object->GetID());
Expand All @@ -970,11 +970,11 @@ void GenerateTimemapFunctor::AddTimemapEntry(const Object *object)

/*********** end values ***********/

TimemapEntry &endEntry = m_timemap->GetEntry(realTimeEnd);
TimemapEntry &endEntry = m_timemap->GetEntry(scoreTimeEnd);

// Should check if value for realTimeEnd already exists and if so, then
// ensure that it is equal to scoreTimeEnd:
endEntry.qstamp = scoreTimeEnd.ToDouble();
endEntry.tstamp = realTimeEnd;

// Store the element ID in list to turn off at given time - notes or rest
if (!isRest) endEntry.notesOff.push_back(object->GetID());
Expand All @@ -989,11 +989,11 @@ void GenerateTimemapFunctor::AddTimemapEntry(const Object *object)
Fraction scoreTimeStart = m_scoreTimeOffset;
double realTimeStart = round(m_realTimeOffsetMilliseconds);

TimemapEntry &startEntry = m_timemap->GetEntry(realTimeStart);
TimemapEntry &startEntry = m_timemap->GetEntry(scoreTimeStart);

// Should check if value for realTimeStart already exists and if so, then
// ensure that it is equal to scoreTimeStart:
startEntry.qstamp = scoreTimeStart.ToDouble();
startEntry.tstamp = realTimeStart;

// Add the measureOn
startEntry.measureOn = measure->GetID();
Expand Down
23 changes: 18 additions & 5 deletions src/timemap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,22 @@ void Timemap::Reset()
m_map.clear();
}

void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasures)
void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasures, bool useFractions)
{
double currentTempo = -1000.0;
double newTempo;

jsonxx::Array timemap;

for (auto &[tstamp, entry] : m_map) {
for (auto &[qstamp, entry] : m_map) {
jsonxx::Object o;
o << "tstamp" << tstamp;
o << "qstamp" << entry.qstamp;
if (useFractions) {
o << "qfrac" << Timemap::ToArray(qstamp);
}
else {
o << "qstamp" << qstamp.ToDouble();
}
o << "tstamp" << entry.tstamp;

// on / off
if (!entry.notesOn.empty()) {
Expand Down Expand Up @@ -80,7 +85,7 @@ void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasure
newTempo = entry.tempo;
if (newTempo != currentTempo) {
currentTempo = newTempo;
o << "tempo" << std::to_string(currentTempo);
o << "tempo" << currentTempo;
}
}

Expand All @@ -94,4 +99,12 @@ void Timemap::ToJson(std::string &output, bool includeRests, bool includeMeasure
output = timemap.json();
}

jsonxx::Array Timemap::ToArray(const Fraction &fraction)
{
jsonxx::Array array;
array << fraction.GetNumerator();
array << fraction.GetDenominator();
return array;
}

} // namespace vrv
4 changes: 3 additions & 1 deletion src/toolkit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,7 @@ std::string Toolkit::RenderToTimemap(const std::string &jsonOptions)
{
bool includeMeasures = false;
bool includeRests = false;
bool useFractions = false;

jsonxx::Object json;

Expand All @@ -1811,13 +1812,14 @@ std::string Toolkit::RenderToTimemap(const std::string &jsonOptions)
if (json.has<jsonxx::Boolean>("includeMeasures"))
includeMeasures = json.get<jsonxx::Boolean>("includeMeasures");
if (json.has<jsonxx::Boolean>("includeRests")) includeRests = json.get<jsonxx::Boolean>("includeRests");
if (json.has<jsonxx::Boolean>("useFractions")) useFractions = json.get<jsonxx::Boolean>("useFractions");
}
}

this->ResetLogBuffer();

std::string output;
m_doc.ExportTimemap(output, includeRests, includeMeasures);
m_doc.ExportTimemap(output, includeRests, includeMeasures, useFractions);
return output;
}

Expand Down

0 comments on commit 66776c2

Please sign in to comment.