From e62514de70d8365c32e8dbee2ee4086b079a0c80 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 11 Mar 2015 20:00:19 +0000 Subject: [PATCH 01/68] Code comments --- include/vrv/chord.h | 4 +--- include/vrv/mensur.h | 6 +++++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/vrv/chord.h b/include/vrv/chord.h index 1cec3882677..577f5617f0e 100644 --- a/include/vrv/chord.h +++ b/include/vrv/chord.h @@ -49,6 +49,7 @@ class Chord: public LayerElement, public ObjectListInterface, public DurationInt virtual ~Chord(); virtual void Reset(); virtual std::string GetClassName( ) { return "Chord"; }; + ///@} /** * Add an element (only note supported) to a chord. @@ -58,8 +59,6 @@ class Chord: public LayerElement, public ObjectListInterface, public DurationInt virtual void FilterList( ListOfObjects *childlist ); void GetYExtremes(int initial, int *yMax, int *yMin); - - ///@} //----------// // Functors // @@ -70,7 +69,6 @@ class Chord: public LayerElement, public ObjectListInterface, public DurationInt */ virtual int PrepareTieAttr( ArrayPtrVoid params ); - /** * See Object::PrepareTieAttr */ diff --git a/include/vrv/mensur.h b/include/vrv/mensur.h index af850350708..3b52216ba39 100644 --- a/include/vrv/mensur.h +++ b/include/vrv/mensur.h @@ -32,7 +32,11 @@ class Mensur: public LayerElement, public AttSlashcount { public: - // constructors and destructors + /** + * @name Constructors, destructors, and other standard methods + * Reset method reset all attribute classes. + */ + ///@{ Mensur(); Mensur( MensurAttr *mensurAttr ); virtual ~Mensur(); From d03536a0c9415dfad5449ad782558e3f1cbe6154 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Wed, 11 Mar 2015 16:04:12 -0400 Subject: [PATCH 02/68] WIP: slurs drawn for chords, albeit incorrectly view_page::DrawTieOrSlur accepts chords in its assertions --- src/view_page.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/view_page.cpp b/src/view_page.cpp index bcfc81f2834..8e4d73a0e04 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -929,31 +929,35 @@ void View::DrawTieOrSlur( DeviceContext *dc, MeasureElement *element, int x1, in // but then we have to take in account (1) beams (2) stemmed and non stemmed notes tied together y1 = note1->GetDrawingY(); y2 = note2->GetDrawingY(); - assert(dynamic_cast(note1)); // for now we only look at the first note - needs to be improved // m_drawingStemDir it not set properly in beam - needs to be fixed. - noteStemDir = dynamic_cast(note1)->m_drawingStemDir; + if (dynamic_cast(note1)) noteStemDir = dynamic_cast(note1)->m_drawingStemDir; + else if (dynamic_cast(note1)) noteStemDir = dynamic_cast(note1)->GetDrawingStemDir(); + else assert(false); } // This is the case when the tie is split over two system of two pages. // In this case, we are now drawing its beginning to the end of the measure (i.e., the last aligner) else if ( spanningType == SPANNING_START ) { y1 = y2 = note1->GetDrawingY(); - assert(dynamic_cast(note1)); - noteStemDir = dynamic_cast(note1)->m_drawingStemDir; + // m_drawingStemDir it not set properly in beam - needs to be fixed. + if (dynamic_cast(note1)) noteStemDir = dynamic_cast(note1)->m_drawingStemDir; + else if (dynamic_cast(note1)) noteStemDir = dynamic_cast(note1)->GetDrawingStemDir(); + else assert(false); } // Now this is the case when the tie is split but we are drawing the end of it else if ( spanningType == SPANNING_END ) { y1 = y2 = note2->GetDrawingY(); x2 = note2->GetDrawingX(); - assert(dynamic_cast(note2)); - noteStemDir = dynamic_cast(note2)->m_drawingStemDir; + if (dynamic_cast(note2)) noteStemDir = dynamic_cast(note2)->m_drawingStemDir; + else if (dynamic_cast(note2)) noteStemDir = dynamic_cast(note2)->GetDrawingStemDir(); + else assert(false); } // Finally else { - LogDebug("Slur accross an entire system is not supported"); + LogDebug("Slur across an entire system is not supported"); } - assert( dynamic_cast(note1)); + assert( dynamic_cast(note1) || dynamic_cast(note1)); //layer direction trumps note direction if (layer1 && layer1->GetDrawingStemDir() != STEMDIRECTION_NONE){ up = layer1->GetDrawingStemDir() == STEMDIRECTION_up ? true : false; From cb55fca514fd614f17123f250e1443a63eb7980a Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 11 Mar 2015 20:09:32 +0000 Subject: [PATCH 03/68] Fixing coloration drawing --- src/view_mensural.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index 257ec0705cc..31dbfa17a3e 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -52,7 +52,6 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l xLedger = xStem; drawingDur = note->GetDrawingDur(); - drawingDur = ((note->GetColored()==BOOLEAN_true) && drawingDur > DUR_1) ? (drawingDur+1) : drawingDur; int radius = m_doc->m_drawingNoteRadius[staffSize][note->m_cueSize]; @@ -96,13 +95,15 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l } // Other values else { - if ((note->GetColored()==BOOLEAN_true) || drawingDur == DUR_2) { - fontNo = SMUFL_E0A3_noteheadHalf; + if (note->GetColored()==BOOLEAN_true) { + if (drawingDur == DUR_2) fontNo = SMUFL_E0A4_noteheadBlack; + else fontNo = SMUFL_E0A3_noteheadHalf; } else { - fontNo = SMUFL_E0A4_noteheadBlack; + if (drawingDur > DUR_2) fontNo = SMUFL_E0A4_noteheadBlack; + else fontNo = SMUFL_E0A3_noteheadHalf; } - + DrawSmuflCode( dc, xNote, noteY, fontNo, staff->staffSize, note->m_cueSize ); DrawStem(dc, note, staff, note->m_drawingStemDir, radius, xStem, noteY); From 8d05f7252361c674133c747d4bc66a6052622c98 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 11 Mar 2015 20:29:42 +0000 Subject: [PATCH 04/68] Fixing ledger lines for mensural notes --- src/view_mensural.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index 31dbfa17a3e..c99d44ccc01 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -39,14 +39,12 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l int staffSize = staff->staffSize; int noteY = element->GetDrawingY(); - int xLedger, xNote, xAccid, xStem; + int xLedger, xNote, xStem; int drawingDur; int staffY = staff->GetDrawingY(); wchar_t fontNo; int ledge; int verticalCenter = 0; - bool flippedNotehead = false; - bool doubleLengthLedger = false; xStem = element->GetDrawingX(); xLedger = xStem; @@ -111,22 +109,7 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l /************** Ledger lines: **************/ - int staffTop = staffY + m_doc->m_drawingUnit[staffSize]; - int staffBot = staffY - m_doc->m_drawingStaffSize[staffSize] - m_doc->m_drawingUnit[staffSize]; - - //if the note is not in the staff - if (!is_in(noteY,staffTop,staffBot)) - { - int distance, highestNewLine, numLines; - - bool aboveStaff = (noteY > staffTop); - - distance = (aboveStaff ? (noteY - staffY) : staffY - m_doc->m_drawingStaffSize[staffSize] - noteY); - highestNewLine = ((distance % m_doc->m_drawingDoubleUnit[staffSize] > 0) ? (distance - m_doc->m_drawingUnit[staffSize]) : distance); - numLines = highestNewLine / m_doc->m_drawingDoubleUnit[staffSize]; - - //DrawLedgerLines(dc, note, staff, aboveStaff, false, 0, numLines); - } + DrawLedgerLines( dc, noteY, staffY, xStem, ledge, staffSize ); /************** Accidentals/dots/peripherals: **************/ From cd7c00241790cea023ef1acfd9f143b1abc4ea0e Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 12 Mar 2015 09:56:09 +0100 Subject: [PATCH 05/68] Basic dots method --- include/vrv/object.h | 8 ++++++++ src/doc.cpp | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/vrv/object.h b/include/vrv/object.h index 5e8b0ac4daa..13a70342319 100644 --- a/include/vrv/object.h +++ b/include/vrv/object.h @@ -497,6 +497,14 @@ class Object */ virtual int PrepareTieAttrEnd( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; + /** + * Processes Chord and Note for matching @tie by processing by Layer and by looking + * at the Pname and Oct + * param 0: std::vector* that holds the current notes with open ties + * param 1: Chord** currentChord for the current chord if in a chord + */ + virtual int PrepareDots( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; + /** * Functor for setting wordpos and connector ends * The functor is process by staff/layer/verse using an ArrayOfAttComparisons filter. diff --git a/src/doc.cpp b/src/doc.cpp index 6a685332dda..b4ccaf8d84c 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -184,6 +184,25 @@ void Doc::PrepareDrawing() } } + for (staves = layerTree.child.begin(); staves != layerTree.child.end(); ++staves) { + for (layers = staves->second.child.begin(); layers != staves->second.child.end(); ++layers) { + filters.clear(); + // Create ad comparison object for each type / @n + AttCommonNComparison matchStaff( &typeid(Staff), staves->first ); + AttCommonNComparison matchLayer( &typeid(Layer), layers->first ); + filters.push_back( &matchStaff ); + filters.push_back( &matchLayer ); + + // The first pass set m_drawingFirstNote and m_drawingLastNote for each syl + // m_drawingLastNote is set only if the syl has a forward connector + ArrayPtrVoid paramsTieAttr; + //paramsTieAttr.push_back( ¤tNotes ); + //paramsTieAttr.push_back( ¤tChord ); + Functor prepareDots( &Object::PrepareDots ); + this->Process( &prepareDots, paramsTieAttr, NULL, &filters, UNLIMITED_DEPTH, BACKWARD ); + } + } + // Same for the lyrics, but Verse by Verse since Syl are TimeSpanningInterface elements for handling connectors Syl *currentSyl; Note *lastNote; From c83fa6fef4fbbaf3e9ff5069877c04e536ceff82 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 13 Mar 2015 18:45:17 +0100 Subject: [PATCH 06/68] Attaching dot to the previous note in mensural mode --- include/vrv/dot.h | 21 ++++++++++++++++++++- include/vrv/note.h | 5 +++++ include/vrv/object.h | 9 ++++----- src/doc.cpp | 14 ++++++-------- src/dot.cpp | 29 ++++++++++++++++++++++++++++- src/note.cpp | 10 ++++++++++ src/view_element.cpp | 8 +++++++- 7 files changed, 80 insertions(+), 16 deletions(-) diff --git a/include/vrv/dot.h b/include/vrv/dot.h index 83cef6bbeb5..b9fbf741b6b 100644 --- a/include/vrv/dot.h +++ b/include/vrv/dot.h @@ -14,7 +14,7 @@ namespace vrv { -class ChildElement; +class Note; //---------------------------------------------------------------------------- // Dot @@ -34,11 +34,30 @@ class Dot: public LayerElement, public PositionInterface virtual std::string GetClassName( ) { return "Dot"; }; ///@} + + //----------// + // Functors // + //----------// + + /** + * See Object::PreparePointersByLayer + */ + virtual int PreparePointersByLayer( ArrayPtrVoid params ); + + /** + * Reset the drawing values before calling PrepareDrawing after changes. + */ + virtual int ResetDarwing( ArrayPtrVoid params ); + protected: private: public: + /** + * A pointer to the note the point relates to. + */ + Note *m_drawingNote; private: diff --git a/include/vrv/note.h b/include/vrv/note.h index 820454c205e..20fd0317814 100644 --- a/include/vrv/note.h +++ b/include/vrv/note.h @@ -94,6 +94,11 @@ class Note: public LayerElement, public DurationInterface, public PitchInterface * The functor is process by staff/layer/verse using an ArrayOfAttComparisons filter. */ virtual int PrepareLyrics( ArrayPtrVoid params ); + + /** + * See Object::PreparePointersByLayer + */ + virtual int PreparePointersByLayer( ArrayPtrVoid params ); /** */ diff --git a/include/vrv/object.h b/include/vrv/object.h index 13a70342319..f9ed57db76e 100644 --- a/include/vrv/object.h +++ b/include/vrv/object.h @@ -498,12 +498,11 @@ class Object virtual int PrepareTieAttrEnd( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; /** - * Processes Chord and Note for matching @tie by processing by Layer and by looking - * at the Pname and Oct - * param 0: std::vector* that holds the current notes with open ties - * param 1: Chord** currentChord for the current chord if in a chord + * Processes by Layer and set drawing pointers. + * Set Dot::m_drawingNote for Dot elements in mensural mode + * param 0: Note** currentNote for the current not to w */ - virtual int PrepareDots( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; + virtual int PreparePointersByLayer( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; /** * Functor for setting wordpos and connector ends diff --git a/src/doc.cpp b/src/doc.cpp index b4ccaf8d84c..47fed3f8653 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -184,6 +184,7 @@ void Doc::PrepareDrawing() } } + Note *currentNote = NULL; for (staves = layerTree.child.begin(); staves != layerTree.child.end(); ++staves) { for (layers = staves->second.child.begin(); layers != staves->second.child.end(); ++layers) { filters.clear(); @@ -192,14 +193,11 @@ void Doc::PrepareDrawing() AttCommonNComparison matchLayer( &typeid(Layer), layers->first ); filters.push_back( &matchStaff ); filters.push_back( &matchLayer ); - - // The first pass set m_drawingFirstNote and m_drawingLastNote for each syl - // m_drawingLastNote is set only if the syl has a forward connector - ArrayPtrVoid paramsTieAttr; - //paramsTieAttr.push_back( ¤tNotes ); - //paramsTieAttr.push_back( ¤tChord ); - Functor prepareDots( &Object::PrepareDots ); - this->Process( &prepareDots, paramsTieAttr, NULL, &filters, UNLIMITED_DEPTH, BACKWARD ); + + ArrayPtrVoid paramsPointers; + paramsPointers.push_back( ¤tNote ); + Functor preparePointersByLayer( &Object::PreparePointersByLayer ); + this->Process( &preparePointersByLayer, paramsPointers, NULL, &filters ); } } diff --git a/src/dot.cpp b/src/dot.cpp index 10b76652897..ca6bab286fa 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -9,6 +9,12 @@ //---------------------------------------------------------------------------- +#include + +//---------------------------------------------------------------------------- + +#include "note.h" + namespace vrv { //---------------------------------------------------------------------------- @@ -29,6 +35,27 @@ void Dot::Reset() { LayerElement::Reset(); PositionInterface::Reset(); -} + m_drawingNote = NULL; +} + +//---------------------------------------------------------------------------- +// Functors methods +//---------------------------------------------------------------------------- + +int Dot::PreparePointersByLayer( ArrayPtrVoid params ) +{ + // param 0: the current Note + Note **currentNote = static_cast(params[0]); + + m_drawingNote = (*currentNote); + + return FUNCTOR_CONTINUE; +} + +int Dot::ResetDarwing( ArrayPtrVoid params ) +{ + this->m_drawingNote = NULL; + return FUNCTOR_CONTINUE; +}; } // namespace vrv diff --git a/src/note.cpp b/src/note.cpp index 0091b72e7a9..ff5182c6cdd 100644 --- a/src/note.cpp +++ b/src/note.cpp @@ -204,6 +204,16 @@ int Note::PrepareLyrics( ArrayPtrVoid params ) return FUNCTOR_CONTINUE; } +int Note::PreparePointersByLayer( ArrayPtrVoid params ) +{ + // param 0: the current Note + Note **currentNote = static_cast(params[0]); + + (*currentNote) = this; + + return FUNCTOR_CONTINUE; +} + int Note::ResetDarwing( ArrayPtrVoid params ) { this->ResetDrawingTieAttr(); diff --git a/src/view_element.cpp b/src/view_element.cpp index 10a43d17acb..c0eadcd7ed4 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1273,8 +1273,14 @@ void View::DrawDot( DeviceContext *dc, LayerElement *element, Layer *layer, Staf int x = element->GetDrawingX(); int y = element->GetDrawingY(); + + // Use the note to which the points to for position + if ( dot->m_drawingNote ) { + x = dot->m_drawingNote->GetDrawingX() + m_doc->m_drawingUnit[staff->staffSize]*7/2; + y = dot->m_drawingNote->GetDrawingY(); + } - DrawDot ( dc, x, y ); + DrawDots( dc, x, y, 1, staff ); dc->EndGraphic(element, this ); From 42143f38f227dce46e441a4419e3dcb48f7b6b49 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 13 Mar 2015 18:58:14 +0100 Subject: [PATCH 07/68] Fixing ledger lines with mensural notes --- src/view_mensural.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index c0fac1493a1..0a8fd26c27e 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -109,7 +109,22 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l /************** Ledger lines: **************/ - DrawLedgerLines( dc, noteY, staffY, xStem, ledge, staffSize ); + int staffTop = staffY + m_doc->m_drawingUnit[staffSize]; + int staffBot = staffY - m_doc->m_drawingStaffSize[staffSize] - m_doc->m_drawingUnit[staffSize]; + + //if the note is not in the staff + if (!is_in(noteY,staffTop,staffBot)) + { + int distance, highestNewLine, numLines; + bool aboveStaff = (noteY > staffTop); + + distance = (aboveStaff ? (noteY - staffY) : staffY - m_doc->m_drawingStaffSize[staffSize] - noteY); + highestNewLine = ((distance % m_doc->m_drawingDoubleUnit[staffSize] > 0) ? (distance - m_doc->m_drawingUnit[staffSize]) : distance); + numLines = highestNewLine / m_doc->m_drawingDoubleUnit[staffSize]; + + DrawLedgerLines(dc, note, staff, aboveStaff, false, 0, numLines); + + } /************** Accidentals/dots/peripherals: **************/ From a711d9e6dcc6e7e3d73a7c50eac365aa4d924110 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 16 Mar 2015 09:09:46 +0100 Subject: [PATCH 08/68] Drawing system line by default --- include/vrv/beam.h | 1 + include/vrv/view.h | 2 +- src/view_page.cpp | 8 ++++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/vrv/beam.h b/include/vrv/beam.h index 2515022cc94..b39cea87373 100644 --- a/include/vrv/beam.h +++ b/include/vrv/beam.h @@ -125,4 +125,5 @@ class BeamElementCoord } // namespace vrv + #endif diff --git a/include/vrv/view.h b/include/vrv/view.h index 8e827d63cd6..793a6574702 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -149,7 +149,7 @@ class View void DrawSystem( DeviceContext *dc, System *system ); void DrawSystemList( DeviceContext *dc, System *system, const std::type_info *elementType ); void DrawScoreDef( DeviceContext *dc, ScoreDef *scoreDef, Measure *measure, int x, Barline *barLine = NULL ); - void DrawStaffGrp( DeviceContext *dc, Measure *measure, StaffGrp *staffGrp, int x ); + void DrawStaffGrp( DeviceContext *dc, Measure *measure, StaffGrp *staffGrp, int x, bool topStaffGrp = false ); void DrawStaffDefLabels( DeviceContext *dc, Measure *measure, ScoreDef *scoreDef, bool abbreviations = false ); void DrawBracket ( DeviceContext *dc, int x, int y1, int y2, int staffSize); void DrawBrace ( DeviceContext *dc, int x, int y1, int y2, int staffSize); diff --git a/src/view_page.cpp b/src/view_page.cpp index f40fc943a19..135f58e34d0 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -176,7 +176,7 @@ void View::DrawScoreDef( DeviceContext *dc, ScoreDef *scoreDef, Measure *measure if ( barLine == NULL) { // Draw the first staffGrp and from there its children recursively - DrawStaffGrp( dc, measure, staffGrp, x ); + DrawStaffGrp( dc, measure, staffGrp, x, true ); DrawStaffDefLabels( dc, measure, scoreDef, !scoreDef->DrawLabels() ); // if this was true (non-abbreviated labels), set it to false for next one @@ -192,7 +192,7 @@ void View::DrawScoreDef( DeviceContext *dc, ScoreDef *scoreDef, Measure *measure return; } -void View::DrawStaffGrp( DeviceContext *dc, Measure *measure, StaffGrp *staffGrp, int x ) +void View::DrawStaffGrp( DeviceContext *dc, Measure *measure, StaffGrp *staffGrp, int x, bool topStaffGrp ) { assert( measure ); assert( staffGrp ); @@ -231,6 +231,10 @@ void View::DrawStaffGrp( DeviceContext *dc, Measure *measure, StaffGrp *staffGrp y_bottom -= m_doc->m_style->m_staffLineWidth / 2; // actually draw the line, the brace or the bracket + if ( topStaffGrp ) { + DrawVerticalLine( dc , y_top, y_bottom, x, m_doc->m_style->m_barlineWidth ); + } + // this will need to be changed with the next version of MEI will line means additional thick line if ( staffGrp->GetSymbol() == STAFFGRP_LINE ) { DrawVerticalLine( dc , y_top, y_bottom, x, m_doc->m_style->m_barlineWidth ); } From 0699bf3323e5499db6fd6e3d93aea53d2e0d9844 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 18 Mar 2015 09:22:26 +0100 Subject: [PATCH 09/68] Fixing mensur changes and long drawing --- include/vrv/aligner.h | 2 +- src/layerelement.cpp | 5 +++++ src/view_element.cpp | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/vrv/aligner.h b/include/vrv/aligner.h index b7f0da5d027..7a6013dbb1e 100644 --- a/include/vrv/aligner.h +++ b/include/vrv/aligner.h @@ -25,6 +25,7 @@ class MeasureAligner; */ enum AlignmentType { ALIGNMENT_MEASURE_START = 0, + ALIGNMENT_BARLINE, ALIGNMENT_CLEF_ATTR, ALIGNMENT_KEYSIG_ATTR, ALIGNMENT_MENSUR_ATTR, @@ -36,7 +37,6 @@ enum AlignmentType { ALIGNMENT_DOT, ALIGNMENT_GRACENOTE, ALIGNMENT_CONTAINER, - ALIGNMENT_BARLINE, ALIGNMENT_MULTIREST, ALIGNMENT_DEFAULT, ALIGNMENT_MEASURE_END diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 47b106d6d63..6d486bbbf10 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -307,6 +307,7 @@ int LayerElement::AlignHorizontally( ArrayPtrVoid params ) MeasureAligner **measureAligner = static_cast(params[0]); double *time = static_cast(params[1]); Mensur **currentMensur = static_cast(params[2]); + MeterSig **currentMeterSig = static_cast(params[3]); // we need to call it because we are overriding Object::AlignHorizontally this->ResetHorizontalAlignment(); @@ -344,6 +345,8 @@ int LayerElement::AlignHorizontally( ArrayPtrVoid params ) type = ALIGNMENT_MENSUR_ATTR; } else { + // replace the current mensur + (*currentMensur) = dynamic_cast(this); type = ALIGNMENT_MENSUR; } } @@ -352,6 +355,8 @@ int LayerElement::AlignHorizontally( ArrayPtrVoid params ) type = ALIGNMENT_METERSIG_ATTR; } else { + // replace the current meter signature + (*currentMeterSig) = dynamic_cast(this); type = ALIGNMENT_METERSIG; } } diff --git a/src/view_element.cpp b/src/view_element.cpp index bf8540aa119..9ffb8cf8d23 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1019,7 +1019,7 @@ void View::DrawLigature ( DeviceContext *dc, int y, LayerElement *element, Layer } else if (note->m_dur == DUR_LG) // DUR_LG isolee: queue comme notes normales */ - if (note->GetDur() == DUR_LG) + if (note->GetActualDur() == DUR_LG) { verticalCenter = staff->GetDrawingY() - m_doc->m_drawingDoubleUnit[staff->staffSize]*2; // ENZ From 8fe2191a67652d0f303ff8e373da5aeecf13cff3 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Wed, 18 Mar 2015 11:19:56 -0400 Subject: [PATCH 10/68] Fixed: note.m_accid is now a pointer As per line notes. m_accid is set in DrawNote; all manipulations are still the same. -replaced (2*fullUnit) with doubleUnit --- include/vrv/note.h | 2 +- src/note.cpp | 9 ++++++++- src/view_element.cpp | 32 +++++++++++++++++++++----------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/include/vrv/note.h b/include/vrv/note.h index e632a7aac90..4ee31ef19f9 100644 --- a/include/vrv/note.h +++ b/include/vrv/note.h @@ -149,7 +149,7 @@ class Note: public LayerElement, public DurationInterface, public PitchInterface int m_clusterPosition; //1-indexed position in said cluster; 0 if does not have position /** other information necessary for notes in chords **/ - Accid m_accid; + Accid *m_accid; private: diff --git a/src/note.cpp b/src/note.cpp index e60a3ccfb2c..1e7f4247577 100644 --- a/src/note.cpp +++ b/src/note.cpp @@ -34,16 +34,23 @@ Note::Note(): AttTiepresent() { m_drawingTieAttr = NULL; + m_accid = NULL; Reset(); } Note::~Note() { - // This deletes the Tie and Slur objects if necessary + // This deletes the Tie, Slur, and Accid objects if necessary if (m_drawingTieAttr) { delete m_drawingTieAttr; } + + if (m_accid) { + delete m_accid; + m_accid = NULL; + } + } void Note::Reset() diff --git a/src/view_element.cpp b/src/view_element.cpp index bcda0253b7c..5d77248a6ce 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -416,12 +416,22 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St if (note->GetAccid() != ACCIDENTAL_EXPLICIT_NONE) { xAccid = xNote - 1.5 * m_doc->m_drawingAccidWidth[staffSize][note->m_cueSize]; - - Accid *accid = ¬e->m_accid; - accid->SetOloc(note->GetOct()); - accid->SetPloc(note->GetPname()); - accid->SetAccid(note->GetAccid()); - accid->m_cueSize = note->m_cueSize; + Accid *accid; + + if (note->m_accid == NULL) + { + note->m_accid = new Accid(); + accid = note->m_accid; + accid->SetOloc(note->GetOct()); + accid->SetPloc(note->GetPname()); + accid->SetAccid(note->GetAccid()); + accid->m_cueSize = note->m_cueSize; + } + else + { + accid = note->m_accid; + } + accid->SetDrawingX( xAccid ); accid->SetDrawingY( noteY ); @@ -1186,7 +1196,7 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St for(idx = 0; idx < size; idx++) { - Accid *curAccid = ¬eList[idx]->m_accid; + Accid *curAccid = noteList[idx]->m_accid; //false as the last parameter for CalcAccidX will see if there are any vertical conflicts without setting anything if (CalculateAccidX(staff, curAccid, chord, false) > 0) { @@ -1206,8 +1216,8 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St //if it's even, this will catch the overlap; if it's odd, there's an if in the middle there while (fwIdx <= bwIdx) { - Accid *accidFwd = ¬eList[fwIdx]->m_accid; - Accid *accidBwd = ¬eList[bwIdx]->m_accid; + Accid *accidFwd = noteList[fwIdx]->m_accid; + Accid *accidBwd = noteList[bwIdx]->m_accid; //if the top note has an accidental, draw it and update prevAccid accidFwd->SetDrawingX(xAccid); @@ -1445,9 +1455,9 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool save) //Y-position limits int listTop = noteList[0]->GetDrawingY(); int listBot = noteList[noteList.size() - 1]->GetDrawingY(); - int topY = accid->GetDrawingY() + (2 * fullUnit); + int topY = accid->GetDrawingY() + doubleUnit; int topPos = std::max(0, listTop - topY) / halfUnit; - int bottomY = accid->GetDrawingY() - (2 * fullUnit); + int bottomY = accid->GetDrawingY() - doubleUnit; int botPos = (int)accidSpace->size() - 1 - ((std::max(0, bottomY - listBot)) / halfUnit); int currentX = 0; From 6cd6a68ba398aeef69ad67175bb5322a26513047 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Wed, 18 Mar 2015 16:24:58 -0400 Subject: [PATCH 11/68] New: GetListFirstBackwards searches for most recent element -removed Layer::GetFirstOld -added Object:GetListFirstBackwards to search backwards for an object; utilized by Layer::GetClef -included code for GetListFirst, untested --- include/vrv/object.h | 8 ++++++ src/layer.cpp | 59 ++++++++------------------------------------ src/object.cpp | 18 ++++++++++++++ 3 files changed, 36 insertions(+), 49 deletions(-) diff --git a/include/vrv/object.h b/include/vrv/object.h index 090a90378db..7885fcc2ae3 100644 --- a/include/vrv/object.h +++ b/include/vrv/object.h @@ -9,6 +9,7 @@ #ifndef __VRV_OBJECT_H__ #define __VRV_OBJECT_H__ +#include #include #include #include @@ -698,6 +699,12 @@ class ObjectListInterface */ int GetListIndex( const Object *listElement ); + /** + * Gets the first item of type elementType starting at startFrom + */ + Object *GetListFirst(const Object *startFrom, const std::type_info *elementType = NULL ); + Object *GetListFirstBackward(Object *startFrom, const std::type_info *elementType = NULL ); + /** * Returns the previous object in the list (NULL if not found) */ @@ -718,6 +725,7 @@ class ObjectListInterface private: ListOfObjects m_list; + ListOfObjects::iterator m_iteratorCurrent; protected: /** diff --git a/src/layer.cpp b/src/layer.cpp index 7a32fa27734..3a76fe6ce81 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -274,68 +274,29 @@ void Layer::Delete( LayerElement *element ) Refresh(); } -// Dans la direction indiquee (direction), cavale sur tout element qui n'est pas un -// symbol, de la nature indiquee (flg). Retourne le ptr si succes, ou -// l'element de depart; le ptr succ est vrai si symb trouve. - -LayerElement *Layer::GetFirstOld( LayerElement *element, bool direction, const std::type_info *elementType, bool *succ) -{ - LayerElement *original = element; - - *succ = false; - if (element == NULL) - return (element); - - ResetList(this); - - int i = GetListIndex( element ); - if ( i == -1 ) - return (element); - - *succ = true; // we assume we will find it. Change to false if not - while ( typeid(*element) != *elementType ) - { - if (direction==BACKWARD) - { - if (i < 1) { - *succ = false; - break; - } - i--; - element = static_cast( GetListPrevious(element) ); - } - else - { if (i >= (int)GetList(this)->size() - 1 ) { - *succ = false; - break; - } - i++; - element = static_cast( GetListNext(element) ); - } - } - - return (*succ ? element : original); -} Clef* Layer::GetClef( LayerElement *test ) { - bool succ=false; - + Object *testObject = test; + if (!test) { return NULL; } + //make sure list is set + ResetList(this); if ( !test->IsClef() ) - { - test = GetFirstOld(test, BACKWARD, &typeid(Clef), &succ); + { + testObject = GetListFirstBackward(testObject, &typeid(Clef)); } - if ( dynamic_cast(test) ) { - return dynamic_cast(test); + + if ( dynamic_cast(testObject) ) { + return dynamic_cast(testObject); } return m_currentClef; } - + int Layer::GetClefOffset( LayerElement *test ) { Clef *clef = GetClef(test); diff --git a/src/object.cpp b/src/object.cpp index 7317c7d733f..caa15b323ca 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -732,6 +732,24 @@ int ObjectListInterface::GetListIndex( const Object *listElement ) return -1; } + +Object* ObjectListInterface::GetListFirst(const Object *startFrom, const std::type_info *elementType) +{ + m_iteratorCurrent = m_list.begin(); + std::advance(m_iteratorCurrent, GetListIndex(startFrom)); + m_iteratorCurrent = std::find_if(m_iteratorCurrent, m_list.end(), ObjectComparison( elementType ) ); + return (m_iteratorCurrent == m_list.end()) ? NULL : *m_iteratorCurrent; +} + +Object* ObjectListInterface::GetListFirstBackward(Object *startFrom, const std::type_info *elementType) +{ + m_iteratorCurrent = m_list.begin(); + std::advance(m_iteratorCurrent, GetListIndex(startFrom)); + ListOfObjects::reverse_iterator reverseIteratorCurrent(m_iteratorCurrent); + reverseIteratorCurrent = std::find_if(reverseIteratorCurrent, m_list.rend(), ObjectComparison( elementType ) ); + return (reverseIteratorCurrent == m_list.rend()) ? NULL : *reverseIteratorCurrent; +} + Object *ObjectListInterface::GetListPrevious( const Object *listElement ) { ListOfObjects::iterator iter; From 71256c37d829251a5950157a5bc2017a83fa36d1 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Sun, 22 Mar 2015 21:56:38 +0100 Subject: [PATCH 12/68] Fixing single figure mensur --- src/view_mensural.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index 0a8fd26c27e..1b59838db1e 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -198,7 +198,8 @@ void View::DrawMensur( DeviceContext *dc, LayerElement *element, Layer *layer, S { x += m_doc->m_drawingUnit[staff->staffSize] * 5; // step forward because we have a sign or a meter symbol } - DrawMeterSigFigures ( dc, x, staff->GetDrawingY(), mensur->GetNum(), mensur->GetNumbase(), staff); + int numbase = mensur->HasNumbase() ? mensur->GetNumbase() : 0; + DrawMeterSigFigures ( dc, x, staff->GetDrawingY(), mensur->GetNum(), numbase, staff); } dc->EndGraphic(element, this ); //RZ From 4af0e84b6833f7cb53fea1ffe6eb085b9a4790de Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 24 Mar 2015 18:25:06 +0100 Subject: [PATCH 13/68] Setting memory to ASM default practice --- emscripten/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/emscripten/build.sh b/emscripten/build.sh index d645e5653f9..bee8e429467 100755 --- a/emscripten/build.sh +++ b/emscripten/build.sh @@ -29,6 +29,7 @@ if [ ! -d data ]; then mkdir data; fi ASM="\ -O2 --memory-init-file 0 \ -s ASM_JS=1 \ + -s TOTAL_MEMORY=128*1024*1024 \ -s TOTAL_STACK=64*1024*1024" ASM_NAME="" From 09b8804e990007c12534498a83b05817c2792448 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 24 Mar 2015 23:26:01 +0100 Subject: [PATCH 14/68] Removing assert for unresolved timestamp elements --- src/view_page.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/view_page.cpp b/src/view_page.cpp index 135f58e34d0..44d31ffb099 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -798,9 +798,8 @@ void View::DrawTimeSpanningElement( DeviceContext *dc, DocObject *element, Syste { assert(dynamic_cast(element)); // Element must be a TimeSpanningInterface TimeSpanningInterface *interface = dynamic_cast(element); - - if ( !Check( interface->GetStart() ) ) return; - if ( !Check( interface->GetEnd() ) ) return; + + if ( !interface->HasStartAndEnd() ) return; // Get the parent system of the first and last note System *parentSystem1 = dynamic_cast( interface->GetStart()->GetFirstParent( &typeid(System) ) ); From 1e18f311f32b2d67cd3772428a928804fab8a63a Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 26 Mar 2015 08:52:17 +0100 Subject: [PATCH 15/68] Verifying that a mensur is provided for calculating durations in mensural mode --- src/durationinterface.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/durationinterface.cpp b/src/durationinterface.cpp index d919602b039..18b18cc6dc1 100644 --- a/src/durationinterface.cpp +++ b/src/durationinterface.cpp @@ -73,6 +73,11 @@ double DurationInterface::GetAlignmentMensuralDuration( int num, int numbase, Me { int note_dur = this->GetDurGes() != DURATION_NONE ? this->GetDurGes() : this->GetActualDur(); + if (!currentMensur) { + LogWarning("No current mensur for calculating duration" ); + return DUR_MENSURAL_REF; + } + if (this->HasNum()) num *=this->GetNum(); if (this->HasNumbase()) numbase *=this->GetNumbase(); if (currentMensur->HasNum()) num *=currentMensur->GetNum(); From a6a414ab234db06535885a4e6e82ec23591a2352 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 26 Mar 2015 22:07:31 +0100 Subject: [PATCH 16/68] Fixing maxima --- include/vrv/view.h | 6 +- src/view_element.cpp | 178 +----------------------------- src/view_mensural.cpp | 246 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 251 insertions(+), 179 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index 793a6574702..d9fd96a85f4 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -263,7 +263,6 @@ class View void DrawDots ( DeviceContext *dc, int x, int y, unsigned char dots, Staff *staff ); void DrawFermata(DeviceContext *dc, LayerElement *element, Staff *staff); void DrawLedgerLines ( DeviceContext *dc, LayerElement *element, Staff *staff, bool aboveStaff, bool doubleLength, int skip, int n); - void DrawLigature( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff ); void DrawLongRest ( DeviceContext *dc, int x, int y, Staff *staff); void DrawMeterSigFigures( DeviceContext *dc, int x, int y, int num, int numBase, Staff *staff); void DrawQuarterRest ( DeviceContext *dc, int x, int y, int valeur, unsigned char dots, unsigned int smaller, Staff *staff); @@ -272,7 +271,6 @@ class View void DrawSylConnectorLines( DeviceContext *dc, int x1, int x2, int y, Syl *syl, Staff *staff ); void DrawTrill(DeviceContext *dc, LayerElement *element, Staff *staff ); void DrawWholeRest ( DeviceContext *dc, int x, int y, int valeur, unsigned char dots, unsigned int smaller, Staff *staff); - void CalculateLigaturePosX ( LayerElement *element, Layer *layer, Staff *staff); ///@} /** @@ -296,6 +294,10 @@ class View void DrawMensurHalfCircle( DeviceContext *dc, int x, int yy, Staff *staff ); void DrawMensurReversedHalfCircle( DeviceContext *dc, int x, int yy, Staff *staff ); void DrawMensurSlash( DeviceContext *dc, int x, int yy, Staff *staff ); + void DrawMaximaToBrevis( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff ); + void DrawLigature( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff ); + void CalculateLigaturePosX ( LayerElement *element, Layer *layer, Staff *staff); + ///@} /** * @name Method for drawing Beam. diff --git a/src/view_element.cpp b/src/view_element.cpp index 9ffb8cf8d23..1cff5d71516 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -49,9 +49,6 @@ namespace vrv { // View - LayerElement //---------------------------------------------------------------------------- -int View::s_drawingLigX[2], View::s_drawingLigY[2]; // pour garder coord. des ligatures -bool View::s_drawingLigObliqua = false; // marque le 1e passage pour une oblique - void View::DrawLayerElement( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure) { assert(layer); // Pointer to layer cannot be NULL" @@ -356,10 +353,9 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St /************** Noteheads: **************/ - // Long, breve and ligatures - if (drawingDur == DUR_LG || drawingDur == DUR_BR || ((note->GetLig()!=LIGATURE_NONE) && drawingDur == DUR_1)) { - DrawLigature ( dc, noteY, element, layer, staff); - } + if (drawingDur < DUR_1) { + DrawMaximaToBrevis( dc, noteY, element, layer, staff); + } // Whole notes else if (drawingDur == DUR_1) { if (note->GetColored()==BOOLEAN_true) @@ -881,174 +877,6 @@ void View::DrawDots ( DeviceContext *dc, int x, int y, unsigned char dots, Staff return; } - - -void View::CalculateLigaturePosX ( LayerElement *element, Layer *layer, Staff *staff) -{ - /* - if (element == NULL) - { - return; - } - LayerElement *previous = layer->GetPrevious(element); - if (previous == NULL || !previous->IsNote()) - { - return; - } - Note *previousNote = dynamic_cast(previous); - if (previousNote->m_lig==LIG_TERMINAL) - { - return; - } - if (previousNote->m_lig && previousNote->m_dur <= DUR_1) - { - element->SetDrawingX( previous->GetDrawingX() + m_doc->m_drawingBrevisWidth[staff->staffSize] * 2 ); - } - */ - return; -} - -void View::DrawLigature ( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff ) -{ - assert(layer); // Pointer to layer cannot be NULL" - assert(staff); // Pointer to staff cannot be NULL" - assert(dynamic_cast(element)); // Element must be a Note" - - - Note *note = dynamic_cast(element); - - int xn, x1, x2, y1, y2, y3, y4; - // int yy2, y5; // unused - int verticalCenter, up, epaisseur; - - epaisseur = std::max (2, m_doc->m_drawingBeamWidth[staff->staffSize]/2); - xn = element->GetDrawingX(); - - /* - if ((note->m_lig==LIG_MEDIAL) || (note->m_lig==LIG_TERMINAL)) - { - CalculateLigaturePosX ( element, layer, staff ); - } - else - */{ - xn = element->GetDrawingX(); - } - - // calcul des dimensions du rectangle - x1 = xn - m_doc->m_drawingBrevisWidth[staff->staffSize]; x2 = xn + m_doc->m_drawingBrevisWidth[staff->staffSize]; - y1 = y + m_doc->m_drawingUnit[staff->staffSize]; - y2 = y - m_doc->m_drawingUnit[staff->staffSize]; - y3 = (int)(y1 + m_doc->m_drawingUnit[staff->staffSize]/2); // partie d'encadrement qui depasse - y4 = (int)(y2 - m_doc->m_drawingUnit[staff->staffSize]/2); - - - //if (!note->m_ligObliqua && (!View::s_drawingLigObliqua)) // notes rectangulaires, y c. en ligature - { - if (note->GetColored()!=BOOLEAN_true) - { // double base des carrees - DrawObliquePolygon ( dc, x1, y1, x2, y1, -epaisseur ); - DrawObliquePolygon ( dc, x1, y2, x2, y2, epaisseur ); - } - else - DrawFullRectangle( dc,x1,y1,x2,y2); // dessine val carree pleine // ENZ correction de x2 - - DrawVerticalLine ( dc, y3, y4, x1, m_doc->m_style->m_stemWidth ); // corset lateral - DrawVerticalLine ( dc, y3, y4, x2, m_doc->m_style->m_stemWidth ); - } - /* - else // traitement des obliques - { - if (!View::s_drawingLigObliqua) // 1e passage: ligne flagStemHeighte initiale - { - DrawVerticalLine (dc,y3,y4,x1, m_doc->m_style->m_stemWidth ); - View::s_drawingLigObliqua = true; - //oblique = OFF; -// if (val == DUR_1) // queue gauche haut si DUR_1 -// queue_lig = ON; - } - else // 2e passage: lignes obl. et flagStemHeighte finale - { - x1 -= m_doc->m_drawingBrevisWidth[staff->staffSize]*2; // avance auto - - y1 = *View::s_drawingLigY - m_doc->m_drawingUnit[staff->staffSize]; // ligat_y contient y original - yy2 = y2; - y5 = y1+ m_doc->m_drawingDoubleUnit[staff->staffSize]; y2 += m_doc->m_drawingDoubleUnit[staff->staffSize]; // on monte d'un INTERL - - if (note->GetColored()==BOOLEAN_true) - DrawObliquePolygon ( dc, x1, y1, x2, yy2, m_doc->m_drawingDoubleUnit[staff->staffSize]); - else - { DrawObliquePolygon ( dc, x1, y1, x2, yy2, 5); - DrawObliquePolygon ( dc, x1, y5, x2, y2, -5); - } - DrawVerticalLine ( dc,y3,y4,x2,m_doc->m_style->m_stemWidth); //cloture flagStemHeighte - - View::s_drawingLigObliqua = false; -// queue_lig = OFF; //desamorce alg.queue DUR_BR - - } - } - - if (note->m_lig) // memoriser positions d'une note a l'autre; relier notes par barres - { - *(View::s_drawingLigX+1) = x2; *(View::s_drawingLigY+1) = y; // relie notes ligaturees par barres flagStemHeightes - //if (in(x1,(*View::s_drawingLigX)-2,(*View::s_drawingLigX)+2) || (this->fligat && this->lat && !Note1::marq_obl)) - // les dernieres conditions pour permettre ligature flagStemHeighte ancienne - // DrawVerticalLine (dc, *ligat_y, y1, (this->fligat && this->lat) ? x2: x1, m_doc->m_parameters.m_stemWidth); // ax2 - drawing flagStemHeight lines missing - *View::s_drawingLigX = *(View::s_drawingLigX + 1); - *View::s_drawingLigY = *(View::s_drawingLigY + 1); - } - - - y3 = y2 - m_doc->m_drawingUnit[staff->staffSize]*6; - - if (note->m_lig) - { - if (note->m_dur == DUR_BR) // && this->queue_lig) // queue gauche bas: DUR_BR initiale descendante // ax2 - no support of queue_lig (see WG corrigeLigature) - { - DrawVerticalLine ( dc, y2, y3, x1, m_doc->m_style->m_stemWidth ); - } - else if (note->m_dur == DUR_LG) // && !this->queue_lig) // DUR_LG en ligature, queue droite bas // ax2 - no support of queue_lig - { - DrawVerticalLine (dc, y2, y3, x2, m_doc->m_style->m_stemWidth ); - } - else if (note->m_dur == DUR_1) // && this->queue_lig ) // queue gauche haut // ax2 - no support of queue_lig - { - y2 = y1 + m_doc->m_drawingUnit[staff->staffSize]*6; - DrawVerticalLine ( dc, y1, y2, x1, m_doc->m_style->m_stemWidth ); - } - } - else if (note->m_dur == DUR_LG) // DUR_LG isolee: queue comme notes normales - */ - if (note->GetActualDur() == DUR_LG) - { - verticalCenter = staff->GetDrawingY() - m_doc->m_drawingDoubleUnit[staff->staffSize]*2; - // ENZ - up = (y < verticalCenter) ? ON : OFF; - // ENZ - if ( note->m_drawingStemDir != STEMDIRECTION_NONE ) { - if ( note->m_drawingStemDir == STEMDIRECTION_up) { - up = ON; - } - else { - up = OFF; - } - } - - if (!up) - { - y3 = y1 - m_doc->m_drawingUnit[staff->staffSize]*8; - y2 = y1; - } - else { - y3 = y1 + m_doc->m_drawingUnit[staff->staffSize]*6; - y2 = y1; - } - DrawVerticalLine ( dc, y2,y3,x2, m_doc->m_style->m_stemWidth ); - } - - return; -} - void View::DrawBarline( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ) { assert(layer); // Pointer to layer cannot be NULL" diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index 1b59838db1e..3bc3fe06306 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -23,7 +23,10 @@ #include "staff.h" #include "style.h" -namespace vrv { +namespace vrv { + +int View::s_drawingLigX[2], View::s_drawingLigY[2]; // pour garder coord. des ligatures +bool View::s_drawingLigObliqua = false; // marque le 1e passage pour une oblique //---------------------------------------------------------------------------- // View - Mensural @@ -79,9 +82,12 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l /************** Noteheads: **************/ // Long, breve and ligatures - if (drawingDur == DUR_LG || drawingDur == DUR_BR || ((note->GetLig()!=LIGATURE_NONE) && drawingDur == DUR_1)) { + if ((note->GetLig()!=LIGATURE_NONE) && (drawingDur <= DUR_1)) { DrawLigature ( dc, noteY, element, layer, staff); } + else if (drawingDur < DUR_1) { + DrawMaximaToBrevis( dc, noteY, element, layer, staff); + } // Whole notes else if (drawingDur == DUR_1) { if (note->GetColored()==BOOLEAN_true) @@ -296,5 +302,241 @@ void View::DrawMensurSlash ( DeviceContext *dc, int a, int yy, Staff *staff ) return; } +void View::CalculateLigaturePosX ( LayerElement *element, Layer *layer, Staff *staff) +{ + /* + if (element == NULL) + { + return; + } + LayerElement *previous = layer->GetPrevious(element); + if (previous == NULL || !previous->IsNote()) + { + return; + } + Note *previousNote = dynamic_cast(previous); + if (previousNote->m_lig==LIG_TERMINAL) + { + return; + } + if (previousNote->m_lig && previousNote->m_dur <= DUR_1) + { + element->SetDrawingX( previous->GetDrawingX() + m_doc->m_drawingBrevisWidth[staff->staffSize] * 2 ); + } + */ + return; +} + +void View::DrawMaximaToBrevis( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff ) +{ + assert(layer); // Pointer to layer cannot be NULL" + assert(staff); // Pointer to staff cannot be NULL" + assert(dynamic_cast(element)); // Element must be a Note" + + + Note *note = dynamic_cast(element); + + int xn, x1, x2, y1, y2, y3, y4; + // int yy2, y5; // unused + int verticalCenter, up, height; + + height = m_doc->m_drawingBeamWidth[staff->staffSize]/2 ; + xn = element->GetDrawingX(); + + // calcul des dimensions du rectangle + x1 = xn - m_doc->m_drawingBrevisWidth[staff->staffSize]; + x2 = xn + m_doc->m_drawingBrevisWidth[staff->staffSize]; + if (note->GetActualDur() == DUR_MX) { + x1 -= m_doc->m_drawingBrevisWidth[staff->staffSize]; + x2 += m_doc->m_drawingBrevisWidth[staff->staffSize]; + } + y1 = y + m_doc->m_drawingUnit[staff->staffSize]; + y2 = y - m_doc->m_drawingUnit[staff->staffSize]; + y3 = (int)(y1 + m_doc->m_drawingUnit[staff->staffSize]/2); // partie d'encadrement qui depasse + y4 = (int)(y2 - m_doc->m_drawingUnit[staff->staffSize]/2); + + if (note->GetColored()!=BOOLEAN_true) { + // double base des carrees + DrawObliquePolygon ( dc, x1, y1, x2, y1, -height ); + DrawObliquePolygon ( dc, x1, y2, x2, y2, height ); + } + else { + DrawFullRectangle( dc,x1,y1,x2,y2); + } + + DrawVerticalLine ( dc, y3, y4, x1, m_doc->m_style->m_stemWidth ); // corset lateral + DrawVerticalLine ( dc, y3, y4, x2, m_doc->m_style->m_stemWidth ); + + // stem + if (note->GetActualDur() < DUR_BR) + { + verticalCenter = staff->GetDrawingY() - m_doc->m_drawingDoubleUnit[staff->staffSize]*2; + up = (y < verticalCenter) ? true : false; + if ( note->m_drawingStemDir != STEMDIRECTION_NONE ) { + if ( note->m_drawingStemDir == STEMDIRECTION_up) { + up = true; + } + else { + up = false; + } + } + + if (!up) { + y3 = y1 - m_doc->m_drawingUnit[staff->staffSize]*8; + y2 = y1; + } + else { + y3 = y1 + m_doc->m_drawingUnit[staff->staffSize]*6; + y2 = y1; + } + DrawVerticalLine ( dc, y2,y3,x2, m_doc->m_style->m_stemWidth ); + } + + return; +} + +void View::DrawLigature ( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff ) +{ + assert(layer); // Pointer to layer cannot be NULL" + assert(staff); // Pointer to staff cannot be NULL" + assert(dynamic_cast(element)); // Element must be a Note" + + + Note *note = dynamic_cast(element); + + int xn, x1, x2, y1, y2, y3, y4; + // int yy2, y5; // unused + int verticalCenter, up, epaisseur; + + epaisseur = std::max (2, m_doc->m_drawingBeamWidth[staff->staffSize]/2); + xn = element->GetDrawingX(); + + /* + if ((note->m_lig==LIG_MEDIAL) || (note->m_lig==LIG_TERMINAL)) + { + CalculateLigaturePosX ( element, layer, staff ); + } + else + */{ + xn = element->GetDrawingX(); + } + + // calcul des dimensions du rectangle + x1 = xn - m_doc->m_drawingBrevisWidth[staff->staffSize]; x2 = xn + m_doc->m_drawingBrevisWidth[staff->staffSize]; + y1 = y + m_doc->m_drawingUnit[staff->staffSize]; + y2 = y - m_doc->m_drawingUnit[staff->staffSize]; + y3 = (int)(y1 + m_doc->m_drawingUnit[staff->staffSize]/2); // partie d'encadrement qui depasse + y4 = (int)(y2 - m_doc->m_drawingUnit[staff->staffSize]/2); + + + //if (!note->m_ligObliqua && (!View::s_drawingLigObliqua)) // notes rectangulaires, y c. en ligature + { + if (note->GetColored()!=BOOLEAN_true) + { // double base des carrees + DrawObliquePolygon ( dc, x1, y1, x2, y1, -epaisseur ); + DrawObliquePolygon ( dc, x1, y2, x2, y2, epaisseur ); + } + else + DrawFullRectangle( dc,x1,y1,x2,y2); // dessine val carree pleine // ENZ correction de x2 + + DrawVerticalLine ( dc, y3, y4, x1, m_doc->m_style->m_stemWidth ); // corset lateral + DrawVerticalLine ( dc, y3, y4, x2, m_doc->m_style->m_stemWidth ); + } + /* + else // traitement des obliques + { + if (!View::s_drawingLigObliqua) // 1e passage: ligne flagStemHeighte initiale + { + DrawVerticalLine (dc,y3,y4,x1, m_doc->m_style->m_stemWidth ); + View::s_drawingLigObliqua = true; + //oblique = OFF; + // if (val == DUR_1) // queue gauche haut si DUR_1 + // queue_lig = ON; + } + else // 2e passage: lignes obl. et flagStemHeighte finale + { + x1 -= m_doc->m_drawingBrevisWidth[staff->staffSize]*2; // avance auto + + y1 = *View::s_drawingLigY - m_doc->m_drawingUnit[staff->staffSize]; // ligat_y contient y original + yy2 = y2; + y5 = y1+ m_doc->m_drawingDoubleUnit[staff->staffSize]; y2 += m_doc->m_drawingDoubleUnit[staff->staffSize]; // on monte d'un INTERL + + if (note->GetColored()==BOOLEAN_true) + DrawObliquePolygon ( dc, x1, y1, x2, yy2, m_doc->m_drawingDoubleUnit[staff->staffSize]); + else + { DrawObliquePolygon ( dc, x1, y1, x2, yy2, 5); + DrawObliquePolygon ( dc, x1, y5, x2, y2, -5); + } + DrawVerticalLine ( dc,y3,y4,x2,m_doc->m_style->m_stemWidth); //cloture flagStemHeighte + + View::s_drawingLigObliqua = false; + // queue_lig = OFF; //desamorce alg.queue DUR_BR + + } + } + + if (note->m_lig) // memoriser positions d'une note a l'autre; relier notes par barres + { + *(View::s_drawingLigX+1) = x2; *(View::s_drawingLigY+1) = y; // relie notes ligaturees par barres flagStemHeightes + //if (in(x1,(*View::s_drawingLigX)-2,(*View::s_drawingLigX)+2) || (this->fligat && this->lat && !Note1::marq_obl)) + // les dernieres conditions pour permettre ligature flagStemHeighte ancienne + // DrawVerticalLine (dc, *ligat_y, y1, (this->fligat && this->lat) ? x2: x1, m_doc->m_parameters.m_stemWidth); // ax2 - drawing flagStemHeight lines missing + *View::s_drawingLigX = *(View::s_drawingLigX + 1); + *View::s_drawingLigY = *(View::s_drawingLigY + 1); + } + + + y3 = y2 - m_doc->m_drawingUnit[staff->staffSize]*6; + + if (note->m_lig) + { + if (note->m_dur == DUR_BR) // && this->queue_lig) // queue gauche bas: DUR_BR initiale descendante // ax2 - no support of queue_lig (see WG corrigeLigature) + { + DrawVerticalLine ( dc, y2, y3, x1, m_doc->m_style->m_stemWidth ); + } + else if (note->m_dur == DUR_LG) // && !this->queue_lig) // DUR_LG en ligature, queue droite bas // ax2 - no support of queue_lig + { + DrawVerticalLine (dc, y2, y3, x2, m_doc->m_style->m_stemWidth ); + } + else if (note->m_dur == DUR_1) // && this->queue_lig ) // queue gauche haut // ax2 - no support of queue_lig + { + y2 = y1 + m_doc->m_drawingUnit[staff->staffSize]*6; + DrawVerticalLine ( dc, y1, y2, x1, m_doc->m_style->m_stemWidth ); + } + } + else if (note->m_dur == DUR_LG) // DUR_LG isolee: queue comme notes normales + */ + if (note->GetActualDur() == DUR_LG) + { + verticalCenter = staff->GetDrawingY() - m_doc->m_drawingDoubleUnit[staff->staffSize]*2; + // ENZ + up = (y < verticalCenter) ? ON : OFF; + // ENZ + if ( note->m_drawingStemDir != STEMDIRECTION_NONE ) { + if ( note->m_drawingStemDir == STEMDIRECTION_up) { + up = ON; + } + else { + up = OFF; + } + } + + if (!up) + { + y3 = y1 - m_doc->m_drawingUnit[staff->staffSize]*8; + y2 = y1; + } + else { + y3 = y1 + m_doc->m_drawingUnit[staff->staffSize]*6; + y2 = y1; + } + DrawVerticalLine ( dc, y2,y3,x2, m_doc->m_style->m_stemWidth ); + } + + return; +} + + + } // namespace vrv From b41e3868dea7a055c6217037ee661dd4e301aedf Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Mon, 30 Mar 2015 11:59:25 -0400 Subject: [PATCH 17/68] Fixed: local iterators in GetListFirst(Backwards) Using local it/rit variables instead of global m_(reverse)iteratorCurrent. --- src/object.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/object.cpp b/src/object.cpp index caa15b323ca..a6216aa8350 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -735,19 +735,19 @@ int ObjectListInterface::GetListIndex( const Object *listElement ) Object* ObjectListInterface::GetListFirst(const Object *startFrom, const std::type_info *elementType) { - m_iteratorCurrent = m_list.begin(); - std::advance(m_iteratorCurrent, GetListIndex(startFrom)); - m_iteratorCurrent = std::find_if(m_iteratorCurrent, m_list.end(), ObjectComparison( elementType ) ); - return (m_iteratorCurrent == m_list.end()) ? NULL : *m_iteratorCurrent; + ListOfObjects::iterator it = m_list.begin(); + std::advance(it, GetListIndex(startFrom)); + it = std::find_if(it, m_list.end(), ObjectComparison( elementType ) ); + return (it == m_list.end()) ? NULL : *it; } Object* ObjectListInterface::GetListFirstBackward(Object *startFrom, const std::type_info *elementType) { - m_iteratorCurrent = m_list.begin(); - std::advance(m_iteratorCurrent, GetListIndex(startFrom)); - ListOfObjects::reverse_iterator reverseIteratorCurrent(m_iteratorCurrent); - reverseIteratorCurrent = std::find_if(reverseIteratorCurrent, m_list.rend(), ObjectComparison( elementType ) ); - return (reverseIteratorCurrent == m_list.rend()) ? NULL : *reverseIteratorCurrent; + ListOfObjects::iterator it = m_list.begin(); + std::advance(it, GetListIndex(startFrom)); + ListOfObjects::reverse_iterator rit(it); + rit = std::find_if(rit, m_list.rend(), ObjectComparison( elementType ) ); + return (rit == m_list.rend()) ? NULL : *rit; } Object *ObjectListInterface::GetListPrevious( const Object *listElement ) From 22bd50e301bfddb1617aaed081ef4ea16d0a01ab Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 30 Mar 2015 23:05:51 +0200 Subject: [PATCH 18/68] Adding element --- Verovio.xcodeproj/project.pbxproj | 6 ++++ emscripten/build.sh | 3 +- include/vrv/iomei.h | 3 ++ include/vrv/space.h | 48 +++++++++++++++++++++++++++++++ include/vrv/view.h | 1 + python/setup.py | 3 +- src/iomei.cpp | 27 ++++++++++++++++- src/mrest.cpp | 2 +- src/space.cpp | 33 +++++++++++++++++++++ src/view_element.cpp | 12 ++++++++ tools/CMakeLists.txt | 1 + 11 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 include/vrv/space.h create mode 100644 src/space.cpp diff --git a/Verovio.xcodeproj/project.pbxproj b/Verovio.xcodeproj/project.pbxproj index 84d11f75ae6..3ff7601c4c3 100644 --- a/Verovio.xcodeproj/project.pbxproj +++ b/Verovio.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 4DA3FCD419B61DB400CBDFE6 /* atts_cmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE28EF1940BCC100C76319 /* atts_cmn.cpp */; }; 4DA80D961A6ACF5D0089802D /* style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DA80D951A6ACF5D0089802D /* style.cpp */; }; 4DA80D971A6ACF5D0089802D /* style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DA80D951A6ACF5D0089802D /* style.cpp */; }; + 4DB3072F1AC9ED2500EE0982 /* space.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DB3072E1AC9ED2500EE0982 /* space.cpp */; }; 4DC34BA219BC4A71006175CD /* accid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DC34B9F19BC4A70006175CD /* accid.h */; }; 4DC34BA319BC4A71006175CD /* custos.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DC34BA019BC4A70006175CD /* custos.h */; }; 4DC34BA419BC4A71006175CD /* dot.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DC34BA119BC4A70006175CD /* dot.h */; }; @@ -223,6 +224,8 @@ 4D9A9C1D19A1DE2000028D93 /* syl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = syl.cpp; path = src/syl.cpp; sourceTree = ""; }; 4DA80D941A6940120089802D /* style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = style.h; path = include/vrv/style.h; sourceTree = ""; }; 4DA80D951A6ACF5D0089802D /* style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = style.cpp; path = src/style.cpp; sourceTree = ""; }; + 4DB3072D1AC9ED1800EE0982 /* space.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = space.h; path = include/vrv/space.h; sourceTree = ""; }; + 4DB3072E1AC9ED2500EE0982 /* space.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = space.cpp; path = src/space.cpp; sourceTree = ""; }; 4DC34B9F19BC4A70006175CD /* accid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = accid.h; path = include/vrv/accid.h; sourceTree = ""; }; 4DC34BA019BC4A70006175CD /* custos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = custos.h; path = include/vrv/custos.h; sourceTree = ""; }; 4DC34BA119BC4A70006175CD /* dot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dot.h; path = include/vrv/dot.h; sourceTree = ""; }; @@ -612,6 +615,8 @@ 8F59292318854BF800FE51AD /* note.h */, 8F086ED1188539540037FD8E /* rest.cpp */, 8F59292818854BF800FE51AD /* rest.h */, + 4DB3072E1AC9ED2500EE0982 /* space.cpp */, + 4DB3072D1AC9ED1800EE0982 /* space.h */, 4D9A9C1D19A1DE2000028D93 /* syl.cpp */, 4D9A9C1B199F576100028D93 /* syl.h */, 8F086ED9188539540037FD8E /* tuplet.cpp */, @@ -763,6 +768,7 @@ 8F086EEA188539540037FD8E /* durationinterface.cpp in Sources */, 8F086EEB188539540037FD8E /* toolkit.cpp in Sources */, 8F086EEC188539540037FD8E /* io.cpp in Sources */, + 4DB3072F1AC9ED2500EE0982 /* space.cpp in Sources */, 8F086EED188539540037FD8E /* iodarms.cpp in Sources */, 8F086EEE188539540037FD8E /* iomei.cpp in Sources */, 8F086EEF188539540037FD8E /* iomusxml.cpp in Sources */, diff --git a/emscripten/build.sh b/emscripten/build.sh index bee8e429467..127c800c76f 100755 --- a/emscripten/build.sh +++ b/emscripten/build.sh @@ -132,11 +132,12 @@ python $EMCC $CHATTY \ $VEROVIO_ROOT/src/rest.cpp \ $VEROVIO_ROOT/src/scoredef.cpp \ $VEROVIO_ROOT/src/slur.cpp \ + $VEROVIO_ROOT/src/space.cpp \ $VEROVIO_ROOT/src/staff.cpp \ $VEROVIO_ROOT/src/style.cpp \ $VEROVIO_ROOT/src/svgdevicecontext.cpp \ $VEROVIO_ROOT/src/syl.cpp \ - $VEROVIO_ROOT/src/system.cpp \ + $VEROVIO_ROOT/src/system.cpp \ $VEROVIO_ROOT/src/tie.cpp \ $VEROVIO_ROOT/src/timeinterface.cpp \ $VEROVIO_ROOT/src/toolkit.cpp \ diff --git a/include/vrv/iomei.h b/include/vrv/iomei.h index 9d03b6af129..5edff34245d 100644 --- a/include/vrv/iomei.h +++ b/include/vrv/iomei.h @@ -43,6 +43,7 @@ class Rdg; class Rest; class ScoreDef; class Slur; +class Space; class Staff; class Syl; class System; @@ -131,6 +132,7 @@ class MeiOutput: public FileOutputStream void WriteMeiMultiRest( pugi::xml_node currentNode, MultiRest *multiRest ); void WriteMeiNote( pugi::xml_node currentNode, Note *note ); void WriteMeiRest( pugi::xml_node currentNode, Rest *rest ); + void WriteMeiSpace( pugi::xml_node currentNode, Space *space ); void WriteMeiTuplet( pugi::xml_node currentNode, Tuplet *tuplet ); ///@} @@ -289,6 +291,7 @@ class MeiInput: public FileInputStream bool ReadMeiMultiRest( Object *parent, pugi::xml_node multiRest ); bool ReadMeiNote( Object *parent, pugi::xml_node note ); bool ReadMeiRest( Object *parent, pugi::xml_node rest ); + bool ReadMeiSpace( Object *parent, pugi::xml_node space ); bool ReadMeiSyl( Object *parent, pugi::xml_node syl ); bool ReadMeiTuplet( Object *parent, pugi::xml_node tuplet ); bool ReadMeiVerse( Object *parent, pugi::xml_node verse ); diff --git a/include/vrv/space.h b/include/vrv/space.h new file mode 100644 index 00000000000..832be52b634 --- /dev/null +++ b/include/vrv/space.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: space.h +// Author: Laurent Pugin +// Created: 2015 +// Copyright (c) Authors and others. All rights reserved. +///////////////////////////////////////////////////////////////////////////// + + +#ifndef __VRV_SPACE_H__ +#define __VRV_SPACE_H__ + +#include "durationinterface.h" +#include "layerelement.h" + +namespace vrv { + +//---------------------------------------------------------------------------- +// Space +//---------------------------------------------------------------------------- + +/** + * This class models the MEI + */ +class Space: public LayerElement, public DurationInterface +{ +public: + /** + * @name Constructors, destructors, reset and class name methods + * Reset method reset all attribute classes + */ + ///@{ + Space( ); + virtual ~Space(); + virtual void Reset(); + virtual std::string GetClassName( ){ return "Space"; }; ; + ///@} + +private: + +public: + +private: + +}; + +} // namespace vrv + +#endif diff --git a/include/vrv/view.h b/include/vrv/view.h index 793a6574702..4532bec0123 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -245,6 +245,7 @@ class View void DrawMultiRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawNote( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); + void DrawSpace( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawSyl( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawTie( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawTuplet( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); diff --git a/python/setup.py b/python/setup.py index 3ae2962f0f4..3b584db2fef 100755 --- a/python/setup.py +++ b/python/setup.py @@ -51,7 +51,8 @@ '../src/view_tuplet.cpp', '../src/rest.cpp', '../src/scoredef.cpp', - '../src/slur.cpp', + '../src/slur.cpp', + '../src/space.cpp', '../src/staff.cpp', '../src/style.cpp', '../src/svgdevicecontext.cpp', diff --git a/src/iomei.cpp b/src/iomei.cpp index 0b14512471d..fe2c26ab06f 100644 --- a/src/iomei.cpp +++ b/src/iomei.cpp @@ -32,6 +32,7 @@ #include "page.h" #include "rest.h" #include "slur.h" +#include "space.h" #include "staff.h" #include "syl.h" #include "system.h" @@ -216,6 +217,10 @@ bool MeiOutput::WriteObject( Object *object ) m_currentNode = m_currentNode.append_child("rest"); WriteMeiRest( m_currentNode, dynamic_cast(object) ); } + else if (dynamic_cast(object)) { + m_currentNode = m_currentNode.append_child("space"); + WriteMeiSpace( m_currentNode, dynamic_cast(object) ); + } else if (dynamic_cast(object)) { m_currentNode = m_currentNode.append_child("tuplet"); WriteMeiTuplet( m_currentNode, dynamic_cast(object) ); @@ -583,6 +588,13 @@ void MeiOutput::WriteMeiRest( pugi::xml_node currentNode, Rest *rest ) WritePositionInterface(currentNode, rest); return; } + +void MeiOutput::WriteMeiSpace( pugi::xml_node currentNode, Space *space ) +{ + WriteLayerElement( currentNode, space ); + WriteDurationInterface(currentNode, space); + return; +} void MeiOutput::WriteMeiTuplet( pugi::xml_node currentNode, Tuplet *tuplet ) { @@ -1367,6 +1379,9 @@ bool MeiInput::ReadMeiLayerChildren( Object *parent, pugi::xml_node parentNode, else if ( elementName == "multiRest" ) { success = ReadMeiMultiRest( parent, xmlElement ); } + else if ( elementName == "space" ) { + success = ReadMeiSpace( parent, xmlElement ); + } else if ( elementName == "syl" ) { success = ReadMeiSyl( parent, xmlElement ); } @@ -1573,7 +1588,6 @@ bool MeiInput::ReadMeiNote( Object *parent, pugi::xml_node note ) return ReadMeiLayerChildren(vrvNote, note, vrvNote); } - bool MeiInput::ReadMeiRest( Object *parent, pugi::xml_node rest ) { Rest *vrvRest = new Rest(); @@ -1586,6 +1600,17 @@ bool MeiInput::ReadMeiRest( Object *parent, pugi::xml_node rest ) return true; } +bool MeiInput::ReadMeiSpace( Object *parent, pugi::xml_node space ) +{ + Space *vrvSpace = new Space(); + ReadLayerElement(space, vrvSpace); + + ReadDurationInterface(space, vrvSpace); + + AddLayerElement(parent, vrvSpace); + return true; +} + bool MeiInput::ReadMeiSyl( Object *parent, pugi::xml_node syl) { Syl *vrvSyl = new Syl(); diff --git a/src/mrest.cpp b/src/mrest.cpp index c4d57ebbb92..832b0f7409b 100644 --- a/src/mrest.cpp +++ b/src/mrest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: mrest.h +// Name: mrest.cpp // Author: Laurent Pugin // Created: 2014 // Copyright (c) Authors and others. All rights reserved. diff --git a/src/space.cpp b/src/space.cpp new file mode 100644 index 00000000000..4e8eaaa7d88 --- /dev/null +++ b/src/space.cpp @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: space.cpp +// Author: Laurent Pugin +// Created: 2015 +// Copyright (c) Authors and others. All rights reserved. +///////////////////////////////////////////////////////////////////////////// + + +#include "space.h" + +namespace vrv { + +//---------------------------------------------------------------------------- +// Space +//---------------------------------------------------------------------------- + +Space::Space( ): + LayerElement("space-") +{ + Reset(); +} + +Space::~Space() +{ +} + +void Space::Reset() +{ + LayerElement::Reset(); + DurationInterface::Reset(); +} + +} // namespace vrv diff --git a/src/view_element.cpp b/src/view_element.cpp index 1814032fc66..a933e2299e6 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -33,6 +33,7 @@ #include "note.h" #include "rest.h" #include "slur.h" +#include "space.h" #include "smufl.h" #include "staff.h" #include "style.h" @@ -126,6 +127,9 @@ void View::DrawLayerElement( DeviceContext *dc, LayerElement *element, Layer *la else if (dynamic_cast(element)) { DrawTie(dc, element, layer, staff, measure); } + else if (dynamic_cast(element)) { + DrawSpace(dc, element, layer, staff, measure); + } else if (dynamic_cast(element)) { DrawSyl(dc, element, layer, staff, measure); } @@ -1563,6 +1567,14 @@ void View::DrawAccid( DeviceContext *dc, LayerElement *element, Layer *layer, St dc->EndGraphic(element, this ); } +void View::DrawSpace(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure) { + + assert(layer); // Pointer to layer cannot be NULL" + assert(staff); // Pointer to staff cannot be NULL" + + dc->StartGraphic( element, "", element->GetUuid() ); + dc->EndGraphic(element, this ); +} void View::DrawCustos( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ) { diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index aa56538e48e..1486541e975 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -55,6 +55,7 @@ add_executable (verovio ../src/rest.cpp ../src/scoredef.cpp ../src/slur.cpp + ../src/space.cpp ../src/staff.cpp ../src/style.cpp ../src/svgdevicecontext.cpp From bebca9b602db6ec6efa1182a3b0cae9d28cfbfdd Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 30 Mar 2015 23:11:53 +0200 Subject: [PATCH 19/68] Basic cross-staff --- include/vrv/durationinterface.h | 3 ++- libmei/atts_shared.cpp | 12 ++++++------ libmei/atts_shared.h | 6 +++--- src/durationinterface.cpp | 4 +++- src/iomei.cpp | 2 ++ src/view_element.cpp | 11 ++++++++++- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/include/vrv/durationinterface.h b/include/vrv/durationinterface.h index bd1bb01f019..c0792c25a65 100644 --- a/include/vrv/durationinterface.h +++ b/include/vrv/durationinterface.h @@ -31,7 +31,8 @@ class DurationInterface: public AttDurationMusical, public AttDurationPerformed, public AttDurationRatio, - public AttFermatapresent + public AttFermatapresent, + public AttStaffident { public: /** diff --git a/libmei/atts_shared.cpp b/libmei/atts_shared.cpp index d34aa809327..b4c8fc28a12 100644 --- a/libmei/atts_shared.cpp +++ b/libmei/atts_shared.cpp @@ -5423,13 +5423,13 @@ AttStaffident::~AttStaffident() { } void AttStaffident::ResetStaffident() { - m_staff = ""; + m_staff = 0; } bool AttStaffident::ReadStaffident( pugi::xml_node element ) { bool hasAttribute = false; if (element.attribute("staff")) { - this->SetStaff(StrToStr(element.attribute("staff").value())); + this->SetStaff(StrToInt(element.attribute("staff").value())); element.remove_attribute("staff"); hasAttribute = true; } @@ -5439,7 +5439,7 @@ bool AttStaffident::ReadStaffident( pugi::xml_node element ) { bool AttStaffident::WriteStaffident( pugi::xml_node element ) { bool wroteAttribute = false; if (this->HasStaff()) { - element.append_attribute("staff") = StrToStr(this->GetStaff()).c_str(); + element.append_attribute("staff") = IntToStr(this->GetStaff()).c_str(); wroteAttribute = true; } return wroteAttribute; @@ -5447,7 +5447,7 @@ bool AttStaffident::WriteStaffident( pugi::xml_node element ) { bool AttStaffident::HasStaff( ) { - return (m_staff != ""); + return (m_staff != 0); } @@ -7956,7 +7956,7 @@ bool Att::SetShared( Object *element, std::string attrType, std::string attrValu if (dynamic_cast(element) ) { AttStaffident *att = dynamic_cast(element); if (attrType == "staff") { - att->SetStaff(att->StrToStr(attrValue)); + att->SetStaff(att->StrToInt(attrValue)); return true; } } @@ -9073,7 +9073,7 @@ void Att::GetShared( Object *element, ArrayOfStrAttr *attributes ) { if (dynamic_cast(element) ) { AttStaffident *att = dynamic_cast(element); if (att->HasStaff()) { - attributes->push_back(std::make_pair("staff", att->StrToStr(att->GetStaff()))); + attributes->push_back(std::make_pair("staff", att->IntToStr(att->GetStaff()))); } } if (dynamic_cast(element) ) { diff --git a/libmei/atts_shared.h b/libmei/atts_shared.h index 96570dd2fbc..2ac1cd467ae 100644 --- a/libmei/atts_shared.h +++ b/libmei/atts_shared.h @@ -4594,8 +4594,8 @@ class AttStaffident: public Att * to the default value) **/ ///@{ - void SetStaff(std::string staff_) { m_staff = staff_; }; - std::string GetStaff() const { return m_staff; }; + void SetStaff(int staff_) { m_staff = staff_; }; + int GetStaff() const { return m_staff; }; bool HasStaff( ); ///@} @@ -4606,7 +4606,7 @@ class AttStaffident: public Att * applies. * Mandatory when applicable. **/ - std::string m_staff; + int m_staff; /* include */ }; diff --git a/src/durationinterface.cpp b/src/durationinterface.cpp index d919602b039..9c27c1a19d6 100644 --- a/src/durationinterface.cpp +++ b/src/durationinterface.cpp @@ -33,7 +33,8 @@ DurationInterface::DurationInterface(): AttDurationMusical(), AttDurationPerformed(), AttDurationRatio(), - AttFermatapresent() + AttFermatapresent(), + AttStaffident() { Reset(); } @@ -52,6 +53,7 @@ void DurationInterface::Reset() ResetDurationPerformed(); ResetDurationRatio(); ResetFermatapresent(); + ResetStaffident(); } double DurationInterface::GetAlignmentDuration( int num, int numbase ) diff --git a/src/iomei.cpp b/src/iomei.cpp index fe2c26ab06f..a391d956ab3 100644 --- a/src/iomei.cpp +++ b/src/iomei.cpp @@ -628,6 +628,7 @@ void MeiOutput::WriteDurationInterface(pugi::xml_node element, vrv::DurationInte interface->WriteDurationPerformed(element); interface->WriteDurationRatio(element); interface->WriteFermatapresent(element); + interface->WriteStaffident(element); } void MeiOutput::WritePitchInterface(pugi::xml_node element, vrv::PitchInterface *interface) @@ -1663,6 +1664,7 @@ bool MeiInput::ReadDurationInterface(pugi::xml_node element, DurationInterface * interface->ReadDurationPerformed(element); interface->ReadDurationRatio(element); interface->ReadFermatapresent(element); + interface->ReadStaffident(element); return true; } diff --git a/src/view_element.cpp b/src/view_element.cpp index a933e2299e6..b80cc79df69 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -154,7 +154,16 @@ void View::DrawDurationElement( DeviceContext *dc, LayerElement *element, Layer DurationInterface *durElement = dynamic_cast(element); if ( !durElement ) return; - + + if (durElement->HasStaff()) { + AttCommonNComparison comparisonFirst( &typeid(Staff), durElement->GetStaff() ); + Staff *crossStaff = dynamic_cast(measure->FindChildByAttComparison(&comparisonFirst, 1)); + if (crossStaff) staff = crossStaff; + else LogWarning("Could not get the cross staff reference '%d' for element '%s'", durElement->GetStaff(), element->GetUuid().c_str()); + element->SetDrawingY( staff->GetDrawingY() ); + // If we have a @layer we probably also want to change the layer element (for getting the right clef if different) + } + if (dynamic_cast(element)) { dc->StartGraphic( element, "", element->GetUuid() ); From 294ea0fa21cdf9724c5a5157779e6424d1a96ac2 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 31 Mar 2015 08:27:30 +0200 Subject: [PATCH 20/68] Making intermediate clef cue sized --- src/view_element.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index 1814032fc66..335b1094036 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1352,13 +1352,16 @@ void View::DrawClef( DeviceContext *dc, LayerElement *element, Layer *layer, Sta break; } - a -= m_doc->m_drawingUnit[staff->staffSize] * 2; - if (clef->m_cueSize) - a += m_doc->m_drawingUnit[staff->staffSize]; - - DrawSmuflCode ( dc, a, b, sym, staff->staffSize, clef->m_cueSize ); + bool cueSize = clef->m_cueSize; + // force cue size for intermediate clefs + if (clef->GetFirstParent(&typeid(Layer))) cueSize = true; + + if (!cueSize) + a -= m_doc->m_drawingUnit[staff->staffSize] * 2; + + DrawSmuflCode ( dc, a, b, sym, staff->staffSize, cueSize ); - dc->EndGraphic(element, this ); //RZ + dc->EndGraphic(element, this ); } void View::DrawMeterSigFigures( DeviceContext *dc, int x, int y, int num, int numBase, Staff *staff) From 2632aafb96194f3b082c6696cf6999140039601e Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 31 Mar 2015 09:47:12 +0200 Subject: [PATCH 21/68] Fixing multi rest shape and right margin --- doc/tests/pae/6_mixed/measure_rest_and_keysig_change.pae | 2 +- src/doc.cpp | 2 +- src/view_element.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/tests/pae/6_mixed/measure_rest_and_keysig_change.pae b/doc/tests/pae/6_mixed/measure_rest_and_keysig_change.pae index f1373d63516..a2f5a45bb8c 100644 --- a/doc/tests/pae/6_mixed/measure_rest_and_keysig_change.pae +++ b/doc/tests/pae/6_mixed/measure_rest_and_keysig_change.pae @@ -1,4 +1,4 @@ @clef:G-2 @keysig:xF @timesig:3/8 -@data:=25//$xFCG @c 2-4.-'8E/{6AGFE}{8A''C}'B''4D{6C'B}/{''DC'BA}{''8EA} \ No newline at end of file +@data:=25//=5//$xFCG @c 2-4.-'8E/{6AGFE}{8A''C}'B''4D{6C'B}/{''DC'BA}{''8EA} \ No newline at end of file diff --git a/src/doc.cpp b/src/doc.cpp index 85dcbce570e..f76d395d7dd 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -395,7 +395,7 @@ short Doc::GetRightMargin( const std::type_info *elementType ) else if (typeid(Barline) == *elementType) return 30; else if (typeid(BarlineAttr) == *elementType) return 0; else if (typeid(MRest) == *elementType) return 0; - else if (typeid(MultiRest) == *elementType) return 0; + else if (typeid(MultiRest) == *elementType) return 30; //else if (typeid(Note) == *elementType) return 10; return 10; } diff --git a/src/view_element.cpp b/src/view_element.cpp index 335b1094036..9e619935753 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -695,7 +695,7 @@ void View::DrawMultiRest(DeviceContext *dc, LayerElement *element, Layer *layer, //Draw the to lines at beginning and end // make it 8 pixesl longers, and 4 pixels width - int border = m_doc->m_drawingUnit[staff->staffSize] / 2; + int border = m_doc->m_drawingUnit[staff->staffSize]; DrawVerticalLine(dc, y1 - border, y2 + border, x1, m_doc->m_style->m_stemWidth * 2); DrawVerticalLine(dc, y1 - border, y2 + border, x2, m_doc->m_style->m_stemWidth * 2); From 55c9ff1b4cd0f0d30cf7d131d3430fc3aa7ade38 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Wed, 1 Apr 2015 10:51:34 -0400 Subject: [PATCH 22/68] Fixed: null accidental glitch, beamed notes drawn twice glitch -Fix to prevent NULL accidentals as per line notes from 8fe2191 -Fix to prevent beamed notes from being drawn twice as per line notes from c540ad7 --- src/chord.cpp | 2 +- src/view_beam.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/chord.cpp b/src/chord.cpp index b58c4814ca5..4d5f722dd63 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -163,7 +163,7 @@ void Chord::ResetAccidList() ListOfObjects* childList = this->GetList(this); //make sure it's initialized for (ListOfObjects::reverse_iterator it = childList->rbegin(); it != childList->rend(); it++) { Note *note = dynamic_cast(*it); - if (note->HasAccid()) { + if (note->m_drawingAccid != NULL) { m_accidList.push_back(note); } } diff --git a/src/view_beam.cpp b/src/view_beam.cpp index 3ad2db715bf..653dada9784 100644 --- a/src/view_beam.cpp +++ b/src/view_beam.cpp @@ -309,7 +309,7 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff /******************************************************************/ // Draw notes for all objects in the beam now that stem direction is calculated - for (i = 0; i < elementCount; i++) { + /*for (i = 0; i < elementCount; i++) { if ((*beamElementCoords)[i]->m_element->IsChord()) { Chord *chord = dynamic_cast((*beamElementCoords)[i]->m_element); ListOfObjects *noteList = chord->GetList(chord); @@ -331,7 +331,7 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff DrawNote(dc, dynamic_cast((*beamElementCoords)[i]->m_element), layer, staff, measure); dc->EndResumedGraphic( dynamic_cast((*beamElementCoords)[i]->m_element), this ); } - } + }*/ /******************************************************************/ // Calculate the stem lengths and draw them From 3abe496bc3256845928fb9475c2700e10ee990ae Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 1 Apr 2015 17:21:26 +0200 Subject: [PATCH 23/68] Tidying up --- src/view_beam.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/view_beam.cpp b/src/view_beam.cpp index 3ad2db715bf..fa5a4eadb5a 100644 --- a/src/view_beam.cpp +++ b/src/view_beam.cpp @@ -200,18 +200,18 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff avgY += (*beamElementCoords)[i]->m_y; } } - yExtreme = (abs(high - verticalCenter) > abs(low - verticalCenter) ? high : low); - - avgY /= elementCount; /******************************************************************/ // Set the stem direction + yExtreme = (abs(high - verticalCenter) > abs(low - verticalCenter) ? high : low); + avgY /= elementCount; + stemDir = layer->GetDrawingStemDir(); //force layer direction if it exists + if (stemDir == STEMDIRECTION_NONE) { - if (beamHasChord) stemDir = (yExtreme > verticalCenter ? STEMDIRECTION_down : STEMDIRECTION_up); //if it has a chord, go by the most extreme position - else if ( avgY < verticalCenter ) stemDir = STEMDIRECTION_up; //otherwise go by average - else stemDir = STEMDIRECTION_down; + if (beamHasChord) stemDir = (yExtreme < verticalCenter) ? STEMDIRECTION_up : STEMDIRECTION_down; //if it has a chord, go by the most extreme position + else stemDir = (avgY < verticalCenter) ? STEMDIRECTION_up : STEMDIRECTION_down; //otherwise go by average } beam->SetDrawingStemDir(stemDir); @@ -227,6 +227,7 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff } } + // We look only at the last note for checking if cuesized. Somehow arbitrarily if ((*beamElementCoords)[last]->m_element->m_cueSize == false) { beamWidthBlack = m_doc->m_drawingBeamWidth[staff->staffSize]; beamWidthWhite = m_doc->m_drawingBeamWhiteWidth[staff->staffSize]; @@ -266,18 +267,12 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff //change the stem dir for all objects if ( (*beamElementCoords)[i]->m_element->IsNote() ) { ((Note*)(*beamElementCoords)[i]->m_element)->m_drawingStemDir = stemDir; - (*beamElementCoords)[i]->m_yBeam = (*beamElementCoords)[i]->m_y + verticalShift; } - else if ( (*beamElementCoords)[i]->m_element->IsChord() ) { ((Chord*)(*beamElementCoords)[i]->m_element)->SetDrawingStemDir(stemDir); - (*beamElementCoords)[i]->m_yBeam = (*beamElementCoords)[i]->m_y + verticalShift; - } - - else { - (*beamElementCoords)[i]->m_yBeam = (*beamElementCoords)[i]->m_y + verticalShift; } - + + (*beamElementCoords)[i]->m_yBeam = (*beamElementCoords)[i]->m_y + verticalShift; (*beamElementCoords)[i]->m_x += dx[(*beamElementCoords)[i]->m_element->m_cueSize]; s_y += (*beamElementCoords)[i]->m_yBeam; @@ -287,7 +282,6 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff s_xy += (*beamElementCoords)[i]->m_x * (*beamElementCoords)[i]->m_yBeam; } - y1 = elementCount * s_xy - s_x * s_y; xr = elementCount * s_x2 - s_x * s_x; From 91b4daa79680aaab6b574b544b980134f4da8824 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 1 Apr 2015 18:13:37 +0200 Subject: [PATCH 24/68] Remove code duplication --- src/note.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/note.cpp b/src/note.cpp index e60a3ccfb2c..bb381dd074d 100644 --- a/src/note.cpp +++ b/src/note.cpp @@ -122,20 +122,7 @@ bool Note::IsClusterExtreme() bool Note::HasDrawingStemDir() { - Chord* chordParent = dynamic_cast(this->GetFirstParent( &typeid( Chord ), MAX_CHORD_DEPTH)); - Beam* beamParent = dynamic_cast(this->GetFirstParent( &typeid( Beam ), MAX_BEAM_DEPTH)); - if( chordParent && chordParent->GetDrawingStemDir() != STEMDIRECTION_NONE ) - { - return chordParent->GetDrawingStemDir(); - } - else if( beamParent && beamParent->GetDrawingStemDir() != STEMDIRECTION_NONE ) - { - return beamParent->GetDrawingStemDir(); - } - else - { - return this->HasStemDir(); - } + return (this->GetDrawingStemDir() != STEMDIRECTION_NONE); } data_STEMDIRECTION Note::GetDrawingStemDir() From 8c9835352b1a6fc79e387c40038432eb561c7530 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 2 Apr 2015 07:35:12 +0200 Subject: [PATCH 25/68] Looking at multiple stem directions --- src/view_beam.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/view_beam.cpp b/src/view_beam.cpp index fa5a4eadb5a..1b646912a72 100644 --- a/src/view_beam.cpp +++ b/src/view_beam.cpp @@ -35,6 +35,7 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff bool changingDur = OFF; bool beamHasChord = OFF; + bool hasMultipleStemDir = OFF; data_STEMDIRECTION stemDir = STEMDIRECTION_NONE; // position variables @@ -110,6 +111,8 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff // This could be moved to Beam::InitCoord for optimization because there should be no // need of redoing it everytime it is drawn. + data_STEMDIRECTION currentStemDir; + ListOfObjects::iterator iter = beamChildren->begin(); do { // Beam list should contain only DurationInterface objects @@ -138,6 +141,16 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff // Skip rests if (current->IsNote() || current->IsChord()) { + // look at the stemDir to see if we have multiple stem Dir + if (!hasMultipleStemDir) { + currentStemDir = dynamic_cast(current)->GetStemDir(); + if (currentStemDir != STEMDIRECTION_NONE) { + if ((stemDir != STEMDIRECTION_NONE) && (stemDir != currentStemDir)) { + hasMultipleStemDir = ON; + } + } + stemDir = currentStemDir; + } // keep the shortest dur in the beam shortestDur = std::max(currentDur,shortestDur); // check if we have more than duration in the beam @@ -207,8 +220,10 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff yExtreme = (abs(high - verticalCenter) > abs(low - verticalCenter) ? high : low); avgY /= elementCount; - stemDir = layer->GetDrawingStemDir(); //force layer direction if it exists + // If we have one stem direction in the beam, then don't look at the layer + if (stemDir != STEMDIRECTION_NONE) stemDir = layer->GetDrawingStemDir(); // force layer direction if it exists + // Automatic stem direction if nothing in the notes or in the layer if (stemDir == STEMDIRECTION_NONE) { if (beamHasChord) stemDir = (yExtreme < verticalCenter) ? STEMDIRECTION_up : STEMDIRECTION_down; //if it has a chord, go by the most extreme position else stemDir = (avgY < verticalCenter) ? STEMDIRECTION_up : STEMDIRECTION_down; //otherwise go by average From 41621c4d54c8e47a60d26c9c436553f16fd076a9 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Sun, 5 Apr 2015 11:08:49 +0200 Subject: [PATCH 26/68] Fixing compilation warning and ignoring python toolkit generated files --- include/vrv/vrvdef.h | 2 +- src/view_page.cpp | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index 93b08e1e580..6508c093e42 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -22,7 +22,7 @@ namespace vrv { class Object; class AttComparison; class Note; -struct BeamElementCoord; +class BeamElementCoord; typedef std::vector ArrayOfObjects; diff --git a/src/view_page.cpp b/src/view_page.cpp index 73c8b4a7b7b..f31c27adeef 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -897,7 +897,7 @@ void View::DrawTimeSpanningElement( DeviceContext *dc, DocObject *element, Syste } void View::DrawTieOrSlur( DeviceContext *dc, MeasureElement *element, int x1, int x2, Staff *staff, - char spanningType, DocObject *graphic ) + char spanningType, DocObject *graphic ) { assert(dynamic_cast(element) || dynamic_cast(element)); // Element must be a Tie or a Slur TimeSpanningInterface *interface = dynamic_cast(element); @@ -941,7 +941,8 @@ void View::DrawTieOrSlur( DeviceContext *dc, MeasureElement *element, int x1, in // This is the case when the tie is split over two system of two pages. // In this case, we are now drawing its beginning to the end of the measure (i.e., the last aligner) else if ( spanningType == SPANNING_START ) { - y1 = y2 = note1->GetDrawingY(); + y1 = note1->GetDrawingY(); + y2 = y1; // m_drawingStemDir it not set properly in beam - needs to be fixed. if (dynamic_cast(note1)) noteStemDir = dynamic_cast(note1)->m_drawingStemDir; else if (dynamic_cast(note1)) noteStemDir = dynamic_cast(note1)->GetDrawingStemDir(); @@ -949,7 +950,8 @@ void View::DrawTieOrSlur( DeviceContext *dc, MeasureElement *element, int x1, in } // Now this is the case when the tie is split but we are drawing the end of it else if ( spanningType == SPANNING_END ) { - y1 = y2 = note2->GetDrawingY(); + y1 = note2->GetDrawingY(); + y2 = y1; x2 = note2->GetDrawingX(); if (dynamic_cast(note2)) noteStemDir = dynamic_cast(note2)->m_drawingStemDir; else if (dynamic_cast(note2)) noteStemDir = dynamic_cast(note2)->GetDrawingStemDir(); @@ -958,6 +960,7 @@ void View::DrawTieOrSlur( DeviceContext *dc, MeasureElement *element, int x1, in // Finally else { LogDebug("Slur across an entire system is not supported"); + return; } assert( dynamic_cast(note1) || dynamic_cast(note1)); From 6728f6a5390e9bc20b75b1c8e8fe4403608c1036 Mon Sep 17 00:00:00 2001 From: ahwitz Date: Wed, 8 Apr 2015 12:22:04 -0400 Subject: [PATCH 27/68] Doc: commented/renamed variables in accid drawing Refs line note comments on 44bd999 -Moved some variables to a slightly tighter scope to save time -accidClusters -> accidClusterStarts for clarity -Cleaned up function call for CalculateAccidX -A lot more commenting in DrawChord --- src/view_element.cpp | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index 98f675a1ec0..fd2d6e98653 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1170,41 +1170,51 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St /************ Accidentals ************/ //navigate through list of notes, starting with outside and working in - //set the default x position: only non-default case is a down-stemmed non-cluster which needs one more note diameter of space - int xAccid = chord->GetDrawingX() - (radius * 2) - fullUnit; - if (chord->GetDrawingStemDir() == STEMDIRECTION_down && chord->m_clusters.size() > 0) xAccid -= (radius * 2); - - int fwIdx = 0; - int idx, bwIdx; - chord->ResetAccidList(); std::vector noteList = chord->m_accidList; int size = (int)noteList.size(); if (size > 0) { + //set the default x position + int xAccid = chord->GetDrawingX() - (radius * 2) - fullUnit; + + //if chord is a down-stemmed non-cluster, it needs one more note diameter of space + if ((chord->GetDrawingStemDir() == STEMDIRECTION_down) && (chord->m_clusters.size() > 0)) + { + xAccid -= (radius * 2); + } + + int fwIdx, idx, bwIdx; + + //reset the boolean 2d vector chord->ResetAccidSpace(fullUnit); + std::vector accidClusterStarts; - std::vector accidClusters; - + //iterate through the list of notes with accidentals for(idx = 0; idx < size; idx++) { Accid *curAccid = noteList[idx]->m_drawingAccid; - //false as the last parameter for CalcAccidX will see if there are any vertical conflicts without setting anything - if (CalculateAccidX(staff, curAccid, chord, false) > 0) + + //if the note does not need to be moved, save a new cluster start position + if (CalculateAccidX(staff, curAccid, chord, false)) { - accidClusters.push_back(idx); + accidClusterStarts.push_back(idx); } } chord->ResetAccidSpace(fullUnit); - int accidSize = (int)accidClusters.size(); + int accidSize = (int)accidClusterStarts.size(); + //for each note that conflicts for(idx = 0; idx < accidSize; idx++) { - fwIdx = accidClusters[idx]; + //set fwIdx to the start of the cluster + fwIdx = accidClusterStarts[idx]; + //if this is the last cluster, set bwIdx to the last note in the chord if (idx == accidSize - 1) bwIdx = size - 1; - else bwIdx = accidClusters[idx + 1] - 1; + //otherwise, set bwIdx to one before the beginning of the next cluster + else bwIdx = accidClusterStarts[idx + 1] - 1; //if it's even, this will catch the overlap; if it's odd, there's an if in the middle there while (fwIdx <= bwIdx) From bfb921d15424afc8285f5c93aff5aacd6ba20d6c Mon Sep 17 00:00:00 2001 From: ahwitz Date: Wed, 8 Apr 2015 16:16:22 -0400 Subject: [PATCH 28/68] Fixed: accidSpace array now has the correct amount of horizontal locations This is the most time I've ever spent on a 4-character commit. Assertions and error-checking will come in the next commit if deemed necessary. --- src/chord.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chord.cpp b/src/chord.cpp index 4d5f722dd63..fd89649e2e0 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -180,7 +180,7 @@ void Chord::ResetAccidSpace(int fullUnit) //make m_accidSpace into a 2D vector of size (vertical half-units, most possible horizontal halfunits) int idx, setIdx; - int size = (int)m_accidList.size(); + int size = (int)m_accidList.size() + 1; std::vector *accidLine; //top y position - bottom y position in half-units int rows = ((m_accidList[0]->GetDrawingY() - m_accidList[m_accidList.size() - 1]->GetDrawingY()) / halfUnit); From f8c08d1e558d372e250732e2d2f2c67edf78e82c Mon Sep 17 00:00:00 2001 From: ahwitz Date: Wed, 8 Apr 2015 17:14:19 -0400 Subject: [PATCH 29/68] New: assertion in CalculateAccidX for safety. --- src/view_element.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/view_element.cpp b/src/view_element.cpp index fd2d6e98653..9dc9d788895 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1489,6 +1489,8 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool save) }; } + assert(currentX + ACCID_WIDTH <= xLength); + //move the accidental position if requested if (save) { From a8560be71d07c7268ac52d382c509d1cbf71bbe3 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Fri, 10 Apr 2015 11:24:10 -0400 Subject: [PATCH 30/68] Doc: better documentation for accidSpace calculations -Re-organized code in header files -Added variables to keep track of top/bottom position represented by m_accidSpace -Commented and reorganized accidSpace functions in chord.cpp and view_element.cpp --- include/vrv/chord.h | 10 ++++++ include/vrv/view.h | 8 +++-- include/vrv/vrvdef.h | 2 +- src/chord.cpp | 43 +++++++++++++++++--------- src/view_element.cpp | 73 ++++++++++++++++++++++++-------------------- 5 files changed, 86 insertions(+), 50 deletions(-) diff --git a/include/vrv/chord.h b/include/vrv/chord.h index 3caaa7b944a..2ce1eee21be 100644 --- a/include/vrv/chord.h +++ b/include/vrv/chord.h @@ -64,6 +64,11 @@ class Chord: public LayerElement, public ObjectListInterface, public DurationInt * Returns list of notes that have accidentals */ void ResetAccidList(); + + /** + * Prepares a 2D grid of booleans to track where accidentals are placed. + * Further documentation in chord.cpp comments. + */ void ResetAccidSpace(int staffSize); /** @@ -113,8 +118,13 @@ class Chord: public LayerElement, public ObjectListInterface, public DurationInt * Positions of dots in the chord to avoid overlapping */ std::list m_dots; + + /** + * Variables related to preventing overlapping in the X dimension for accidentals + */ std::vector m_accidList; std::vector< std::vector > m_accidSpace; + int m_accidSpaceTop, m_accidSpaceBot, m_accidSpaceLeft; }; } // namespace vrv diff --git a/include/vrv/view.h b/include/vrv/view.h index 793a6574702..3466d551217 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -350,10 +350,14 @@ class View bool IsOnStaffLine ( int y, Staff *staff ); /** - * Internal methods for calculating spacing chords + * Make sure dots on chords are vertically aligned correctly */ void PrepareChordDots ( DeviceContext *dc, Chord *chord, int x, int y, unsigned char dots, Staff *staff ); - bool CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool save); + + /** + * Changes and/or calculates the horizontal alignment of accidentals to prevent overlapping + */ + bool CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjustHorizontally); /** * Swap the to points passed as reference. diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index 6508c093e42..d031c3f1147 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -176,7 +176,7 @@ enum ClefId { perc = CLEFSHAPE_perc << 8 | 1 }; -//Used in spacing accidentals on complex chords +//Width (in half-drawing units) of an accidental; used to prevent overlap on complex chords #define ACCID_WIDTH 4 } // namespace vrv diff --git a/src/chord.cpp b/src/chord.cpp index fd89649e2e0..52a3767c4da 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -169,32 +169,47 @@ void Chord::ResetAccidList() } } +/** + * Creates a 2D grid of width (# of accidentals + 1) * 4 and of height (highest accid - lowest accid) / (half a drawing unit) + */ void Chord::ResetAccidSpace(int fullUnit) { m_accidSpace.clear(); - + m_accidSpaceBot = 0; + m_accidSpaceTop = 0; + + //if there are no accidentals in the chord, we don't need to plan for any if (m_accidList.size() == 0) return; + //dimensional units, other variables int halfUnit = fullUnit / 2; int doubleUnit = fullUnit * 2; - - //make m_accidSpace into a 2D vector of size (vertical half-units, most possible horizontal halfunits) int idx, setIdx; - int size = (int)m_accidList.size() + 1; - std::vector *accidLine; - //top y position - bottom y position in half-units - int rows = ((m_accidList[0]->GetDrawingY() - m_accidList[m_accidList.size() - 1]->GetDrawingY()) / halfUnit); - m_accidSpace.resize(std::max(rows, ACCID_WIDTH)); - //each line needs to be 4 times the number of notes in case every one overlaps fully - int lineLength = (doubleUnit*size) / halfUnit; + /* + * Prepare for the situation where every accidental conflicts horizontally: + * -Assume each accidental to be 2 drawing units wide, drawn to 1/2-unit detail (ACCID_WIDTH should be represented in half-units) + * -Prepare each line to account for one extra accidental so we can guarantee the grid has enough space + * -Set m_accidSpaceLeft to be used for asserts during drawing + */ + int accidLineLength = ((int)m_accidList.size() + 1) * ACCID_WIDTH; + + /* + * Each accidental's Y position will be its vertical center; set the grid extremes to account for that + * Resize m_accidSpace to be as tall as is possibly necessary; must accomodate every accidental stacked vertically. + */ + m_accidSpaceTop = m_accidList.front()->GetDrawingY() + doubleUnit; + m_accidSpaceBot = m_accidList.back()->GetDrawingY() - doubleUnit; + int height = (m_accidSpaceTop - m_accidSpaceBot) / halfUnit; + m_accidSpace.resize(height); + + //Resize each row in m_accidSpace to be the proper length; set all the bools to false + std::vector *accidLine; for(idx = 0; idx < m_accidSpace.size(); idx++) { accidLine = &m_accidSpace.at(idx); - //resize each line - accidLine->resize(lineLength); - //initialize all spaces to false - for(setIdx = 0; setIdx < lineLength; setIdx++) accidLine->at(setIdx) = false; + accidLine->resize(accidLineLength); + for(setIdx = 0; setIdx < accidLineLength; setIdx++) accidLine->at(setIdx) = false; } } diff --git a/src/view_element.cpp b/src/view_element.cpp index 9dc9d788895..0ac00061f87 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1444,74 +1444,80 @@ void View::DrawMeterSig( DeviceContext *dc, LayerElement *element, Layer *layer, dc->EndGraphic(element, this ); } - -//returns false if no adjustment is necessary -bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool save) + +bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjustHorizontally) { - //size declarations + std::vector< std::vector > *accidSpace = &chord->m_accidSpace; + + //global drawing variables int fullUnit = m_doc->m_drawingUnit[staff->staffSize]; int doubleUnit = fullUnit * 2; int halfUnit = fullUnit / 2; - int type = accid->GetAccid(); - std::vector< std::vector > *accidSpace = &chord->m_accidSpace; - std::vector noteList = chord->m_accidList; - int xLength = (int)accidSpace->at(0).size(); + //drawing variables for the chord + int xLength = (int)accidSpace->front().size(); + int listTop = chord->m_accidSpaceTop; + int listBot = chord->m_accidSpaceBot; + + //drawing variables for the accidental + int type = accid->GetAccid(); + int centerY = accid->GetDrawingY(); + int topY = centerY + doubleUnit; + int bottomY = centerY - doubleUnit; - //Y-position limits - int listTop = noteList[0]->GetDrawingY(); - int listBot = noteList[noteList.size() - 1]->GetDrawingY(); - int topY = accid->GetDrawingY() + doubleUnit; - int topPos = std::max(0, listTop - topY) / halfUnit; - int bottomY = accid->GetDrawingY() - doubleUnit; - int botPos = (int)accidSpace->size() - 1 - ((std::max(0, bottomY - listBot)) / halfUnit); + //drawing variables for the accidental in accidSpace units + int accidTop = std::max(0, listTop - topY) / halfUnit; + int accidBot = ((int)accidSpace->size() - 1) - ((std::max(0, bottomY - listBot)) / halfUnit); + //how many halfunits we have moved the element int currentX = 0; - //move to the left by half-units until all four corners are false + /* + * Make sure all four corners of the accidental are not on an already-taken spot. + * The top right corner of a flat can overlap something else; make sure that the bordering sections do not overlap. + * Move the accidental one half-unit left until it doesn't overlap. + */ if (type == ACCIDENTAL_EXPLICIT_f) { while (currentX < xLength) { - if (accidSpace->at(topPos + 1)[currentX]) currentX += 1; - if (accidSpace->at(topPos)[currentX + 1]) currentX += 1; - else if (accidSpace->at(botPos)[currentX]) currentX += 1; - else if (accidSpace->at(topPos)[currentX + ACCID_WIDTH]) currentX += 1; - else if (accidSpace->at(botPos)[currentX + ACCID_WIDTH]) currentX += 1; + if (accidSpace->at(accidTop + 1)[currentX]) currentX += 1; + if (accidSpace->at(accidTop)[currentX + 1]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX + ACCID_WIDTH]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX + ACCID_WIDTH]) currentX += 1; else break; }; } else { while (currentX < xLength) { - if (accidSpace->at(topPos)[currentX]) currentX += 1; - else if (accidSpace->at(botPos)[currentX]) currentX += 1; - else if (accidSpace->at(topPos)[currentX + ACCID_WIDTH]) currentX += 1; - else if (accidSpace->at(botPos)[currentX + ACCID_WIDTH]) currentX += 1; + if (accidSpace->at(accidTop)[currentX]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX + ACCID_WIDTH]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX + ACCID_WIDTH]) currentX += 1; else break; }; } - - assert(currentX + ACCID_WIDTH <= xLength); - //move the accidental position if requested - if (save) + //If we need to move the accidental horizontally, move it by currentX half-units. + if (adjustHorizontally) { int xShift = currentX * halfUnit; accid->SetDrawingX(accid->GetDrawingX() - xShift); - //mark the spaces as taken (true) + //mark the spaces as taken (true in accidSpace) for(int xIdx = currentX; xIdx < currentX + ACCID_WIDTH; xIdx++) { - for(int yIdx = topPos; yIdx < botPos + 1; yIdx++) + for(int yIdx = accidTop; yIdx < accidBot + 1; yIdx++) { accidSpace->at(yIdx).at(xIdx) = true; } } } - //otherwise just mark the vertical position so we can see if there are any vertical conflicts + //Otherwise, just mark its vertical position so we can see if there are any vertical conflicts else { for(int xIdx = 0; xIdx < ACCID_WIDTH; xIdx++) //x from 0 to 4, base position { - for(int yIdx = topPos; yIdx < botPos + 1; yIdx++) + for(int yIdx = accidTop; yIdx < accidBot + 1; yIdx++) { accidSpace->at(yIdx).at(xIdx) = true; } @@ -1519,6 +1525,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool save) } + //Regardless of whether or not we moved it, return true if there was a conflict and currentX would have been moved return (currentX == 0); } From 1e0a4cfaa9a622e5b989e9f90b2fdef7febcea4c Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 13 Apr 2015 10:57:03 +0200 Subject: [PATCH 31/68] Adding git commit to version name --- Verovio.xcodeproj/project.pbxproj | 19 +++++++++++++++++++ emscripten/build.sh | 5 ++++- java/build.sh | 3 +++ python/setup.py | 6 ++++++ src/vrv.cpp | 3 ++- tools/CMakeLists.txt | 2 ++ tools/get_git_commit.sh | 12 ++++++++++++ 7 files changed, 48 insertions(+), 2 deletions(-) create mode 100755 tools/get_git_commit.sh diff --git a/Verovio.xcodeproj/project.pbxproj b/Verovio.xcodeproj/project.pbxproj index 84d11f75ae6..0e173d36765 100644 --- a/Verovio.xcodeproj/project.pbxproj +++ b/Verovio.xcodeproj/project.pbxproj @@ -221,6 +221,7 @@ 4D9A9C18199F561200028D93 /* verse.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = verse.cpp; path = src/verse.cpp; sourceTree = ""; }; 4D9A9C1B199F576100028D93 /* syl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = syl.h; path = include/vrv/syl.h; sourceTree = ""; }; 4D9A9C1D19A1DE2000028D93 /* syl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = syl.cpp; path = src/syl.cpp; sourceTree = ""; }; + 4D9C5F3A1ADBBBEB005D3031 /* git_commit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = git_commit.h; path = include/vrv/git_commit.h; sourceTree = SOURCE_ROOT; }; 4DA80D941A6940120089802D /* style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = style.h; path = include/vrv/style.h; sourceTree = ""; }; 4DA80D951A6ACF5D0089802D /* style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = style.cpp; path = src/style.cpp; sourceTree = ""; }; 4DC34B9F19BC4A70006175CD /* accid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = accid.h; path = include/vrv/accid.h; sourceTree = ""; }; @@ -380,6 +381,7 @@ 4D7D8A3C1886E36200D78B62 /* tools */ = { isa = PBXGroup; children = ( + 4D9C5F3A1ADBBBEB005D3031 /* git_commit.h */, 4D983004192E959E00320037 /* main.cpp */, 4D2E09B118A92371001EEEB8 /* emscripten_main.cpp */, ); @@ -692,6 +694,7 @@ isa = PBXNativeTarget; buildConfigurationList = 8F086EB3188534690037FD8E /* Build configuration list for PBXNativeTarget "Verovio" */; buildPhases = ( + 4D9C5F361ADBADDA005D3031 /* ShellScript */, 8F086EA5188534680037FD8E /* Sources */, 8F086EA6188534680037FD8E /* Frameworks */, 8F086EA7188534680037FD8E /* CopyFiles */, @@ -748,6 +751,22 @@ }; /* End PBXProject section */ +/* Begin PBXShellScriptBuildPhase section */ + 4D9C5F361ADBADDA005D3031 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd ${SRCROOT}/tools\n./get_git_commit.sh"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 8F086EA5188534680037FD8E /* Sources */ = { isa = PBXSourcesBuildPhase; diff --git a/emscripten/build.sh b/emscripten/build.sh index bee8e429467..2e99090fbb9 100755 --- a/emscripten/build.sh +++ b/emscripten/build.sh @@ -4,7 +4,7 @@ function print_help { echo "Usage: -l Light version with no increased memory allocation -w WebWorker-compatible build. --v N Version number (e.g., 1.0.0); no number by default +-v N Version number (e.g., 1.0.0); no number by default -c Turns on \"Chatty\" compiling; Will print the compiler progress" >&2 ; } @@ -39,6 +39,9 @@ VERSION_NAME="" CHATTY="" WEBWORKER=false +# generate the git commit file +../tools/get_git_commit.sh + while getopts "lwv:h:c" opt; do case $opt in l) diff --git a/java/build.sh b/java/build.sh index 04aa7bb050f..3cfa2d44858 100755 --- a/java/build.sh +++ b/java/build.sh @@ -3,6 +3,9 @@ mkdir -p src/main/java/org/rismch/verovio mkdir target +# generate the git commit include file +../tools/get_git_commit.sh + swig -c++ -java -package org.rismch.verovio -outdir src/main/java/org/rismch/verovio verovio.i FILES="../src/accid.cpp \ diff --git a/python/setup.py b/python/setup.py index 3ae2962f0f4..2fd39473eba 100755 --- a/python/setup.py +++ b/python/setup.py @@ -4,8 +4,14 @@ setup.py file for Verovio """ + from distutils.core import setup, Extension +# generate the git commit include file +import os +os.system("../tools/get_git_commit.sh") + + verovio_module = Extension('_verovio', sources=['../src/accid.cpp', '../src/aligner.cpp', diff --git a/src/vrv.cpp b/src/vrv.cpp index b4e7d6f4318..6a7119323b2 100644 --- a/src/vrv.cpp +++ b/src/vrv.cpp @@ -18,6 +18,7 @@ //---------------------------------------------------------------------------- +#include "git_commit.h" #include "glyph.h" #include "pugixml.hpp" #include "smufl.h" @@ -465,7 +466,7 @@ std::string GetFilename( std::string fullpath ) } std::string GetVersion() { - return StringFormat("%d.%d.%d", VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION ); + return StringFormat("%d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, GIT_COMMIT ); } } // namespace vrv \ No newline at end of file diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index aa56538e48e..e0480492cdc 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -6,6 +6,8 @@ SET(CMAKE_BUILD_TYPE Release) add_definitions(-g) +EXEC_PROGRAM(../tools/get_git_commit.sh ARGS OUTPUT_VARIABLE GIT_COMMIT) + include_directories(/usr/local/include ../include/vrv ../libmei) add_executable (verovio diff --git a/tools/get_git_commit.sh b/tools/get_git_commit.sh new file mode 100755 index 00000000000..dae8fd6d5a2 --- /dev/null +++ b/tools/get_git_commit.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +cd .. +output="./include/vrv/git_commit.h" +COMMIT=`git describe --abbrev=7 --always --dirty` + +echo "////////////////////////////////////////////////////////" > $output +echo "/// Git commit version file generated at compilation ///" >> $output +echo "////////////////////////////////////////////////////////" >> $output +echo "" >> $output +echo "#define GIT_COMMIT \"$COMMIT\"" >> $output +echo "" >> $output From 7748e06d84c07559a6b9a2242839f87dbe821323 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 13 Apr 2015 11:09:56 +0200 Subject: [PATCH 32/68] Adding version to method to the JS toolkit --- emscripten/build.sh | 1 + emscripten/emscripten_main.cpp | 7 ++++++- emscripten/verovio-proxy.js | 7 +++++++ include/vrv/toolkit.h | 6 ++++++ src/toolkit.cpp | 10 ++++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/emscripten/build.sh b/emscripten/build.sh index 2e99090fbb9..68d31b42d10 100755 --- a/emscripten/build.sh +++ b/emscripten/build.sh @@ -156,6 +156,7 @@ python $EMCC $CHATTY \ '_vrvToolkit_constructor',\ '_vrvToolkit_destructor',\ '_vrvToolkit_getLog',\ + '_vrvToolkit_getVersion',\ '_vrvToolkit_getMEI',\ '_vrvToolkit_getPageCount',\ '_vrvToolkit_getPageWithElement',\ diff --git a/emscripten/emscripten_main.cpp b/emscripten/emscripten_main.cpp index a9f3261bf8a..407f0f47cf4 100644 --- a/emscripten/emscripten_main.cpp +++ b/emscripten/emscripten_main.cpp @@ -49,7 +49,12 @@ extern "C" { tk->SetCString(tk->GetLogString()); return tk->GetCString(); } - + + const char *vrvToolkit_getVersion(Toolkit *tk) { + tk->SetCString(tk->GetVersion()); + return tk->GetCString(); + } + int vrvToolkit_getPageCount(Toolkit *tk) { return tk->GetPageCount(); } diff --git a/emscripten/verovio-proxy.js b/emscripten/verovio-proxy.js index 7cd286bf7a2..467084e1dac 100644 --- a/emscripten/verovio-proxy.js +++ b/emscripten/verovio-proxy.js @@ -15,6 +15,9 @@ verovio.vrvToolkit.destructor = Module.cwrap('vrvToolkit_destructor', null, ['nu // char *getLog(Toolkit *ic) verovio.vrvToolkit.getLog = Module.cwrap('vrvToolkit_getLog', 'string', ['number']); +// char *getVersion(Toolkit *ic) +verovio.vrvToolkit.getVersion = Module.cwrap('vrvToolkit_getVersion', 'string', ['number']); + // int getPageCount(Toolkit *ic) verovio.vrvToolkit.getPageCount = Module.cwrap('vrvToolkit_getPageCount', 'number', ['number']); @@ -72,6 +75,10 @@ verovio.toolkit.prototype.getLog = function () { return verovio.vrvToolkit.getLog(this.ptr); }; +verovio.toolkit.prototype.getVersion = function () { + return verovio.vrvToolkit.getVersion(this.ptr); +}; + verovio.toolkit.prototype.getPageCount = function () { return verovio.vrvToolkit.getPageCount(this.ptr); }; diff --git a/include/vrv/toolkit.h b/include/vrv/toolkit.h index 7d702f7be89..fb3c7125e31 100644 --- a/include/vrv/toolkit.h +++ b/include/vrv/toolkit.h @@ -79,6 +79,12 @@ class Toolkit */ std::string GetLogString( ); + /** + * Returns the version number as a string. + * This is used only for Emscripten based compilation. + */ + std::string GetVersion( ); + /** * Resets the vrv::logBuffer. * This is used only for Emscripten based compilation. diff --git a/src/toolkit.cpp b/src/toolkit.cpp index a5003d18553..8b5d27db684 100644 --- a/src/toolkit.cpp +++ b/src/toolkit.cpp @@ -425,6 +425,16 @@ std::string Toolkit::GetLogString() { #endif } +std::string Toolkit::GetVersion() { +#ifdef USE_EMSCRIPTEN + std::string str = vrv::GetVersion(); + return str; +#else + // The non js version of the app should not use this function. + return ""; +#endif +} + void Toolkit::ResetLogBuffer() { #ifdef USE_EMSCRIPTEN From 68f7b1c3eb76e313947bfbe9296ddf4ccbf8a940 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 13 Apr 2015 15:56:05 +0200 Subject: [PATCH 33/68] Adding minimum measure width --- include/vrv/doc.h | 2 ++ include/vrv/style.h | 6 ++++++ src/aligner.cpp | 11 +++++++++-- src/doc.cpp | 2 ++ src/measure.cpp | 5 +++-- src/page.cpp | 2 ++ src/style.cpp | 2 ++ 7 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/vrv/doc.h b/include/vrv/doc.h index 0d2c5ae13e4..c22c745f54d 100644 --- a/include/vrv/doc.h +++ b/include/vrv/doc.h @@ -280,6 +280,8 @@ class Doc: public Object float m_drawingBeamMaxSlope; /** flag for disabling justification */ bool m_drawingJustifyX; + /** minimum measure width */ + int m_drawingMinMeasureWidth; private: /** diff --git a/include/vrv/style.h b/include/vrv/style.h index 76901984501..2d669657644 100644 --- a/include/vrv/style.h +++ b/include/vrv/style.h @@ -74,6 +74,10 @@ namespace vrv { #define MIN_LYRIC_SIZE 2.0 #define MAX_LYRIC_SIZE 8.0 +#define DEFAULT_MEASURE_WIDTH 15.0 +#define MIN_MEASURE_WIDTH 5.0 +#define MAX_MEASURE_WIDTH 50.0 + //---------------------------------------------------------------------------- // Style //---------------------------------------------------------------------------- @@ -128,6 +132,8 @@ class Style /** The system minimal spacing */ short m_spacingSystem; + /** The minimal measure width in units / PARAM_DENOMINATOR */ + short m_minMeasureWidth; /** The lyrics size (in units / PARAM_DENOMINATOR) */ int m_lyricSize; diff --git a/src/aligner.cpp b/src/aligner.cpp index 3120160508f..81f9118efb7 100644 --- a/src/aligner.cpp +++ b/src/aligner.cpp @@ -346,7 +346,8 @@ int MeasureAligner::SetAligmentXPos( ArrayPtrVoid params ) { // param 0: the previous time position // param 1: the previous x rel position - // param 2: the functor to be redirected to the MeasureAligner (unused) + // param 2: the minimum measure width (unused) + // param 3: the functor to be redirected to the MeasureAligner (unused) double *previousTime = static_cast(params[0]); int *previousXRel = static_cast(params[1]); @@ -362,9 +363,11 @@ int Alignment::SetAligmentXPos( ArrayPtrVoid params ) { // param 0: the previous time position // param 1: the previous x rel position - // param 2: the functor to be redirected to the MeasureAligner (unused) + // param 2: the minimum measure width + // param 3: the functor to be redirected to the MeasureAligner (unused) double *previousTime = static_cast(params[0]); int *previousXRel = static_cast(params[1]); + int *minMeasureWidth = static_cast(params[2]); int intervalXRel = 0; double intervalTime = (m_time - (*previousTime)); @@ -376,6 +379,10 @@ int Alignment::SetAligmentXPos( ArrayPtrVoid params ) (*previousTime) = m_time; (*previousXRel) = m_xRel; + if (this->GetType() == ALIGNMENT_MEASURE_END) { + m_xRel = std::max( m_xRel, (*minMeasureWidth) ); + } + return FUNCTOR_CONTINUE; } diff --git a/src/doc.cpp b/src/doc.cpp index f76d395d7dd..ae3cf211971 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -541,6 +541,8 @@ Page *Doc::SetDrawingPage( int pageIdx ) m_drawingLyricFonts[0].SetPointSize( m_drawingUnit[0] * m_style->m_lyricSize / PARAM_DENOMINATOR ); m_drawingLyricFonts[1].SetPointSize( m_drawingUnit[1] * m_style->m_lyricSize / PARAM_DENOMINATOR ); + m_drawingMinMeasureWidth = m_drawingUnit[0] * m_style->m_minMeasureWidth / PARAM_DENOMINATOR ; + float glyph_size; Glyph *glyph; int x, y, w, h; diff --git a/src/measure.cpp b/src/measure.cpp index 90aa89644fd..98577a6ce1a 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -181,8 +181,9 @@ int Measure::SetAligmentXPos( ArrayPtrVoid params ) { // param 0: the previous time position (unused) // param 1: the previous x rel position (unused) - // param 2: the functor to be redirected to Aligner - Functor *setAligmnentPosX = static_cast(params[2]); + // param 2: the minimum measure width (unused) + // param 3: the functor to be redirected to Aligner + Functor *setAligmnentPosX = static_cast(params[3]); m_measureAligner.Process( setAligmnentPosX, params); diff --git a/src/page.cpp b/src/page.cpp index 3329feda6f0..a692a7375ec 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -140,8 +140,10 @@ void Page::LayOutHorizontally( ) params.clear(); double previousTime = 0.0; int previousXRel = 0; + int minMeasureWidth = doc->m_drawingMinMeasureWidth; params.push_back( &previousTime ); params.push_back( &previousXRel ); + params.push_back( &minMeasureWidth ); Functor setAlignmentX( &Object::SetAligmentXPos ); // Special case: because we redirect the functor, pass is a parameter to itself (!) params.push_back( &setAlignmentX ); diff --git a/src/style.cpp b/src/style.cpp index 5c5e2d6e944..a00159feafa 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -51,6 +51,8 @@ Style::Style() m_spacingSystem = DEFAULT_SPACING_SYSTEM; m_lyricSize = DEFAULT_LYRIC_SIZE * PARAM_DENOMINATOR; + + m_minMeasureWidth = (short)(DEFAULT_MEASURE_WIDTH * PARAM_DENOMINATOR); } Style::~Style() From 7f0eddfe28dd22a1b1136876708dc185890c02c1 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 30 Mar 2015 23:05:51 +0200 Subject: [PATCH 34/68] Adding element --- Verovio.xcodeproj/project.pbxproj | 6 ++++ emscripten/build.sh | 3 +- include/vrv/iomei.h | 3 ++ include/vrv/space.h | 48 +++++++++++++++++++++++++++++++ include/vrv/view.h | 1 + python/setup.py | 3 +- src/iomei.cpp | 27 ++++++++++++++++- src/mrest.cpp | 2 +- src/space.cpp | 33 +++++++++++++++++++++ src/view_element.cpp | 12 ++++++++ tools/CMakeLists.txt | 1 + 11 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 include/vrv/space.h create mode 100644 src/space.cpp diff --git a/Verovio.xcodeproj/project.pbxproj b/Verovio.xcodeproj/project.pbxproj index 0e173d36765..be07fa0f273 100644 --- a/Verovio.xcodeproj/project.pbxproj +++ b/Verovio.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ 4DA3FCD419B61DB400CBDFE6 /* atts_cmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DEE28EF1940BCC100C76319 /* atts_cmn.cpp */; }; 4DA80D961A6ACF5D0089802D /* style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DA80D951A6ACF5D0089802D /* style.cpp */; }; 4DA80D971A6ACF5D0089802D /* style.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DA80D951A6ACF5D0089802D /* style.cpp */; }; + 4DB3072F1AC9ED2500EE0982 /* space.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4DB3072E1AC9ED2500EE0982 /* space.cpp */; }; 4DC34BA219BC4A71006175CD /* accid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DC34B9F19BC4A70006175CD /* accid.h */; }; 4DC34BA319BC4A71006175CD /* custos.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DC34BA019BC4A70006175CD /* custos.h */; }; 4DC34BA419BC4A71006175CD /* dot.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DC34BA119BC4A70006175CD /* dot.h */; }; @@ -224,6 +225,8 @@ 4D9C5F3A1ADBBBEB005D3031 /* git_commit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = git_commit.h; path = include/vrv/git_commit.h; sourceTree = SOURCE_ROOT; }; 4DA80D941A6940120089802D /* style.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = style.h; path = include/vrv/style.h; sourceTree = ""; }; 4DA80D951A6ACF5D0089802D /* style.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = style.cpp; path = src/style.cpp; sourceTree = ""; }; + 4DB3072D1AC9ED1800EE0982 /* space.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = space.h; path = include/vrv/space.h; sourceTree = ""; }; + 4DB3072E1AC9ED2500EE0982 /* space.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = space.cpp; path = src/space.cpp; sourceTree = ""; }; 4DC34B9F19BC4A70006175CD /* accid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = accid.h; path = include/vrv/accid.h; sourceTree = ""; }; 4DC34BA019BC4A70006175CD /* custos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = custos.h; path = include/vrv/custos.h; sourceTree = ""; }; 4DC34BA119BC4A70006175CD /* dot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dot.h; path = include/vrv/dot.h; sourceTree = ""; }; @@ -614,6 +617,8 @@ 8F59292318854BF800FE51AD /* note.h */, 8F086ED1188539540037FD8E /* rest.cpp */, 8F59292818854BF800FE51AD /* rest.h */, + 4DB3072E1AC9ED2500EE0982 /* space.cpp */, + 4DB3072D1AC9ED1800EE0982 /* space.h */, 4D9A9C1D19A1DE2000028D93 /* syl.cpp */, 4D9A9C1B199F576100028D93 /* syl.h */, 8F086ED9188539540037FD8E /* tuplet.cpp */, @@ -782,6 +787,7 @@ 8F086EEA188539540037FD8E /* durationinterface.cpp in Sources */, 8F086EEB188539540037FD8E /* toolkit.cpp in Sources */, 8F086EEC188539540037FD8E /* io.cpp in Sources */, + 4DB3072F1AC9ED2500EE0982 /* space.cpp in Sources */, 8F086EED188539540037FD8E /* iodarms.cpp in Sources */, 8F086EEE188539540037FD8E /* iomei.cpp in Sources */, 8F086EEF188539540037FD8E /* iomusxml.cpp in Sources */, diff --git a/emscripten/build.sh b/emscripten/build.sh index 68d31b42d10..bbb1ef804bd 100755 --- a/emscripten/build.sh +++ b/emscripten/build.sh @@ -135,11 +135,12 @@ python $EMCC $CHATTY \ $VEROVIO_ROOT/src/rest.cpp \ $VEROVIO_ROOT/src/scoredef.cpp \ $VEROVIO_ROOT/src/slur.cpp \ + $VEROVIO_ROOT/src/space.cpp \ $VEROVIO_ROOT/src/staff.cpp \ $VEROVIO_ROOT/src/style.cpp \ $VEROVIO_ROOT/src/svgdevicecontext.cpp \ $VEROVIO_ROOT/src/syl.cpp \ - $VEROVIO_ROOT/src/system.cpp \ + $VEROVIO_ROOT/src/system.cpp \ $VEROVIO_ROOT/src/tie.cpp \ $VEROVIO_ROOT/src/timeinterface.cpp \ $VEROVIO_ROOT/src/toolkit.cpp \ diff --git a/include/vrv/iomei.h b/include/vrv/iomei.h index 9d03b6af129..5edff34245d 100644 --- a/include/vrv/iomei.h +++ b/include/vrv/iomei.h @@ -43,6 +43,7 @@ class Rdg; class Rest; class ScoreDef; class Slur; +class Space; class Staff; class Syl; class System; @@ -131,6 +132,7 @@ class MeiOutput: public FileOutputStream void WriteMeiMultiRest( pugi::xml_node currentNode, MultiRest *multiRest ); void WriteMeiNote( pugi::xml_node currentNode, Note *note ); void WriteMeiRest( pugi::xml_node currentNode, Rest *rest ); + void WriteMeiSpace( pugi::xml_node currentNode, Space *space ); void WriteMeiTuplet( pugi::xml_node currentNode, Tuplet *tuplet ); ///@} @@ -289,6 +291,7 @@ class MeiInput: public FileInputStream bool ReadMeiMultiRest( Object *parent, pugi::xml_node multiRest ); bool ReadMeiNote( Object *parent, pugi::xml_node note ); bool ReadMeiRest( Object *parent, pugi::xml_node rest ); + bool ReadMeiSpace( Object *parent, pugi::xml_node space ); bool ReadMeiSyl( Object *parent, pugi::xml_node syl ); bool ReadMeiTuplet( Object *parent, pugi::xml_node tuplet ); bool ReadMeiVerse( Object *parent, pugi::xml_node verse ); diff --git a/include/vrv/space.h b/include/vrv/space.h new file mode 100644 index 00000000000..832be52b634 --- /dev/null +++ b/include/vrv/space.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: space.h +// Author: Laurent Pugin +// Created: 2015 +// Copyright (c) Authors and others. All rights reserved. +///////////////////////////////////////////////////////////////////////////// + + +#ifndef __VRV_SPACE_H__ +#define __VRV_SPACE_H__ + +#include "durationinterface.h" +#include "layerelement.h" + +namespace vrv { + +//---------------------------------------------------------------------------- +// Space +//---------------------------------------------------------------------------- + +/** + * This class models the MEI + */ +class Space: public LayerElement, public DurationInterface +{ +public: + /** + * @name Constructors, destructors, reset and class name methods + * Reset method reset all attribute classes + */ + ///@{ + Space( ); + virtual ~Space(); + virtual void Reset(); + virtual std::string GetClassName( ){ return "Space"; }; ; + ///@} + +private: + +public: + +private: + +}; + +} // namespace vrv + +#endif diff --git a/include/vrv/view.h b/include/vrv/view.h index 3466d551217..a52e0caada5 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -245,6 +245,7 @@ class View void DrawMultiRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawNote( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); + void DrawSpace( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawSyl( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawTie( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawTuplet( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); diff --git a/python/setup.py b/python/setup.py index 2fd39473eba..7732e5dcea4 100755 --- a/python/setup.py +++ b/python/setup.py @@ -57,7 +57,8 @@ '../src/view_tuplet.cpp', '../src/rest.cpp', '../src/scoredef.cpp', - '../src/slur.cpp', + '../src/slur.cpp', + '../src/space.cpp', '../src/staff.cpp', '../src/style.cpp', '../src/svgdevicecontext.cpp', diff --git a/src/iomei.cpp b/src/iomei.cpp index 0b14512471d..fe2c26ab06f 100644 --- a/src/iomei.cpp +++ b/src/iomei.cpp @@ -32,6 +32,7 @@ #include "page.h" #include "rest.h" #include "slur.h" +#include "space.h" #include "staff.h" #include "syl.h" #include "system.h" @@ -216,6 +217,10 @@ bool MeiOutput::WriteObject( Object *object ) m_currentNode = m_currentNode.append_child("rest"); WriteMeiRest( m_currentNode, dynamic_cast(object) ); } + else if (dynamic_cast(object)) { + m_currentNode = m_currentNode.append_child("space"); + WriteMeiSpace( m_currentNode, dynamic_cast(object) ); + } else if (dynamic_cast(object)) { m_currentNode = m_currentNode.append_child("tuplet"); WriteMeiTuplet( m_currentNode, dynamic_cast(object) ); @@ -583,6 +588,13 @@ void MeiOutput::WriteMeiRest( pugi::xml_node currentNode, Rest *rest ) WritePositionInterface(currentNode, rest); return; } + +void MeiOutput::WriteMeiSpace( pugi::xml_node currentNode, Space *space ) +{ + WriteLayerElement( currentNode, space ); + WriteDurationInterface(currentNode, space); + return; +} void MeiOutput::WriteMeiTuplet( pugi::xml_node currentNode, Tuplet *tuplet ) { @@ -1367,6 +1379,9 @@ bool MeiInput::ReadMeiLayerChildren( Object *parent, pugi::xml_node parentNode, else if ( elementName == "multiRest" ) { success = ReadMeiMultiRest( parent, xmlElement ); } + else if ( elementName == "space" ) { + success = ReadMeiSpace( parent, xmlElement ); + } else if ( elementName == "syl" ) { success = ReadMeiSyl( parent, xmlElement ); } @@ -1573,7 +1588,6 @@ bool MeiInput::ReadMeiNote( Object *parent, pugi::xml_node note ) return ReadMeiLayerChildren(vrvNote, note, vrvNote); } - bool MeiInput::ReadMeiRest( Object *parent, pugi::xml_node rest ) { Rest *vrvRest = new Rest(); @@ -1586,6 +1600,17 @@ bool MeiInput::ReadMeiRest( Object *parent, pugi::xml_node rest ) return true; } +bool MeiInput::ReadMeiSpace( Object *parent, pugi::xml_node space ) +{ + Space *vrvSpace = new Space(); + ReadLayerElement(space, vrvSpace); + + ReadDurationInterface(space, vrvSpace); + + AddLayerElement(parent, vrvSpace); + return true; +} + bool MeiInput::ReadMeiSyl( Object *parent, pugi::xml_node syl) { Syl *vrvSyl = new Syl(); diff --git a/src/mrest.cpp b/src/mrest.cpp index c4d57ebbb92..832b0f7409b 100644 --- a/src/mrest.cpp +++ b/src/mrest.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: mrest.h +// Name: mrest.cpp // Author: Laurent Pugin // Created: 2014 // Copyright (c) Authors and others. All rights reserved. diff --git a/src/space.cpp b/src/space.cpp new file mode 100644 index 00000000000..4e8eaaa7d88 --- /dev/null +++ b/src/space.cpp @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: space.cpp +// Author: Laurent Pugin +// Created: 2015 +// Copyright (c) Authors and others. All rights reserved. +///////////////////////////////////////////////////////////////////////////// + + +#include "space.h" + +namespace vrv { + +//---------------------------------------------------------------------------- +// Space +//---------------------------------------------------------------------------- + +Space::Space( ): + LayerElement("space-") +{ + Reset(); +} + +Space::~Space() +{ +} + +void Space::Reset() +{ + LayerElement::Reset(); + DurationInterface::Reset(); +} + +} // namespace vrv diff --git a/src/view_element.cpp b/src/view_element.cpp index 0ac00061f87..b713dccf614 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -33,6 +33,7 @@ #include "note.h" #include "rest.h" #include "slur.h" +#include "space.h" #include "smufl.h" #include "staff.h" #include "style.h" @@ -126,6 +127,9 @@ void View::DrawLayerElement( DeviceContext *dc, LayerElement *element, Layer *la else if (dynamic_cast(element)) { DrawTie(dc, element, layer, staff, measure); } + else if (dynamic_cast(element)) { + DrawSpace(dc, element, layer, staff, measure); + } else if (dynamic_cast(element)) { DrawSyl(dc, element, layer, staff, measure); } @@ -1589,6 +1593,14 @@ void View::DrawAccid( DeviceContext *dc, LayerElement *element, Layer *layer, St dc->EndGraphic(element, this ); } +void View::DrawSpace(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure) { + + assert(layer); // Pointer to layer cannot be NULL" + assert(staff); // Pointer to staff cannot be NULL" + + dc->StartGraphic( element, "", element->GetUuid() ); + dc->EndGraphic(element, this ); +} void View::DrawCustos( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ) { diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index e0480492cdc..f029cbbafd4 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -57,6 +57,7 @@ add_executable (verovio ../src/rest.cpp ../src/scoredef.cpp ../src/slur.cpp + ../src/space.cpp ../src/staff.cpp ../src/style.cpp ../src/svgdevicecontext.cpp From 85bd79d46b6f204956076160561e9ee1af349d79 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 13 Apr 2015 16:20:37 +0200 Subject: [PATCH 35/68] Adding to Java toolkit --- java/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/java/build.sh b/java/build.sh index 3cfa2d44858..01fca4149dc 100755 --- a/java/build.sh +++ b/java/build.sh @@ -53,6 +53,7 @@ FILES="../src/accid.cpp \ ../src/rest.cpp \ ../src/scoredef.cpp \ ../src/slur.cpp \ + ../src/space.cpp \ ../src/staff.cpp \ ../src/style.cpp \ ../src/svgdevicecontext.cpp \ From 065fb66e73165623b82c6992ac3a9eca76ea124d Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 14 Apr 2015 09:53:11 +0200 Subject: [PATCH 36/68] Removing AttColoration in Chord --- include/vrv/chord.h | 2 -- src/chord.cpp | 2 -- src/view_element.cpp | 1 - 3 files changed, 5 deletions(-) diff --git a/include/vrv/chord.h b/include/vrv/chord.h index 2ce1eee21be..0275313413a 100644 --- a/include/vrv/chord.h +++ b/include/vrv/chord.h @@ -16,7 +16,6 @@ #include "atts_shared.h" #include "durationinterface.h" #include "layerelement.h" -#include "object.h" namespace vrv { @@ -35,7 +34,6 @@ namespace vrv { */ class Chord: public LayerElement, public ObjectListInterface, public DurationInterface, - public AttColoration, public AttCommon, public AttStemmed, public AttTiepresent diff --git a/src/chord.cpp b/src/chord.cpp index 52a3767c4da..f68c0dd1f84 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -24,7 +24,6 @@ namespace vrv { Chord::Chord( ): LayerElement("chord-"), ObjectListInterface(), DurationInterface(), - AttColoration(), AttCommon(), AttStemmed(), AttTiepresent() @@ -49,7 +48,6 @@ void Chord::Reset() DurationInterface::Reset(); ResetCommon(); ResetStemmed(); - ResetColoration(); ResetTiepresent(); } diff --git a/src/view_element.cpp b/src/view_element.cpp index b713dccf614..49acb3fa607 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1248,7 +1248,6 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St /************ Stems ************/ int drawingDur = chord->GetDur(); - drawingDur = ((chord->GetColored()==BOOLEAN_true) && drawingDur > DUR_1) ? (drawingDur + 1) : drawingDur; //(unless we're in a beam) if (!(inBeam && drawingDur > DUR_4)) { From afd8b9012697f0a731e3e8175e943105004c0b9a Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 15 Apr 2015 08:25:46 +0200 Subject: [PATCH 37/68] Moving -4 octave offset (Wolfgang code) to one place (View::CalculatePitchPosY) --- include/vrv/vrvdef.h | 4 +++- src/keysig.cpp | 2 +- src/view_element.cpp | 15 +++++---------- src/view_page.cpp | 11 +++++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index d031c3f1147..091c46ca45b 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -99,7 +99,9 @@ enum FunctorCode { //---------------------------------------------------------------------------- // Legacy Wolfgang defines //---------------------------------------------------------------------------- - + +#define OCTAVE_OFFSET 4 + // ACCID #define ACCID_SHARP 1 #define ACCID_FLAT 2 diff --git a/src/keysig.cpp b/src/keysig.cpp index fe0ceeea8b9..73555866f34 100644 --- a/src/keysig.cpp +++ b/src/keysig.cpp @@ -138,7 +138,7 @@ int KeySig::GetOctave(unsigned char pitch, int clefId) { default: key_set = 0; break; } - return octave_map[alter_set][key_set][pitch - 1]; + return octave_map[alter_set][key_set][pitch - 1] + OCTAVE_OFFSET; } diff --git a/src/view_element.cpp b/src/view_element.cpp index 6cbadfee8ae..de823b4596b 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -161,22 +161,20 @@ void View::DrawDurationElement( DeviceContext *dc, LayerElement *element, Layer else if (dynamic_cast(element)) { Note *note = dynamic_cast(element); - int oct = note->GetOct() - 4; - element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, note->GetPname(), layer->GetClefOffset( element ), oct ) ); + element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, note->GetPname(), layer->GetClefOffset( element ), note->GetOct() ) ); dc->StartGraphic( element, "", element->GetUuid() ); DrawNote(dc, element, layer, staff, measure); dc->EndGraphic(element, this ); } else if (dynamic_cast(element)) { Rest *rest = dynamic_cast(element); - int oct = rest->GetOloc() - 4; // Automatically calculate rest position, if so requested if (rest->GetPloc() == PITCHNAME_NONE) element->SetDrawingY( element->GetDrawingY() + CalculateRestPosY( staff, rest->GetActualDur()) ); else - element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, rest->GetPloc(), layer->GetClefOffset( element ), oct) ); + element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, rest->GetPloc(), layer->GetClefOffset( element ), rest->GetOloc()) ); dc->StartGraphic( element, "", element->GetUuid() ); DrawRest( dc, element, layer, staff, measure ); @@ -1371,8 +1369,7 @@ void View::DrawAccid( DeviceContext *dc, LayerElement *element, Layer *layer, St // Parent will be NULL if we are drawing a note @accid (see DrawNote) - the y value is already set if ( accid->m_parent ) { - int oct = accid->GetOloc() - 4; - accid->SetDrawingY( accid->GetDrawingY() + CalculatePitchPosY( staff, accid->GetPloc(), layer->GetClefOffset( accid ), oct) ); + accid->SetDrawingY( accid->GetDrawingY() + CalculatePitchPosY( staff, accid->GetPloc(), layer->GetClefOffset( accid ), accid->GetOloc()) ); } //Get the offset @@ -1438,8 +1435,7 @@ void View::DrawCustos( DeviceContext *dc, LayerElement *element, Layer *layer, S Custos *custos = dynamic_cast(element); dc->StartGraphic( element, "", element->GetUuid() ); - int oct = custos->GetOloc() - 4; - element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, custos->GetPloc(), layer->GetClefOffset( element ), oct) ); + element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, custos->GetPloc(), layer->GetClefOffset( element ), custos->GetOloc()) ); int x = element->GetDrawingX(); int y = element->GetDrawingY(); @@ -1462,8 +1458,7 @@ void View::DrawDot( DeviceContext *dc, LayerElement *element, Layer *layer, Staf Dot *dot = dynamic_cast(element); dc->StartGraphic( element, "", element->GetUuid() ); - int oct = dot->GetOloc() - 4; - element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, dot->GetPloc(), layer->GetClefOffset( element ), oct) ); + element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, dot->GetPloc(), layer->GetClefOffset( element ), dot->GetOloc()) ); int x = element->GetDrawingX(); int y = element->GetDrawingY(); diff --git a/src/view_page.cpp b/src/view_page.cpp index f31c27adeef..e4cd40d4365 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -682,16 +682,19 @@ int View::CalculatePitchPosY ( Staff *staff, char pname, int dec_clef, int oct) char *ptouche, i; ptouche=&touches[0]; + // Old Wolfgang code with octave stored in an unsigned char - this could be refactored + oct -= OCTAVE_OFFSET; y_int = ((dec_clef + oct*7) - 9 ) * m_doc->m_drawingUnit[staff->staffSize]; - if (staff->m_drawingLines > 5) + if (staff->m_drawingLines > 5) { y_int -= ((staff->m_drawingLines - 5) * 2) * m_doc->m_drawingUnit[staff->staffSize]; + } /* exprime distance separant m_drawingY de position 1e Si, corrigee par dec_clef et oct. Elle est additionnee ensuite, donc elle doit etre NEGATIVE si plus bas que m_drawingY */ - for (i=0; i<(signed)sizeof(touches); i++) - if (*(ptouche+i) == pname) - return(y_int += ((i+1)*m_doc->m_drawingUnit[staff->staffSize])); + for (i=0; i<(signed)sizeof(touches); i++) { + if (*(ptouche+i) == pname) return (y_int += ((i+1)*m_doc->m_drawingUnit[staff->staffSize])); + } return 0; } From 48ca67559c1ba646a29dfb3fabd0299fc21867b5 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 15 Apr 2015 09:15:11 +0200 Subject: [PATCH 38/68] Improving minimal measure width with MRest --- include/vrv/style.h | 6 +++--- src/doc.cpp | 3 ++- src/object.cpp | 21 ++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/vrv/style.h b/include/vrv/style.h index 2d669657644..1419f9c8e12 100644 --- a/include/vrv/style.h +++ b/include/vrv/style.h @@ -74,9 +74,9 @@ namespace vrv { #define MIN_LYRIC_SIZE 2.0 #define MAX_LYRIC_SIZE 8.0 -#define DEFAULT_MEASURE_WIDTH 15.0 -#define MIN_MEASURE_WIDTH 5.0 -#define MAX_MEASURE_WIDTH 50.0 +#define DEFAULT_MEASURE_WIDTH 3.0 +#define MIN_MEASURE_WIDTH 1.0 +#define MAX_MEASURE_WIDTH 30.0 //---------------------------------------------------------------------------- // Style diff --git a/src/doc.cpp b/src/doc.cpp index caff132e2d7..b0bcbb9536e 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -398,6 +398,7 @@ short Doc::GetLeftMargin( const std::type_info *elementType ) if (typeid(Barline) == *elementType) return 5; else if (typeid(Clef) == *elementType) return -20; + else if (typeid(MRest) == *elementType) return 30; //else if (typeid(Note) == *elementType) return 10; return 0; @@ -411,7 +412,7 @@ short Doc::GetRightMargin( const std::type_info *elementType ) else if (typeid(MeterSig) == *elementType) return 30; else if (typeid(Barline) == *elementType) return 30; else if (typeid(BarlineAttr) == *elementType) return 0; - else if (typeid(MRest) == *elementType) return 0; + else if (typeid(MRest) == *elementType) return 30; else if (typeid(MultiRest) == *elementType) return 30; //else if (typeid(Note) == *elementType) return 10; return 10; diff --git a/src/object.cpp b/src/object.cpp index a6216aa8350..546e5ca02a1 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1100,28 +1100,27 @@ int Object::SetBoundingBoxXShift( ArrayPtrVoid params ) return FUNCTOR_CONTINUE; } - if ( current->IsMRest() ) { - // We need to reconsider this: if the mrest is on the top staff, the aligner will be before any other note - // aligner. This means that it will not be shifted. We need to shift it but not take into account its own width. - //current->GetAlignment()->SetXShift( current->GetAlignment()->GetXRel() ); - (*min_pos) = 0; - return FUNCTOR_CONTINUE; - } - - //(*min_pos) += doc->GetLeftMargin(current) * doc->m_drawingUnit / PARAM_DENOMINATOR; - // the negative offset it the part of the bounding box that overflows on the left // |____x_____| // ---- = negative offset //int negative_offset = current->GetAlignment()->GetXRel() - current->m_contentBB_x1; int negative_offset = - (current->m_contentBB_x1) + (doc->GetLeftMargin(&typeid(*current)) * doc->m_drawingUnit[0] / PARAM_DENOMINATOR); - // this will probably never happen + // this should never happen (but can with glyphs not exactly registered at position x=0 in the SMuFL font used if ( negative_offset < 0 ) { //LogDebug("%s negative offset %d;", current->GetClassName().c_str(), negative_offset ); negative_offset = 0; } + if ( current->IsMRest() ) { + // With MRest, the only thing we want to do it keep their with as possible measure with (if only MRest in all staves/layers) + int width = current->m_contentBB_x2 + doc->GetRightMargin(&typeid(*current)) * doc->m_drawingUnit[0] / PARAM_DENOMINATOR + negative_offset ; + // Keep it if more than the current measure width + (*measure_width) = std::max( (*measure_width), width ); + (*min_pos) = 0; + return FUNCTOR_CONTINUE; + } + // check if the element overlaps with the preceeding one given by (*min_pos) int overlap = 0; overlap = (*min_pos) - current->GetAlignment()->GetXRel() + negative_offset; From 319784959acf8443a213e60d0fa08fe4d84436ce Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 15 Apr 2015 13:06:53 +0200 Subject: [PATCH 39/68] Include the VerovioText font in the SVG only when necessary --- include/vrv/devicecontext.h | 11 +++++++++++ src/svgdevicecontext.cpp | 39 ++++++++++++++++++++++++------------- src/view_graph.cpp | 1 + 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/include/vrv/devicecontext.h b/include/vrv/devicecontext.h index 8750b60684c..584566886c1 100644 --- a/include/vrv/devicecontext.h +++ b/include/vrv/devicecontext.h @@ -160,10 +160,21 @@ class DeviceContext virtual bool GetDrawBoundingBoxes() {return m_drawingBoundingBoxes;}; ///@} + /** + * Change the flag for indicating the use of the VerovioText font + */ + void VrvTextFont() { m_vrvTextFont = true; }; + protected: bool m_correctMusicAscent; // specify if the ascent has to be correct when view the music font (true wxDC, false SVG) bool m_drawingBoundingBoxes; + /** + * Flag for indicating if the VerovioText font is currently used. + * If used, it has to be initialized to false (e.g., in the overriden version of StartPage) and will be changed in DeviceContext::VrvTextFont + */ + bool m_vrvTextFont; + std::stack m_penStack; std::stack m_brushStack; diff --git a/src/svgdevicecontext.cpp b/src/svgdevicecontext.cpp index f04b6762318..082292ec008 100644 --- a/src/svgdevicecontext.cpp +++ b/src/svgdevicecontext.cpp @@ -100,11 +100,13 @@ void SvgDeviceContext::Commit( bool xml_declaration ) { m_svgNode.prepend_attribute( "height" ) = StringFormat("%dpx", (int)((double)m_height * m_userScaleY)).c_str(); m_svgNode.prepend_attribute( "width" ) = StringFormat("%dpx", (int)((double)m_width * m_userScaleX)).c_str(); - // add the woff VerovioText font - std::string woff = Resources::GetPath() + "/woff.xml"; - pugi::xml_document woffDoc; - woffDoc.load_file(woff.c_str()); - m_svgNode.prepend_copy( woffDoc.first_child() ); + // add the woff VerovioText font in needed + if (m_vrvTextFont) { + std::string woff = Resources::GetPath() + "/woff.xml"; + pugi::xml_document woffDoc; + woffDoc.load_file(woff.c_str()); + m_svgNode.prepend_copy( woffDoc.first_child() ); + } // header if (m_smufl_glyphs.size() > 0) @@ -148,8 +150,8 @@ void SvgDeviceContext::Commit( bool xml_declaration ) { void SvgDeviceContext::StartGraphic( DocObject *object, std::string gClass, std::string gId ) { - Pen currentPen = m_penStack.top(); - Brush currentBrush = m_brushStack.top(); + //Pen currentPen = m_penStack.top(); + //Brush currentBrush = m_brushStack.top(); std::string baseClass = object->GetClassName(); std::transform( baseClass.begin(), baseClass.begin() + 1, baseClass.begin(), ::tolower ); @@ -161,7 +163,7 @@ void SvgDeviceContext::StartGraphic( DocObject *object, std::string gClass, std: m_svgNodeStack.push_back(m_currentNode); m_currentNode.append_attribute( "class" ) = baseClass.c_str(); m_currentNode.append_attribute( "id" ) = gId.c_str(); - m_currentNode.append_attribute( "style" ) = StringFormat("stroke: #%s; stroke-opacity: %f; fill: #%s; fill-opacity: %f;", GetColour(currentPen.GetColour()).c_str(), currentPen.GetOpacity(), GetColour(currentBrush.GetColour()).c_str(), currentBrush.GetOpacity()).c_str(); + //m_currentNode.append_attribute( "style" ) = StringFormat("stroke: #%s; stroke-opacity: %f; fill: #%s; fill-opacity: %f;", GetColour(currentPen.GetColour()).c_str(), currentPen.GetOpacity(), GetColour(currentBrush.GetColour()).c_str(), currentBrush.GetOpacity()).c_str(); } void SvgDeviceContext::ResumeGraphic( DocObject *object, std::string gId ) @@ -223,6 +225,9 @@ void SvgDeviceContext::EndResumedGraphic(DocObject *object, View *view ) void SvgDeviceContext::StartPage( ) { + // Initialize the flag to false because we want to know if the font needs to be included in the SVG + m_vrvTextFont = false; + // a graphic for definition scaling m_currentNode = m_currentNode.append_child("svg"); m_svgNodeStack.push_back(m_currentNode); @@ -235,6 +240,8 @@ void SvgDeviceContext::StartPage( ) m_svgNodeStack.push_back(m_currentNode); m_currentNode.append_attribute("class") = "page-margin"; m_currentNode.append_attribute("transform") = StringFormat("translate(%d, %d)", (int)((double)m_originX), (int)((double)m_originY)).c_str(); + m_currentNode.append_attribute( "style" ) = "stroke: #000; stroke-opacity: 1.0; fill: #000; fill-opacity: 1.0"; + } @@ -299,7 +306,9 @@ void SvgDeviceContext::DrawComplexBezierPath(int x, int y, int bezier1_coord[6], bezier1_coord[0], bezier1_coord[1], bezier1_coord[2], bezier1_coord[3], bezier1_coord[4], bezier1_coord[5], // First bezier bezier2_coord[0], bezier2_coord[1], bezier2_coord[2], bezier2_coord[3], bezier2_coord[4], bezier2_coord[5] // Second Bezier ).c_str(); - pathChild.append_attribute("style") = StringFormat("fill:#000; fill-opacity:1.0; stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-opacity:1.0; stroke-width: %d", m_penStack.top().GetWidth() ).c_str(); + //pathChild.append_attribute("style") = StringFormat("fill:#000; fill-opacity:1.0; stroke:#000000; stroke-linecap:round; stroke-linejoin:round; stroke-opacity:1.0; stroke-width: %d", m_penStack.top().GetWidth() ).c_str(); + // without colour + pathChild.append_attribute("style") = StringFormat("fill-opacity:1.0; stroke-linecap:round; stroke-linejoin:round; stroke-opacity:1.0; stroke-width: %d", m_penStack.top().GetWidth() ).c_str(); } void SvgDeviceContext::DrawCircle(int x, int y, int radius) @@ -325,8 +334,10 @@ void SvgDeviceContext::DrawEllipse(int x, int y, int width, int height) ellipseChild.append_attribute("rx") = rw; ellipseChild.append_attribute("ry") = rh; - ellipseChild.append_attribute( "style" ) = StringFormat("stroke: #%s; stroke-opacity: %f; stroke-width: %d; fill: #%s; fill-opacity: %f;", GetColour(currentPen.GetColour()).c_str(), currentPen.GetOpacity(), currentPen.GetWidth(), - GetColour(currentBrush.GetColour()).c_str(), currentBrush.GetOpacity()).c_str(); + //ellipseChild.append_attribute( "style" ) = StringFormat("stroke: #%s; stroke-opacity: %f; stroke-width: %d; fill: #%s; fill-opacity: %f;", GetColour(currentPen.GetColour()).c_str(), currentPen.GetOpacity(), currentPen.GetWidth(), + // GetColour(currentBrush.GetColour()).c_str(), currentBrush.GetOpacity()).c_str(); + // without colour + ellipseChild.append_attribute( "style" ) = StringFormat("stroke-opacity: %f; stroke-width: %d; fill-opacity: %f;", currentPen.GetOpacity(), currentPen.GetWidth(), currentBrush.GetOpacity()).c_str(); } @@ -384,8 +395,10 @@ void SvgDeviceContext::DrawEllipticArc(int x, int y, int width, int height, doub pugi::xml_node pathChild = m_currentNode.append_child("path"); pathChild.append_attribute("d") = StringFormat("M%d %d A%d %d 0.0 %d %d %d %d",int(xs), int(ys), abs(int(rx)), abs(int(ry)), fArc, fSweep, int(xe), int(ye)).c_str(); - pathChild.append_attribute( "style" ) = StringFormat("stroke: #%s; stroke-opacity: %f; stroke-width: %d; fill: #%s; fill-opacity: %f;", GetColour(currentPen.GetColour()).c_str(), currentPen.GetOpacity(), currentPen.GetWidth(), - GetColour(currentBrush.GetColour()).c_str(), currentBrush.GetOpacity()).c_str(); + //pathChild.append_attribute( "style" ) = StringFormat("stroke: #%s; stroke-opacity: %f; stroke-width: %d; fill: #%s; fill-opacity: %f;", GetColour(currentPen.GetColour()).c_str(), currentPen.GetOpacity(), currentPen.GetWidth(), + // GetColour(currentBrush.GetColour()).c_str(), currentBrush.GetOpacity()).c_str(); + // without colour + pathChild.append_attribute( "style" ) = StringFormat("stroke-opacity: %f; stroke-width: %d; fill-opacity: %f;", currentPen.GetOpacity(), currentPen.GetWidth(), currentBrush.GetOpacity()).c_str(); } diff --git a/src/view_graph.cpp b/src/view_graph.cpp index 367a95effc1..bdc7148fbb2 100644 --- a/src/view_graph.cpp +++ b/src/view_graph.cpp @@ -187,6 +187,7 @@ void View::DrawLyricString ( DeviceContext *dc, int x, int y, std::wstring s, in vrvTxt.SetPointSize( m_doc->m_drawingLyricFonts[staffSize].GetPointSize()); dc->SetFont( &vrvTxt ); + dc->VrvTextFont(); std::wstring str; str.push_back(VRV_TEXT_E551); dc->DrawText( UTF16to8( str.c_str() ), str ); From f1cd68f495b793555465fe49f87d7cdb12e52b73 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 15 Apr 2015 13:25:21 +0200 Subject: [PATCH 40/68] Make getVersion available to non JS toolkits --- src/toolkit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/toolkit.cpp b/src/toolkit.cpp index 8b5d27db684..075271d587d 100644 --- a/src/toolkit.cpp +++ b/src/toolkit.cpp @@ -430,7 +430,8 @@ std::string Toolkit::GetVersion() { std::string str = vrv::GetVersion(); return str; #else - // The non js version of the app should not use this function. + // For non js version, show the version and return empty string + LogMessage( vrv::GetVersion().c_str() ); return ""; #endif } From ccae668e0146902280bf436de0e47d518d58e279 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 15 Apr 2015 13:29:37 +0200 Subject: [PATCH 41/68] Simplifying toolkit getVersion --- src/toolkit.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/toolkit.cpp b/src/toolkit.cpp index 075271d587d..bd1c919a759 100644 --- a/src/toolkit.cpp +++ b/src/toolkit.cpp @@ -426,14 +426,7 @@ std::string Toolkit::GetLogString() { } std::string Toolkit::GetVersion() { -#ifdef USE_EMSCRIPTEN - std::string str = vrv::GetVersion(); - return str; -#else - // For non js version, show the version and return empty string - LogMessage( vrv::GetVersion().c_str() ); - return ""; -#endif + return vrv::GetVersion(); } From 223f5c60ee98a45129b998f6a5c6ee0ca45d11a5 Mon Sep 17 00:00:00 2001 From: Rodolfo Zitellini Date: Wed, 15 Apr 2015 14:01:03 +0200 Subject: [PATCH 42/68] Java port: Put native library into JAR file, add helper class to load it --- java/build.sh | 7 +- .../java/org/rismch/verovio/NativeUtils.java | 93 +++++++++++++++++++ 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 java/src/main/java/org/rismch/verovio/NativeUtils.java diff --git a/java/build.sh b/java/build.sh index 01fca4149dc..8596ddeeeb1 100755 --- a/java/build.sh +++ b/java/build.sh @@ -1,7 +1,8 @@ #!/bin/bash mkdir -p src/main/java/org/rismch/verovio -mkdir target +mkdir -p target +mkdir -p target/classes/META-INF/lib # generate the git commit include file ../tools/get_git_commit.sh @@ -72,6 +73,6 @@ FILES="../src/accid.cpp \ ../libmei/atts_pagebased.cpp" CXXOPTS="-g -fpic -I../include/vrv -I../libmei -I/opt/local/include/ -I/System/Library/Frameworks/JavaVM.framework/Headers/" -g++ -shared -o target/libverovio.dylib $CXXOPTS $FILES verovio_wrap.cxx -sudo cp target/libverovio.dylib /usr/lib/java/ +g++ -shared -o target/libverovio.jnilib $CXXOPTS $FILES verovio_wrap.cxx +cp target/libverovio.jnilib target/classes/META-INF/lib diff --git a/java/src/main/java/org/rismch/verovio/NativeUtils.java b/java/src/main/java/org/rismch/verovio/NativeUtils.java new file mode 100644 index 00000000000..6368d31614c --- /dev/null +++ b/java/src/main/java/org/rismch/verovio/NativeUtils.java @@ -0,0 +1,93 @@ +package org.rismch; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Simple library class for working with JNI (Java Native Interface) + * + * @see http://adamheinrich.com/2012/how-to-load-native-jni-library-from-jar + * + * @author Adam Heirnich <adam@adamh.cz>, http://www.adamh.cz + */ +public class NativeUtils { + + /** + * Private constructor - this class will never be instanced + */ + private NativeUtils() { + } + + /** + * Loads library from current JAR archive + * + * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting. + * Method uses String as filename because the pathname is "abstract", not system-dependent. + * + * @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext + * @throws IOException If temporary file creation or read/write operation fails + * @throws IllegalArgumentException If source file (param path) does not exist + * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}). + */ + public static void loadLibraryFromJar(String path) throws IOException { + + if (!path.startsWith("/")) { + throw new IllegalArgumentException("The path has to be absolute (start with '/')."); + } + + // Obtain filename from path + String[] parts = path.split("/"); + String filename = (parts.length > 1) ? parts[parts.length - 1] : null; + + // Split filename to prexif and suffix (extension) + String prefix = ""; + String suffix = null; + if (filename != null) { + parts = filename.split("\\.", 2); + prefix = parts[0]; + suffix = (parts.length < 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-) + } + + // Check if the filename is okay + if (filename == null || prefix.length() < 3) { + throw new IllegalArgumentException("The filename has to be at least 3 characters long."); + } + + // Prepare temporary file + File temp = File.createTempFile(prefix, suffix); + temp.deleteOnExit(); + + if (!temp.exists()) { + throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist."); + } + + // Prepare buffer for data copying + byte[] buffer = new byte[1024]; + int readBytes; + + // Open and check input stream + InputStream is = NativeUtils.class.getResourceAsStream(path); + if (is == null) { + throw new FileNotFoundException("File " + path + " was not found inside JAR."); + } + + // Open output stream and copy data between source file in JAR and the temporary file + OutputStream os = new FileOutputStream(temp); + try { + while ((readBytes = is.read(buffer)) != -1) { + os.write(buffer, 0, readBytes); + } + } finally { + // If read/write fails, close streams safely before throwing an exception + os.close(); + is.close(); + } + + // Finally, load the library + System.load(temp.getAbsolutePath()); + } +} \ No newline at end of file From f4fcd8b0ddb6c599399cba582991e267979119cd Mon Sep 17 00:00:00 2001 From: Rodolfo Zitellini Date: Wed, 15 Apr 2015 14:36:09 +0200 Subject: [PATCH 43/68] Use JAR version of lib for exmple file --- java/main.java | 10 ++++++++-- java/src/main/java/org/rismch/verovio/NativeUtils.java | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/java/main.java b/java/main.java index 394d664cf58..814e37be89b 100644 --- a/java/main.java +++ b/java/main.java @@ -6,13 +6,19 @@ java -cp .:target/VerovioToolkit-1.0-SNAPSHOT.jar main */ +import java.io.IOException; + import org.rismch.verovio.toolkit; import org.rismch.verovio.convertFileFormat; +import org.rismch.verovio.NativeUtils; public class main { public static void main(String argv[]) { - System.loadLibrary("verovio"); - + try { + NativeUtils.loadLibraryFromJar("/META-INF/lib/libverovio.jnilib"); + } catch (IOException e) { + System.out.println("Could not load Verovio native lib: " + e.getMessage()); + } toolkit toolkit = new toolkit(); String s; diff --git a/java/src/main/java/org/rismch/verovio/NativeUtils.java b/java/src/main/java/org/rismch/verovio/NativeUtils.java index 6368d31614c..9b586f7bac5 100644 --- a/java/src/main/java/org/rismch/verovio/NativeUtils.java +++ b/java/src/main/java/org/rismch/verovio/NativeUtils.java @@ -1,4 +1,4 @@ -package org.rismch; +package org.rismch.verovio; import java.io.File; import java.io.FileNotFoundException; From 31b76c642f8654bde97340e58f971eb5ba0905e1 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Wed, 15 Apr 2015 11:38:23 -0400 Subject: [PATCH 44/68] WIP: accidSpace functions more clearly -Removed the extra 4 spaces in accidSpace -currentX in calculateAccidSpace is now the left side of the note (the side approaching xLength) -the corner checked on flat accidentals is now 2 down instead of 1 down -For some reason, the extra fullUnit in xAccid (line 1180) isn't needed anymore. Not sure what caused this but it's reliably wrong. -Included debug code to print out accidSpace; this will be removed soon. --- src/chord.cpp | 2 +- src/view_element.cpp | 42 +++++++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/chord.cpp b/src/chord.cpp index 52a3767c4da..b3cd1b45947 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -192,7 +192,7 @@ void Chord::ResetAccidSpace(int fullUnit) * -Prepare each line to account for one extra accidental so we can guarantee the grid has enough space * -Set m_accidSpaceLeft to be used for asserts during drawing */ - int accidLineLength = ((int)m_accidList.size() + 1) * ACCID_WIDTH; + int accidLineLength = (int)m_accidList.size() * ACCID_WIDTH; /* * Each accidental's Y position will be its vertical center; set the grid extremes to account for that diff --git a/src/view_element.cpp b/src/view_element.cpp index 0ac00061f87..1700d159a16 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1177,7 +1177,7 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St if (size > 0) { //set the default x position - int xAccid = chord->GetDrawingX() - (radius * 2) - fullUnit; + int xAccid = chord->GetDrawingX() - (radius * 2); //if chord is a down-stemmed non-cluster, it needs one more note diameter of space if ((chord->GetDrawingStemDir() == STEMDIRECTION_down) && (chord->m_clusters.size() > 0)) @@ -1468,9 +1468,13 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust //drawing variables for the accidental in accidSpace units int accidTop = std::max(0, listTop - topY) / halfUnit; int accidBot = ((int)accidSpace->size() - 1) - ((std::max(0, bottomY - listBot)) / halfUnit); + + assert(accidBot > accidTop); //because the "origin" (0, 0) is in the top right - //how many halfunits we have moved the element - int currentX = 0; + //difference between left end and right end of the accidental + int accidDiff = ACCID_WIDTH - 1; + //the left side of the accidental; gets incremented to avoid conflicts + int currentX = accidDiff; /* * Make sure all four corners of the accidental are not on an already-taken spot. @@ -1479,20 +1483,20 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust */ if (type == ACCIDENTAL_EXPLICIT_f) { while (currentX < xLength) { - if (accidSpace->at(accidTop + 1)[currentX]) currentX += 1; - if (accidSpace->at(accidTop)[currentX + 1]) currentX += 1; + if (accidSpace->at(accidTop + 2)[currentX - accidDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX - accidDiff + 1]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX - accidDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX]) currentX += 1; else if (accidSpace->at(accidBot)[currentX]) currentX += 1; - else if (accidSpace->at(accidTop)[currentX + ACCID_WIDTH]) currentX += 1; - else if (accidSpace->at(accidBot)[currentX + ACCID_WIDTH]) currentX += 1; else break; }; } else { while (currentX < xLength) { - if (accidSpace->at(accidTop)[currentX]) currentX += 1; + if (accidSpace->at(accidTop)[currentX - accidDiff]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX - accidDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX]) currentX += 1; else if (accidSpace->at(accidBot)[currentX]) currentX += 1; - else if (accidSpace->at(accidTop)[currentX + ACCID_WIDTH]) currentX += 1; - else if (accidSpace->at(accidBot)[currentX + ACCID_WIDTH]) currentX += 1; else break; }; } @@ -1504,7 +1508,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust accid->SetDrawingX(accid->GetDrawingX() - xShift); //mark the spaces as taken (true in accidSpace) - for(int xIdx = currentX; xIdx < currentX + ACCID_WIDTH; xIdx++) + for(int xIdx = currentX; xIdx > currentX - ACCID_WIDTH; xIdx--) { for(int yIdx = accidTop; yIdx < accidBot + 1; yIdx++) { @@ -1522,11 +1526,23 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust accidSpace->at(yIdx).at(xIdx) = true; } } - } + //For debugging; leaving this in temporarily +// for (int vIdx = 0; vIdx < accidSpace->size(); vIdx++) +// { +// std::cout << "|"; +// std::vector thisRow = accidSpace->at(vIdx); +// for (int hIdx = (int)thisRow.size() - 1; hIdx >= 0; hIdx --) +// { +// std::cout << thisRow.at(hIdx) << "|"; +// } +// std::cout << std::endl; +// } +// std::cout << std::endl; + //Regardless of whether or not we moved it, return true if there was a conflict and currentX would have been moved - return (currentX == 0); + return (currentX - accidDiff == 0); } void View::DrawAccid( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure, Accid *prevAccid ) From b71f0b3440f90ddc4db87c4437e1ea2c8b591a21 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Wed, 15 Apr 2015 14:52:48 -0400 Subject: [PATCH 45/68] WIP: beam no longer draws stem multiple times Still should only have immediate children in the list. --- src/view_beam.cpp | 12 +++++++----- src/view_element.cpp | 1 - 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/view_beam.cpp b/src/view_beam.cpp index 653dada9784..65d53eb7e06 100644 --- a/src/view_beam.cpp +++ b/src/view_beam.cpp @@ -364,13 +364,15 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff fy2 = (*beamElementCoords)[i]->m_yTop - m_doc->m_drawingUnit[staff->staffSize]/4; } - (*beamElementCoords)[i]->m_element->m_drawingStemStart.x = (*beamElementCoords)[i]->m_element->m_drawingStemEnd.x = (*beamElementCoords)[i]->m_x; - (*beamElementCoords)[i]->m_element->m_drawingStemStart.y = fy2; - (*beamElementCoords)[i]->m_element->m_drawingStemEnd.y = fy1; - (*beamElementCoords)[i]->m_element->m_drawingStemDir = stemDir; + LayerElement *el = (*beamElementCoords)[i]->m_element; + el->m_drawingStemStart.x = el->m_drawingStemEnd.x = (*beamElementCoords)[i]->m_x; + el->m_drawingStemStart.y = fy2; + el->m_drawingStemEnd.y = fy1; + el->m_drawingStemDir = stemDir; - if((*beamElementCoords)[i]->m_element->IsNote() || (*beamElementCoords)[i]->m_element->IsChord()) + if((el->IsNote() && ! dynamic_cast(el)->IsChordTone()) || el->IsChord()){ DrawVerticalLine (dc,fy2, fy1, (*beamElementCoords)[i]->m_x, m_doc->m_style->m_stemWidth); + } } /******************************************************************/ diff --git a/src/view_element.cpp b/src/view_element.cpp index 789c526686a..69fece619b7 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -933,7 +933,6 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St if (beam_parent->GetListIndex(chord) > -1) { inBeam = true; } - } else { // the note is just in a beam From 33a83202868c9c68ac45df6d5ce88a7da20fef5d Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 16 Apr 2015 10:45:16 +0200 Subject: [PATCH 46/68] Adding gitignore file --- .gitignore | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..d13d81ff201 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# xcode +Verovio.xccheckout +Verovio.xcodeproj/project.xcworkspace/xcuserdata +Verovio.xcodeproj/xcuserdata/ +bin/ + +# doc generated file +doc/pae-tests.html + +# include file generated at compilation +include/vrv/git_commit.h + +# cmake build +tools/CMakeCache.txt +tools/CMakeFiles/ +tools/Makefile +tools/cmake_install.cmake +tools/install_manifest.txt +tools/verovio + +# emscripten build +emscripten/data/ +emscripten/build/ + +# python build +python/verovio_wrap.cpp +python/verovio.pyc +python/verovio.py +python/_verovio.so + +# java build +java/verovio_wrap.cxx +java/main.class +java/src/ +java/target/ From be41cdfa8a1e7d774da97354ae751f0216fdea4f Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 16 Apr 2015 10:57:59 +0200 Subject: [PATCH 47/68] Making commit version number undefined when building from not cloned repository --- tools/get_git_commit.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/get_git_commit.sh b/tools/get_git_commit.sh index dae8fd6d5a2..6726c626c15 100755 --- a/tools/get_git_commit.sh +++ b/tools/get_git_commit.sh @@ -4,6 +4,11 @@ cd .. output="./include/vrv/git_commit.h" COMMIT=`git describe --abbrev=7 --always --dirty` +if [ -z "$COMMIT" ]; then + echo "Undefined git commit version" + COMMIT="[undefined]" +fi + echo "////////////////////////////////////////////////////////" > $output echo "/// Git commit version file generated at compilation ///" >> $output echo "////////////////////////////////////////////////////////" >> $output From d28fd435bc4c7b60c15af75a6b09cad07827cc95 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 16 Apr 2015 10:45:16 +0200 Subject: [PATCH 48/68] Adding gitignore file --- .gitignore | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..d13d81ff201 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# xcode +Verovio.xccheckout +Verovio.xcodeproj/project.xcworkspace/xcuserdata +Verovio.xcodeproj/xcuserdata/ +bin/ + +# doc generated file +doc/pae-tests.html + +# include file generated at compilation +include/vrv/git_commit.h + +# cmake build +tools/CMakeCache.txt +tools/CMakeFiles/ +tools/Makefile +tools/cmake_install.cmake +tools/install_manifest.txt +tools/verovio + +# emscripten build +emscripten/data/ +emscripten/build/ + +# python build +python/verovio_wrap.cpp +python/verovio.pyc +python/verovio.py +python/_verovio.so + +# java build +java/verovio_wrap.cxx +java/main.class +java/src/ +java/target/ From 46b6b7ca16de405a31bef367d8243e8aefba3cdb Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 16 Apr 2015 12:02:29 +0200 Subject: [PATCH 49/68] Drawing note DrawBeamPostponed --- include/vrv/view.h | 2 +- src/view_beam.cpp | 8 ++++---- src/view_element.cpp | 7 ++++++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index 5f417bf0948..842ab631c9f 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -243,7 +243,7 @@ class View void DrawMeterSig( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawMRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawMultiRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); - void DrawNote( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); + void DrawNote( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure, bool fromBeam = false ); void DrawRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawSpace( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawSyl( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); diff --git a/src/view_beam.cpp b/src/view_beam.cpp index 65d53eb7e06..14994e72f6b 100644 --- a/src/view_beam.cpp +++ b/src/view_beam.cpp @@ -309,7 +309,7 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff /******************************************************************/ // Draw notes for all objects in the beam now that stem direction is calculated - /*for (i = 0; i < elementCount; i++) { + for (i = 0; i < elementCount; i++) { if ((*beamElementCoords)[i]->m_element->IsChord()) { Chord *chord = dynamic_cast((*beamElementCoords)[i]->m_element); ListOfObjects *noteList = chord->GetList(chord); @@ -320,7 +320,7 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff Note *note = dynamic_cast(*iter); if (!note) continue; dc->ResumeGraphic( dynamic_cast(*iter), (*iter)->GetUuid() ); - DrawNote(dc, dynamic_cast(*iter), layer, staff, measure); + DrawNote(dc, dynamic_cast(*iter), layer, staff, measure, true); dc->EndResumedGraphic( dynamic_cast(*iter), this ); iter++; } @@ -328,10 +328,10 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff } else if ((*beamElementCoords)[i]->m_element->IsNote()) { dc->ResumeGraphic( dynamic_cast((*beamElementCoords)[i]->m_element), (*beamElementCoords)[i]->m_element->GetUuid() ); - DrawNote(dc, dynamic_cast((*beamElementCoords)[i]->m_element), layer, staff, measure); + DrawNote(dc, dynamic_cast((*beamElementCoords)[i]->m_element), layer, staff, measure, true); dc->EndResumedGraphic( dynamic_cast((*beamElementCoords)[i]->m_element), this ); } - }*/ + } /******************************************************************/ // Calculate the stem lengths and draw them diff --git a/src/view_element.cpp b/src/view_element.cpp index 69fece619b7..eb144f74de7 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -225,7 +225,7 @@ void View::DrawTuplet(DeviceContext *dc, LayerElement *element, Layer *layer, St // l'accord (ptr_n->fchord), la valeur y extreme opposee au sommet de la // queue: le ptr *testchord extern peut garder le x et l'y. -void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ) +void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure, bool fromBeam ) { assert(layer); // Pointer to layer cannot be NULL" assert(staff); // Pointer to staff cannot be NULL" @@ -263,6 +263,11 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St } } + if (inBeam && !fromBeam) { + // The note will be drawn from DrawBeamPostponed + return; + } + int staffSize = staff->staffSize; int noteY = element->GetDrawingY(); int xLedger, xNote, xAccid, xStem; From 78fd8ac98943201b49d802b2d1cfb841aeb7f5c6 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 16 Apr 2015 21:15:22 +0200 Subject: [PATCH 50/68] Tidy up if/else --- src/view_element.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index b590f3dbb97..67094f142b4 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -180,10 +180,11 @@ void View::DrawDurationElement( DeviceContext *dc, LayerElement *element, Layer Rest *rest = dynamic_cast(element); // Automatically calculate rest position, if so requested - if (rest->GetPloc() == PITCHNAME_NONE) + if (rest->GetPloc() == PITCHNAME_NONE) { element->SetDrawingY( element->GetDrawingY() + CalculateRestPosY( staff, rest->GetActualDur()) ); - else + } else { element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, rest->GetPloc(), layer->GetClefOffset( element ), rest->GetOloc()) ); + } dc->StartGraphic( element, "", element->GetUuid() ); DrawRest( dc, element, layer, staff, measure ); From c6d8b3b26d3357656590ef45ab673ba166dc2a37 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 16 Apr 2015 22:11:41 +0200 Subject: [PATCH 51/68] Adding a SetDrawingXY functor that sets all the X and Y positions before starting the drawing process Also set a m_crossStaff pointer when necessary --- include/vrv/layer.h | 5 ++++ include/vrv/layerelement.h | 11 ++++++++ include/vrv/measure.h | 6 +++++ include/vrv/object.h | 7 ++++- include/vrv/staff.h | 5 ++++ include/vrv/system.h | 5 ++++ src/layer.cpp | 28 ++++++++++++++++++-- src/layerelement.cpp | 50 +++++++++++++++++++++++++++++++++++ src/measure.cpp | 28 ++++++++++++++++++++ src/staff.cpp | 29 ++++++++++++++++++++ src/system.cpp | 28 ++++++++++++++++++++ src/view_element.cpp | 31 +--------------------- src/view_page.cpp | 54 +++++++++----------------------------- 13 files changed, 212 insertions(+), 75 deletions(-) diff --git a/include/vrv/layer.h b/include/vrv/layer.h index 50ee15358e7..3b3f0ffe882 100644 --- a/include/vrv/layer.h +++ b/include/vrv/layer.h @@ -158,6 +158,11 @@ class Layer: public DocObject, public DrawingListInterface, public ObjectListInt * and for staff/layer to be then processed. */ virtual int PrepareProcessingLists( ArrayPtrVoid params ); + + /** + * Set the drawing position (m_drawingX and m_drawingY) values for objects + */ + virtual int SetDrawingXY( ArrayPtrVoid params ); private: diff --git a/include/vrv/layerelement.h b/include/vrv/layerelement.h index 012d91f5471..71d65a39d4d 100644 --- a/include/vrv/layerelement.h +++ b/include/vrv/layerelement.h @@ -18,6 +18,7 @@ class Alignment; class BeamElementCoord; class Mensur; class MeterSig; +class Staff; //---------------------------------------------------------------------------- // LayerElement @@ -116,6 +117,11 @@ class LayerElement: public DocObject */ virtual int PrepareTimeSpanning( ArrayPtrVoid params ); + /** + * Set the drawing position (m_drawingX and m_drawingY) values for objects + */ + virtual int SetDrawingXY( ArrayPtrVoid params ); + protected: /** * Returns the duration if the child element has a DurationInterface @@ -141,6 +147,11 @@ class LayerElement: public DocObject * This store a pointer to the corresponding BeamElementCoord(currentDur > DUR_4) */ BeamElementCoord *m_beamElementCoord; + /** + * This store a pointer to the cross-staff (if any) + * Initialized in LayerElement::SetDrawingXY + */ + Staff *m_crossStaff; protected: Alignment *m_alignment; diff --git a/include/vrv/measure.h b/include/vrv/measure.h index 991abbc6c7d..feb79c9b833 100644 --- a/include/vrv/measure.h +++ b/include/vrv/measure.h @@ -147,6 +147,12 @@ class Measure: public DocObject, * */ virtual int CastOffSystems( ArrayPtrVoid params ); + + /** + * Set the drawing position (m_drawingX and m_drawingY) values for objects + */ + virtual int SetDrawingXY( ArrayPtrVoid params ); + public: /** diff --git a/include/vrv/object.h b/include/vrv/object.h index 79ab53fc594..505c1fabad7 100644 --- a/include/vrv/object.h +++ b/include/vrv/object.h @@ -527,7 +527,12 @@ class Object /** * Reset the drawing values before calling PrepareDrawing after changes. */ - virtual int ResetDarwing( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; + virtual int ResetDarwing( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; + + /** + * Set the drawing position (m_drawingX and m_drawingY) values for objects + */ + virtual int SetDrawingXY( ArrayPtrVoid params ) { return FUNCTOR_CONTINUE; }; /** * @name Functors for justification diff --git a/include/vrv/staff.h b/include/vrv/staff.h index 840c7ae84c4..e4db5b3eb27 100644 --- a/include/vrv/staff.h +++ b/include/vrv/staff.h @@ -100,6 +100,11 @@ class Staff: public MeasureElement, */ virtual int ResetDarwing( ArrayPtrVoid params ); + /** + * Set the drawing position (m_drawingX and m_drawingY) values for objects + */ + virtual int SetDrawingXY( ArrayPtrVoid params ); + public: /** * Number of lines copied from the staffDef for fast access when drawing diff --git a/include/vrv/system.h b/include/vrv/system.h index 9bfaf8cd398..93b9b2d2b46 100644 --- a/include/vrv/system.h +++ b/include/vrv/system.h @@ -139,6 +139,11 @@ class System: public DocObject, public DrawingListInterface * This is used by Doc::ContinuousLayout */ virtual int UnCastOff( ArrayPtrVoid params ); + + /** + * Set the drawing position (m_drawingX and m_drawingY) values for objects + */ + virtual int SetDrawingXY( ArrayPtrVoid params ); private: diff --git a/src/layer.cpp b/src/layer.cpp index 3a76fe6ce81..30426864aa0 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -17,6 +17,7 @@ #include "custos.h" #include "doc.h" #include "keysig.h" +#include "measure.h" #include "mensur.h" #include "metersig.h" #include "note.h" @@ -394,8 +395,6 @@ int Layer::AlignHorizontally( ArrayPtrVoid params ) (*currentMensur) = m_currentMensur; (*currentMeterSig) = m_currentMeterSig; - //LogDebug(" ----- " ); - if ( m_drawClef && m_currentClef ) { m_currentClef->AlignHorizontally( params ); } @@ -426,5 +425,30 @@ int Layer::PrepareProcessingLists( ArrayPtrVoid params ) return FUNCTOR_CONTINUE; } + +int Layer::SetDrawingXY( ArrayPtrVoid params ) +{ + // param 0: a pointer doc (unused) + // param 1: a pointer to the current system (unused) + // param 2: a pointer to the current measure + // param 3: a pointer to the current staff (unused) + Measure **currentMeasure = static_cast(params[2]); + + // set the values for the scoreDef elements when required + if (this->GetDrawingClef()) { + this->GetDrawingClef()->SetDrawingX( this->GetDrawingClef()->GetXRel() + (*currentMeasure)->GetDrawingX() ); + } + if (this->GetDrawingKeySig()) { + this->GetDrawingKeySig()->SetDrawingX( this->GetDrawingKeySig()->GetXRel() + (*currentMeasure)->GetDrawingX() ); + } + if (this->GetDrawingMensur()) { + this->GetDrawingMensur()->SetDrawingX( this->GetDrawingMensur()->GetXRel() + (*currentMeasure)->GetDrawingX() ); + } + if (this->GetDrawingMeterSig()) { + this->GetDrawingMeterSig()->SetDrawingX( this->GetDrawingMeterSig()->GetXRel() + (*currentMeasure)->GetDrawingX() ); + } + + return FUNCTOR_CONTINUE; +} } // namespace vrv diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 6d486bbbf10..22bfdd2244d 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -15,19 +15,23 @@ #include "accid.h" #include "aligner.h" +#include "att_comparison.h" #include "barline.h" #include "beam.h" #include "chord.h" #include "clef.h" #include "custos.h" +#include "doc.h" #include "dot.h" #include "keysig.h" +#include "measure.h" #include "mensur.h" #include "metersig.h" #include "mrest.h" #include "multirest.h" #include "note.h" #include "rest.h" +#include "staff.h" #include "syl.h" #include "tie.h" #include "timeinterface.h" @@ -409,5 +413,51 @@ int LayerElement::PrepareTimeSpanning( ArrayPtrVoid params ) return FUNCTOR_CONTINUE; } + +int LayerElement::SetDrawingXY( ArrayPtrVoid params ) +{ + // param 0: a pointer doc + // param 1: a pointer to the current system (unused) + // param 2: a pointer to the current measure + // param 3: a pointer to the current staff + Doc *doc = static_cast(params[0]); + Measure **currentMeasure = static_cast(params[2]); + Staff **currentStaff = static_cast(params[3]); + + // Look for cross-staff situations + // If we have one, make is available in m_crossStaff + DurationInterface *durElement = dynamic_cast(this); + if ( durElement && durElement->HasStaff()) { + AttCommonNComparison comparisonFirst( &typeid(Staff), durElement->GetStaff() ); + m_crossStaff = dynamic_cast((*currentMeasure)->FindChildByAttComparison(&comparisonFirst, 1)); + if (m_crossStaff) { + if (m_crossStaff == (*currentStaff)) LogWarning("The cross staff reference '%d' for element '%s' seems to be identical to the parent staff", durElement->GetStaff(), this->GetUuid().c_str()); + } + else LogWarning("Could not get the cross staff reference '%d' for element '%s'", durElement->GetStaff(), this->GetUuid().c_str()); + // If we have a @layer we probably also want to change the layer element (for getting the right clef if different) + } else { + m_crossStaff = NULL; + } + + Staff *staffY = m_crossStaff ? m_crossStaff : (*currentStaff); + + // Here we set the appropriate x value to be used for drawing + // With Raw documents, we use m_drawingXRel that is calculated by the layout algorithm + // With Transcription documents, we use the m_xAbs + if ( this->m_xAbs == VRV_UNSET ) { + assert( doc->GetType() == Raw ); + this->SetDrawingX( this->GetXRel() + (*currentMeasure)->GetDrawingX() ); + this->SetDrawingY( staffY->GetDrawingY() ); + } + else + { + assert( doc->GetType() == Transcription ); + this->SetDrawingX( this->m_xAbs ); + // cross staff with Transcription does not make sense anyway + this->SetDrawingY( staffY->GetDrawingY() ); + } + + return FUNCTOR_CONTINUE; +} } // namespace vrv diff --git a/src/measure.cpp b/src/measure.cpp index 98577a6ce1a..a7aea46d914 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -15,6 +15,7 @@ //---------------------------------------------------------------------------- +#include "doc.h" #include "page.h" #include "staff.h" #include "system.h" @@ -256,5 +257,32 @@ int Measure::CastOffSystems( ArrayPtrVoid params ) return FUNCTOR_SIBLINGS; } + +int Measure::SetDrawingXY( ArrayPtrVoid params ) +{ + // param 0: a pointer doc + // param 1: a pointer to the current system + // param 2: a pointer to the current measure + // param 3: a pointer to the current staff (unused) + Doc *doc = static_cast(params[0]); + System **currentSystem = static_cast(params[1]); + Measure **currentMeasure = static_cast(params[2]); + + // Here we set the appropriate y value to be used for drawing + // With Raw documents, we use m_drawingXRel that is calculated by the layout algorithm + // With Transcription documents, we use the m_xAbs + if ( this->m_xAbs == VRV_UNSET ) { + assert( doc->GetType() == Raw ); + this->SetDrawingX( this->m_drawingXRel + (*currentSystem)->GetDrawingX() ); + } + else + { + assert( doc->GetType() == Transcription ); + this->SetDrawingX( this->m_xAbs ); + } + (*currentMeasure) = this; + + return FUNCTOR_CONTINUE; +} } // namespace vrv diff --git a/src/staff.cpp b/src/staff.cpp index 15a147ff47a..957d82bf04b 100644 --- a/src/staff.cpp +++ b/src/staff.cpp @@ -14,6 +14,7 @@ //---------------------------------------------------------------------------- +#include "doc.h" #include "layer.h" #include "note.h" #include "syl.h" @@ -188,5 +189,33 @@ int Staff::ResetDarwing( ArrayPtrVoid params ) this->m_timeSpanningElements.clear(); return FUNCTOR_CONTINUE; }; + + +int Staff::SetDrawingXY( ArrayPtrVoid params ) +{ + // param 0: a pointer doc + // param 1: a pointer to the current system + // param 2: a pointer to the current measure (unused) + // param 3: a pointer to the current staff + Doc *doc = static_cast(params[0]); + System **currentSystem = static_cast(params[1]); + Staff **currentStaff = static_cast(params[3]); + + // Here we set the appropriate y value to be used for drawing + // With Raw documents, we use m_drawingYRel that is calculated by the layout algorithm + // With Transcription documents, we use the m_yAbs + if ( this->m_yAbs == VRV_UNSET ) { + assert( doc->GetType() == Raw ); + this->SetDrawingY( this->GetYRel() + (*currentSystem)->GetDrawingY() ); + } + else + { + assert( m_doc->GetType() == Transcription ); + this->SetDrawingY( this->m_yAbs ); + } + (*currentStaff) = this; + + return FUNCTOR_CONTINUE; +} } // namespace vrv diff --git a/src/system.cpp b/src/system.cpp index 68c6f0033c3..4b17419949f 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -297,4 +297,32 @@ int System::UnCastOff( ArrayPtrVoid params ) return FUNCTOR_SIBLINGS; } +int System::SetDrawingXY( ArrayPtrVoid params ) +{ + // param 0: a pointer doc + // param 1: a pointer to the current system + // param 2: a pointer to the current measure (unused) + // param 3: a pointer to the current staff (unused) + Doc *doc = static_cast(params[0]); + System **currentSystem = static_cast(params[1]); + + // Here we set the appropriate y value to be used for drawing + // With Raw documents, we use m_drawingYRel that is calculated by the layout algorithm + // With Transcription documents, we use the m_yAbs + if ( this->m_yAbs == VRV_UNSET ) { + assert( doc->GetType() == Raw ); + this->SetDrawingX( this->m_drawingXRel ); + this->SetDrawingY( this->m_drawingYRel ); + } + else + { + assert( doc->GetType() == Transcription ); + this->SetDrawingX( this->m_xAbs ); + this->SetDrawingY( this->m_yAbs ); + } + (*currentSystem) = this; + + return FUNCTOR_CONTINUE; +} + } // namespace vrv diff --git a/src/view_element.cpp b/src/view_element.cpp index 67094f142b4..e296fc70bb2 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -15,7 +15,6 @@ //---------------------------------------------------------------------------- -#include "att_comparison.h" #include "accid.h" #include "beam.h" #include "chord.h" @@ -63,22 +62,7 @@ void View::DrawLayerElement( DeviceContext *dc, LayerElement *element, Layer *la else { m_currentColour = AxBLACK; } - - // Here we set the appropriate x value to be used for drawing - // With Raw documents, we use m_drawingXRel that is calculated by the layout algorithm - // With Transcription documents, we use the m_xAbs - if ( element->m_xAbs == VRV_UNSET ) { - assert( m_doc->GetType() == Raw ); - element->SetDrawingX( element->GetXRel() + measure->GetDrawingX() ); - element->SetDrawingY( staff->GetDrawingY() ); - } - else - { - assert( m_doc->GetType() == Transcription ); - element->SetDrawingX( element->m_xAbs ); - element->SetDrawingY( staff->GetDrawingY() ); - } - + if (dynamic_cast(element)) { DrawAccid(dc, element, layer, staff, measure); } @@ -147,19 +131,6 @@ void View::DrawDurationElement( DeviceContext *dc, LayerElement *element, Layer { assert(layer); // Pointer to layer cannot be NULL" assert(staff); // Pointer to staff cannot be NULL" - - DurationInterface *durElement = dynamic_cast(element); - if ( !durElement ) - return; - - if (durElement->HasStaff()) { - AttCommonNComparison comparisonFirst( &typeid(Staff), durElement->GetStaff() ); - Staff *crossStaff = dynamic_cast(measure->FindChildByAttComparison(&comparisonFirst, 1)); - if (crossStaff) staff = crossStaff; - else LogWarning("Could not get the cross staff reference '%d' for element '%s'", durElement->GetStaff(), element->GetUuid().c_str()); - element->SetDrawingY( staff->GetDrawingY() ); - // If we have a @layer we probably also want to change the layer element (for getting the right clef if different) - } if (dynamic_cast(element)) { diff --git a/src/view_page.cpp b/src/view_page.cpp index e4cd40d4365..5f13e98377b 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -52,13 +52,21 @@ void View::DrawCurrentPage( DeviceContext *dc, bool background ) int i; System *system = NULL; + Measure *measure = NULL; + Staff *staff = NULL; + ArrayPtrVoid params; + params.push_back( m_doc ); + params.push_back( &system ); + params.push_back( &measure ); + params.push_back( &staff ); + Functor setDrawingXY( &Object::SetDrawingXY ); + m_currentPage->Process( &setDrawingXY, params ); // Set the current score def to the page one // The page one has previously been set by Object::SetCurrentScoreDef m_drawingScoreDef = m_currentPage->m_drawingScoreDef; - if ( background ) - dc->DrawRectangle( 0, 0, m_doc->m_drawingPageWidth, m_doc->m_drawingPageHeight ); + if ( background ) dc->DrawRectangle( 0, 0, m_doc->m_drawingPageWidth, m_doc->m_drawingPageHeight ); dc->DrawBackgroundImage( ); @@ -71,8 +79,6 @@ void View::DrawCurrentPage( DeviceContext *dc, bool background ) { system = dynamic_cast(m_currentPage->m_children[i]); DrawSystem( dc, system ); - - // TODO here: also update x_abs and m_drawingY positions for system. How to calculate them? } dc->EndPage(); @@ -93,18 +99,6 @@ void View::DrawSystem( DeviceContext *dc, System *system ) // first we need to clear the drawing list of postponed elements system->ResetDrawingList(); - - if ( system->m_yAbs == VRV_UNSET ) { - assert( m_doc->GetType() == Raw ); - system->SetDrawingX( system->m_drawingXRel ); - system->SetDrawingY( system->m_drawingYRel ); - } - else - { - assert( m_doc->GetType() == Transcription ); - system->SetDrawingX( system->m_xAbs ); - system->SetDrawingY( system->m_yAbs ); - } DrawSystemChildren(dc, system, system); @@ -626,20 +620,7 @@ void View::DrawMeasure( DeviceContext *dc, Measure *measure, System *system ) if ( measure->IsMeasuredMusic()) { dc->StartGraphic( measure, "", measure->GetUuid() ); } - - // Here we set the appropriate y value to be used for drawing - // With Raw documents, we use m_drawingXRel that is calculated by the layout algorithm - // With Transcription documents, we use the m_xAbs - if ( measure->m_xAbs == VRV_UNSET ) { - assert( m_doc->GetType() == Raw ); - measure->SetDrawingX( measure->m_drawingXRel + system->GetDrawingX() ); - } - else - { - assert( m_doc->GetType() == Transcription ); - measure->SetDrawingX( measure->m_xAbs ); - } - + DrawMeasureChildren(dc, measure, measure, system); if ( measure->GetLeftBarlineType() != BARRENDITION_NONE) { @@ -732,18 +713,7 @@ void View::DrawStaff( DeviceContext *dc, Staff *staff, Measure *measure, System dc->StartGraphic( staff, "", staff->GetUuid()); - // Here we set the appropriate y value to be used for drawing - // With Raw documents, we use m_drawingYRel that is calculated by the layout algorithm - // With Transcription documents, we use the m_yAbs - if ( staff->m_yAbs == VRV_UNSET ) { - assert( m_doc->GetType() == Raw ); - staff->SetDrawingY( staff->GetYRel() + system->GetDrawingY() ); - } - else - { - assert( m_doc->GetType() == Transcription ); - staff->SetDrawingY( staff->m_yAbs ); - } + // Doing it here might be problematic with cross-staff, even though the default value will be 5 if ( StaffDef *staffDef = m_drawingScoreDef.GetStaffDef( staff->GetN() ) ) { staff->m_drawingLines = staffDef->GetLines( ) ; } From 9c35b34434a2bce9282cd3bda4dccc827ed4cd16 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 16 Apr 2015 22:44:43 +0200 Subject: [PATCH 52/68] Removing DrawBeamPostponed --- include/vrv/view.h | 12 +----------- src/layer.cpp | 4 ++++ src/layerelement.cpp | 23 +++++++++++++++++++++++ src/measure.cpp | 2 ++ src/staff.cpp | 2 ++ src/system.cpp | 2 ++ src/view_beam.cpp | 44 +++++++++++++------------------------------- src/view_element.cpp | 42 +++--------------------------------------- src/view_page.cpp | 15 +++++---------- 9 files changed, 55 insertions(+), 91 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index 842ab631c9f..6b898e554c7 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -243,7 +243,7 @@ class View void DrawMeterSig( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawMRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawMultiRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); - void DrawNote( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure, bool fromBeam = false ); + void DrawNote( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawRest( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawSpace( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawSyl( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); @@ -300,16 +300,6 @@ class View void CalculateLigaturePosX ( LayerElement *element, Layer *layer, Staff *staff); ///@} - /** - * @name Method for drawing Beam. - * Called from the the layer postponed drawing list. - * Wolfgang legacy code to be redesigned. - * Defined in view_beam.cpp - */ - ///@{ - void DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff *staff, Measure *measure ); - ///@} - /** * @name Method for drawing Beam. * Called from the the layer postponed drawing list. diff --git a/src/layer.cpp b/src/layer.cpp index 30426864aa0..3a0da00f7b5 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -432,7 +432,10 @@ int Layer::SetDrawingXY( ArrayPtrVoid params ) // param 1: a pointer to the current system (unused) // param 2: a pointer to the current measure // param 3: a pointer to the current staff (unused) + // param 4: a pointer to the current layer + // param 5: a pointer to the view (unused) Measure **currentMeasure = static_cast(params[2]); + Layer **currentLayer = static_cast(params[4]); // set the values for the scoreDef elements when required if (this->GetDrawingClef()) { @@ -447,6 +450,7 @@ int Layer::SetDrawingXY( ArrayPtrVoid params ) if (this->GetDrawingMeterSig()) { this->GetDrawingMeterSig()->SetDrawingX( this->GetDrawingMeterSig()->GetXRel() + (*currentMeasure)->GetDrawingX() ); } + (*currentLayer) = this; return FUNCTOR_CONTINUE; } diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 22bfdd2244d..6b9850721d8 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -24,6 +24,7 @@ #include "doc.h" #include "dot.h" #include "keysig.h" +#include "layer.h" #include "measure.h" #include "mensur.h" #include "metersig.h" @@ -37,6 +38,7 @@ #include "timeinterface.h" #include "tuplet.h" #include "verse.h" +#include "view.h" #include "vrv.h" namespace vrv { @@ -420,9 +422,13 @@ int LayerElement::SetDrawingXY( ArrayPtrVoid params ) // param 1: a pointer to the current system (unused) // param 2: a pointer to the current measure // param 3: a pointer to the current staff + // param 4: a pointer to the current layer + // param 5: a pointer to the view Doc *doc = static_cast(params[0]); Measure **currentMeasure = static_cast(params[2]); Staff **currentStaff = static_cast(params[3]); + Layer **currentLayer = static_cast(params[4]); + View *view = static_cast(params[5]); // Look for cross-staff situations // If we have one, make is available in m_crossStaff @@ -457,6 +463,23 @@ int LayerElement::SetDrawingXY( ArrayPtrVoid params ) this->SetDrawingY( staffY->GetDrawingY() ); } + // Finally, adjust Y for notes and rests + if (dynamic_cast(this)) + { + Note *note = dynamic_cast(this); + this->SetDrawingY( this->GetDrawingY() + view->CalculatePitchPosY( staffY, note->GetPname(), (*currentLayer)->GetClefOffset( this ), note->GetOct() ) ); + } + else if (dynamic_cast(this)) { + Rest *rest = dynamic_cast(this); + + // Automatically calculate rest position, if so requested + if (rest->GetPloc() == PITCHNAME_NONE) { + this->SetDrawingY( this->GetDrawingY() + view->CalculateRestPosY( staffY, rest->GetActualDur()) ); + } else { + this->SetDrawingY( this->GetDrawingY() + view->CalculatePitchPosY( staffY, rest->GetPloc(), (*currentLayer)->GetClefOffset( this ), rest->GetOloc()) ); + } + } + return FUNCTOR_CONTINUE; } diff --git a/src/measure.cpp b/src/measure.cpp index a7aea46d914..e3722877856 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -264,6 +264,8 @@ int Measure::SetDrawingXY( ArrayPtrVoid params ) // param 1: a pointer to the current system // param 2: a pointer to the current measure // param 3: a pointer to the current staff (unused) + // param 4: a pointer to the current layer (unused) + // param 5: a pointer to the view (unused) Doc *doc = static_cast(params[0]); System **currentSystem = static_cast(params[1]); Measure **currentMeasure = static_cast(params[2]); diff --git a/src/staff.cpp b/src/staff.cpp index 957d82bf04b..a49a1e6e941 100644 --- a/src/staff.cpp +++ b/src/staff.cpp @@ -197,6 +197,8 @@ int Staff::SetDrawingXY( ArrayPtrVoid params ) // param 1: a pointer to the current system // param 2: a pointer to the current measure (unused) // param 3: a pointer to the current staff + // param 4: a pointer to the current layer (unused) + // param 5: a pointer to the view (unused) Doc *doc = static_cast(params[0]); System **currentSystem = static_cast(params[1]); Staff **currentStaff = static_cast(params[3]); diff --git a/src/system.cpp b/src/system.cpp index 4b17419949f..c14ff563895 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -303,6 +303,8 @@ int System::SetDrawingXY( ArrayPtrVoid params ) // param 1: a pointer to the current system // param 2: a pointer to the current measure (unused) // param 3: a pointer to the current staff (unused) + // param 4: a pointer to the current layer + // param 5: a pointer to the view (unused) Doc *doc = static_cast(params[0]); System **currentSystem = static_cast(params[1]); diff --git a/src/view_beam.cpp b/src/view_beam.cpp index d575e060084..b88373ff85b 100644 --- a/src/view_beam.cpp +++ b/src/view_beam.cpp @@ -29,8 +29,13 @@ namespace vrv { -void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff *staff, Measure *measure ) +void View::DrawBeam( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ) { + assert(layer); // Pointer to layer cannot be NULL" + assert(staff); // Pointer to staff cannot be NULL" + + Beam *beam = dynamic_cast(element); + LayerElement *current; bool changingDur = OFF; @@ -314,33 +319,13 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff /* pente correcte: entre 0 et env 0.4 (0.2 a 0.4) */ startingY = (s_y - beamSlope * s_x) / elementCount; - + /******************************************************************/ - // Draw notes for all objects in the beam now that stem direction is calculated + // Start the Beam graphic and draw the children - for (i = 0; i < elementCount; i++) { - if ((*beamElementCoords)[i]->m_element->IsChord()) { - Chord *chord = dynamic_cast((*beamElementCoords)[i]->m_element); - ListOfObjects *noteList = chord->GetList(chord); - ListOfObjects::iterator iter = noteList->begin(); - - dc->ResumeGraphic( dynamic_cast(chord), (chord)->GetUuid() ); - while ( iter != noteList->end()) { - Note *note = dynamic_cast(*iter); - if (!note) continue; - dc->ResumeGraphic( dynamic_cast(*iter), (*iter)->GetUuid() ); - DrawNote(dc, dynamic_cast(*iter), layer, staff, measure, true); - dc->EndResumedGraphic( dynamic_cast(*iter), this ); - iter++; - } - dc->EndResumedGraphic( dynamic_cast(chord), this ); - } - else if ((*beamElementCoords)[i]->m_element->IsNote()) { - dc->ResumeGraphic( dynamic_cast((*beamElementCoords)[i]->m_element), (*beamElementCoords)[i]->m_element->GetUuid() ); - DrawNote(dc, dynamic_cast((*beamElementCoords)[i]->m_element), layer, staff, measure, true); - dc->EndResumedGraphic( dynamic_cast((*beamElementCoords)[i]->m_element), this ); - } - } + dc->StartGraphic( element, "", element->GetUuid() ); + + DrawLayerChildren(dc, beam, layer, staff, measure); /******************************************************************/ // Calculate the stem lengths and draw them @@ -438,8 +423,6 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff marqueurs partitionnant les sous-groupes; la troisieme boucle for est pilotee par l'indice de l'array; elle dessine horizontalement les barres de chaque sous-groupe en suivant les marqueurs */ - - //return; if (changingDur) { testDur = DUR_8 + fullBars; @@ -525,9 +508,8 @@ void View::DrawBeamPostponed( DeviceContext *dc, Layer *layer, Beam *beam, Staff barY += shiftY * beamWidth; } // end of while } // end of drawing partial bars - - return; - + + dc->EndGraphic(element, this ); } } // namespace vrv diff --git a/src/view_element.cpp b/src/view_element.cpp index e296fc70bb2..d53835470f0 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -132,31 +132,17 @@ void View::DrawDurationElement( DeviceContext *dc, LayerElement *element, Layer assert(layer); // Pointer to layer cannot be NULL" assert(staff); // Pointer to staff cannot be NULL" - if (dynamic_cast(element)) - { + if (dynamic_cast(element)) { dc->StartGraphic( element, "", element->GetUuid() ); DrawChord(dc, element, layer, staff, measure); dc->EndGraphic(element, this ); } - else if (dynamic_cast(element)) - { - Note *note = dynamic_cast(element); - - element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, note->GetPname(), layer->GetClefOffset( element ), note->GetOct() ) ); + else if (dynamic_cast(element)) { dc->StartGraphic( element, "", element->GetUuid() ); DrawNote(dc, element, layer, staff, measure); dc->EndGraphic(element, this ); } else if (dynamic_cast(element)) { - Rest *rest = dynamic_cast(element); - - // Automatically calculate rest position, if so requested - if (rest->GetPloc() == PITCHNAME_NONE) { - element->SetDrawingY( element->GetDrawingY() + CalculateRestPosY( staff, rest->GetActualDur()) ); - } else { - element->SetDrawingY( element->GetDrawingY() + CalculatePitchPosY( staff, rest->GetPloc(), layer->GetClefOffset( element ), rest->GetOloc()) ); - } - dc->StartGraphic( element, "", element->GetUuid() ); DrawRest( dc, element, layer, staff, measure ); dc->EndGraphic(element, this ); @@ -165,23 +151,6 @@ void View::DrawDurationElement( DeviceContext *dc, LayerElement *element, Layer return; } -void View::DrawBeam(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure) { - - assert(layer); // Pointer to layer cannot be NULL" - assert(staff); // Pointer to staff cannot be NULL" - - Beam *beam = dynamic_cast(element); - - dc->StartGraphic( element, "", element->GetUuid() ); - - DrawLayerChildren(dc, beam, layer, staff, measure); - - // Add to the list of postponed element - layer->AddToDrawingList( beam ); - - dc->EndGraphic(element, this ); -} - void View::DrawTuplet(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure) { assert(layer); // Pointer to layer cannot be NULL" @@ -206,7 +175,7 @@ void View::DrawTuplet(DeviceContext *dc, LayerElement *element, Layer *layer, St // l'accord (ptr_n->fchord), la valeur y extreme opposee au sommet de la // queue: le ptr *testchord extern peut garder le x et l'y. -void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure, bool fromBeam ) +void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ) { assert(layer); // Pointer to layer cannot be NULL" assert(staff); // Pointer to staff cannot be NULL" @@ -244,11 +213,6 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St } } - if (inBeam && !fromBeam) { - // The note will be drawn from DrawBeamPostponed - return; - } - int staffSize = staff->staffSize; int noteY = element->GetDrawingY(); int xLedger, xNote, xAccid, xStem; diff --git a/src/view_page.cpp b/src/view_page.cpp index 5f13e98377b..70c71b334ff 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -54,11 +54,14 @@ void View::DrawCurrentPage( DeviceContext *dc, bool background ) System *system = NULL; Measure *measure = NULL; Staff *staff = NULL; + Layer *layer = NULL; ArrayPtrVoid params; params.push_back( m_doc ); params.push_back( &system ); params.push_back( &measure ); params.push_back( &staff ); + params.push_back( &layer ); + params.push_back( this ); Functor setDrawingXY( &Object::SetDrawingXY ); m_currentPage->Process( &setDrawingXY, params ); @@ -1076,9 +1079,7 @@ void View::DrawLayer( DeviceContext *dc, Layer *layer, Staff *staff, Measure *me DrawLayerChildren(dc, layer, layer, staff, measure); - // first draw the beams - DrawLayerList(dc, layer, staff, measure, &typeid(Beam) ); - // then tuplets + // first draw the tuplets DrawLayerList(dc, layer, staff, measure, &typeid(Tuplet) ); // then ties DrawLayerList(dc, layer, staff, measure, &typeid(Tie) ); @@ -1103,13 +1104,7 @@ void View::DrawLayerList( DeviceContext *dc, Layer *layer, Staff *staff, Measure element = dynamic_cast(*iter); if (!element) continue; - if ( (typeid(*element) == *elementType) && (*elementType == typeid(Beam) ) ) { - Beam *beam = dynamic_cast(element); - dc->ResumeGraphic(beam, beam->GetUuid()); - DrawBeamPostponed( dc, layer, beam, staff, measure ); - dc->EndResumedGraphic(beam, this); - } - else if ( (typeid(*element) == *elementType) && (*elementType == typeid(Tuplet) ) ) { + if ( (typeid(*element) == *elementType) && (*elementType == typeid(Tuplet) ) ) { Tuplet *tuplet = dynamic_cast(element); dc->ResumeGraphic(tuplet, tuplet->GetUuid()); DrawTupletPostponed( dc, tuplet, layer, staff ); From 21c45f16627c48e790627b27292ba93d7aa3f7b1 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 17 Apr 2015 08:54:20 +0200 Subject: [PATCH 53/68] Test with map and ledger lines --- include/vrv/chord.h | 1 + src/chord.cpp | 2 ++ src/view_element.cpp | 9 +++++++++ 3 files changed, 12 insertions(+) diff --git a/include/vrv/chord.h b/include/vrv/chord.h index 03e19623080..f66b7089377 100644 --- a/include/vrv/chord.h +++ b/include/vrv/chord.h @@ -111,6 +111,7 @@ class Chord: public LayerElement, public ObjectListInterface, public DurationInt * m_ledgerLines[x][0] is below staff, m_ledgerLines[x][1] is above staff */ char m_ledgerLines[2][2]; + std::map > test; /** * Positions of dots in the chord to avoid overlapping diff --git a/src/chord.cpp b/src/chord.cpp index af08c74eaaf..3ed387d9d49 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -34,6 +34,8 @@ LayerElement("chord-"), ObjectListInterface(), DurationInterface(), m_ledgerLines[0][1] = 0; m_ledgerLines[1][0] = 0; m_ledgerLines[1][1] = 0; + + //test[NULL][0][0] = 0; } Chord::~Chord() diff --git a/src/view_element.cpp b/src/view_element.cpp index d53835470f0..7e2b7cd93d2 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -352,6 +352,10 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St //if this is in a chord, we don't want to draw it yet, but we want to keep track of the maxima if (inChord) { + std::vector tmp; + tmp.resize(4); + tmp[3] = 3; + inChord->test[staff] = tmp; inChord->m_ledgerLines[doubleLengthLedger][aboveStaff] = ledgermax(numLines, inChord->m_ledgerLines[doubleLengthLedger][aboveStaff]); } //we do want to go ahead and draw if it's not in a chord @@ -360,6 +364,11 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St } } + if (inChord) { + std::vector *t = &inChord->test[staff]; + std::vector *t3 = &inChord->test[NULL]; + } + /************** Accidentals/dots/peripherals: **************/ if (note->GetAccid() != ACCIDENTAL_EXPLICIT_NONE) { From a94a52a92e00a4913485a5f85b66d06fe785adea Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 17 Apr 2015 09:19:49 +0200 Subject: [PATCH 54/68] WIP: Basic cross-staff swap --- src/view_element.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/view_element.cpp b/src/view_element.cpp index d53835470f0..0592eb3607b 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -188,6 +188,8 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St return; } + if (note->m_crossStaff) staff = note->m_crossStaff; + Chord *inChord = note->IsChordTone(); bool inBeam = false; From 972a4ca93cd36c69e1915a508157a40be65fa293 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 17 Apr 2015 11:04:11 +0200 Subject: [PATCH 55/68] Fixing SetDrawingXY for cross-staff below (now in two passes) --- src/layer.cpp | 12 ++++++++++-- src/layerelement.cpp | 1 + src/measure.cpp | 9 ++++++++- src/staff.cpp | 8 +++++++- src/system.cpp | 8 +++++++- src/view_page.cpp | 7 +++++++ 6 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/layer.cpp b/src/layer.cpp index 3a0da00f7b5..0612b4947ab 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -434,8 +434,16 @@ int Layer::SetDrawingXY( ArrayPtrVoid params ) // param 3: a pointer to the current staff (unused) // param 4: a pointer to the current layer // param 5: a pointer to the view (unused) + // param 6: a bool indicating if we are processing layer elements or not Measure **currentMeasure = static_cast(params[2]); Layer **currentLayer = static_cast(params[4]); + bool *processLayerElements = static_cast(params[6]); + + // Second pass where we do just process layer elements + if ((*processLayerElements)) { + (*currentLayer) = this; + return FUNCTOR_CONTINUE; + } // set the values for the scoreDef elements when required if (this->GetDrawingClef()) { @@ -450,9 +458,9 @@ int Layer::SetDrawingXY( ArrayPtrVoid params ) if (this->GetDrawingMeterSig()) { this->GetDrawingMeterSig()->SetDrawingX( this->GetDrawingMeterSig()->GetXRel() + (*currentMeasure)->GetDrawingX() ); } - (*currentLayer) = this; - return FUNCTOR_CONTINUE; + // If we are here it means we are not processing LayerElements + return FUNCTOR_SIBLINGS; } } // namespace vrv diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 6b9850721d8..1faf6e6355e 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -424,6 +424,7 @@ int LayerElement::SetDrawingXY( ArrayPtrVoid params ) // param 3: a pointer to the current staff // param 4: a pointer to the current layer // param 5: a pointer to the view + // param 6: a bool indicating if we are processing layer elements or not (unused) Doc *doc = static_cast(params[0]); Measure **currentMeasure = static_cast(params[2]); Staff **currentStaff = static_cast(params[3]); diff --git a/src/measure.cpp b/src/measure.cpp index e3722877856..5f0de63a476 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -266,9 +266,16 @@ int Measure::SetDrawingXY( ArrayPtrVoid params ) // param 3: a pointer to the current staff (unused) // param 4: a pointer to the current layer (unused) // param 5: a pointer to the view (unused) + // param 6: a bool indicating if we are processing layer elements or not Doc *doc = static_cast(params[0]); System **currentSystem = static_cast(params[1]); Measure **currentMeasure = static_cast(params[2]); + bool *processLayerElements = static_cast(params[6]); + + (*currentMeasure) = this; + + // Second pass where we do just process layer elements + if ((*processLayerElements)) return FUNCTOR_CONTINUE; // Here we set the appropriate y value to be used for drawing // With Raw documents, we use m_drawingXRel that is calculated by the layout algorithm @@ -282,7 +289,7 @@ int Measure::SetDrawingXY( ArrayPtrVoid params ) assert( doc->GetType() == Transcription ); this->SetDrawingX( this->m_xAbs ); } - (*currentMeasure) = this; + return FUNCTOR_CONTINUE; } diff --git a/src/staff.cpp b/src/staff.cpp index a49a1e6e941..f0f899efd3f 100644 --- a/src/staff.cpp +++ b/src/staff.cpp @@ -199,10 +199,17 @@ int Staff::SetDrawingXY( ArrayPtrVoid params ) // param 3: a pointer to the current staff // param 4: a pointer to the current layer (unused) // param 5: a pointer to the view (unused) + // param 6: a bool indicating if we are processing layer elements or not Doc *doc = static_cast(params[0]); System **currentSystem = static_cast(params[1]); Staff **currentStaff = static_cast(params[3]); + bool *processLayerElements = static_cast(params[6]); + (*currentStaff) = this; + + // Second pass where we do just process layer elements + if ((*processLayerElements)) return FUNCTOR_CONTINUE; + // Here we set the appropriate y value to be used for drawing // With Raw documents, we use m_drawingYRel that is calculated by the layout algorithm // With Transcription documents, we use the m_yAbs @@ -215,7 +222,6 @@ int Staff::SetDrawingXY( ArrayPtrVoid params ) assert( m_doc->GetType() == Transcription ); this->SetDrawingY( this->m_yAbs ); } - (*currentStaff) = this; return FUNCTOR_CONTINUE; } diff --git a/src/system.cpp b/src/system.cpp index c14ff563895..7c4de215319 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -305,8 +305,15 @@ int System::SetDrawingXY( ArrayPtrVoid params ) // param 3: a pointer to the current staff (unused) // param 4: a pointer to the current layer // param 5: a pointer to the view (unused) + // param 6: a bool indicating if we are processing layer elements or not Doc *doc = static_cast(params[0]); System **currentSystem = static_cast(params[1]); + bool *processLayerElements = static_cast(params[6]); + + (*currentSystem) = this; + + // Second pass where we do just process layer elements + if ((*processLayerElements)) return FUNCTOR_CONTINUE; // Here we set the appropriate y value to be used for drawing // With Raw documents, we use m_drawingYRel that is calculated by the layout algorithm @@ -322,7 +329,6 @@ int System::SetDrawingXY( ArrayPtrVoid params ) this->SetDrawingX( this->m_xAbs ); this->SetDrawingY( this->m_yAbs ); } - (*currentSystem) = this; return FUNCTOR_CONTINUE; } diff --git a/src/view_page.cpp b/src/view_page.cpp index 70c71b334ff..7c8b6801b39 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -55,6 +55,7 @@ void View::DrawCurrentPage( DeviceContext *dc, bool background ) Measure *measure = NULL; Staff *staff = NULL; Layer *layer = NULL; + bool processLayerElement = false; ArrayPtrVoid params; params.push_back( m_doc ); params.push_back( &system ); @@ -62,7 +63,13 @@ void View::DrawCurrentPage( DeviceContext *dc, bool background ) params.push_back( &staff ); params.push_back( &layer ); params.push_back( this ); + params.push_back( &processLayerElement ); Functor setDrawingXY( &Object::SetDrawingXY ); + // First pass without processing the LayerElements - we need this for cross-staff going down because + // the elements will need the position of the staff below to have been set before + m_currentPage->Process( &setDrawingXY, params ); + // Second pass that process the LayerElements (only) + processLayerElement = true; m_currentPage->Process( &setDrawingXY, params ); // Set the current score def to the page one From 16d4a198db586d936c8057741ee27540111a66fe Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 17 Apr 2015 11:04:36 +0200 Subject: [PATCH 56/68] Drawing scoreDef before content (now possible with SetDrawingXY) --- src/view_page.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/view_page.cpp b/src/view_page.cpp index 7c8b6801b39..753be3504e3 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -110,12 +110,6 @@ void View::DrawSystem( DeviceContext *dc, System *system ) // first we need to clear the drawing list of postponed elements system->ResetDrawingList(); - DrawSystemChildren(dc, system, system); - - // We draw the groups after the staves because we use the m_drawingY member of the staves - // that needs to be intialized. - // Warning: we assume for now the scoreDef occuring in the system will not change the staffGrps content - // and @symbol values, otherwise results will be unexpected... // First get the first measure of the system Measure *measure = dynamic_cast(system->FindChildByType( &typeid(Measure) ) ); if ( measure ) { @@ -131,6 +125,8 @@ void View::DrawSystem( DeviceContext *dc, System *system ) } } + DrawSystemChildren(dc, system, system); + // first draw the beams DrawSystemList(dc, system, &typeid(Syl) ); DrawSystemList(dc, system, &typeid(Tie) ); From fa34e6e90e66cf08d0aa584b496a997c0b950dbd Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 17 Apr 2015 11:05:00 +0200 Subject: [PATCH 57/68] Bug fix in layout with --- include/vrv/layerelement.h | 1 + src/layerelement.cpp | 8 +++++++- src/object.cpp | 7 +++++-- src/space.cpp | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/include/vrv/layerelement.h b/include/vrv/layerelement.h index 71d65a39d4d..afa29dbee7f 100644 --- a/include/vrv/layerelement.h +++ b/include/vrv/layerelement.h @@ -94,6 +94,7 @@ class LayerElement: public DocObject bool IsRest(); bool IsTie(); bool IsTuplet(); + bool IsSpace(); bool IsSyl(); bool IsVerse(); bool IsGraceNote(); diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 1faf6e6355e..1275162b9b9 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -32,6 +32,7 @@ #include "multirest.h" #include "note.h" #include "rest.h" +#include "space.h" #include "staff.h" #include "syl.h" #include "tie.h" @@ -246,7 +247,12 @@ bool LayerElement::IsTuplet() { return (dynamic_cast(this)); } - + +bool LayerElement::IsSpace() +{ + return (dynamic_cast(this)); +} + bool LayerElement::IsVerse() { return (dynamic_cast(this)); diff --git a/src/object.cpp b/src/object.cpp index 546e5ca02a1..015dc5cfc51 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1072,8 +1072,7 @@ int Object::SetBoundingBoxXShift( ArrayPtrVoid params ) assert( current->GetAlignment() ); if ( !current->HasUpdatedBB() ) { - // this is all we need for empty elements - current->GetAlignment()->SetXRel(*min_pos); + // if nothing was drawn, do not take it into account return FUNCTOR_CONTINUE; } @@ -1096,6 +1095,10 @@ int Object::SetBoundingBoxXShift( ArrayPtrVoid params ) return FUNCTOR_CONTINUE; } + if ( current->IsSpace() ) { + return FUNCTOR_CONTINUE; + } + if ( current->IsVerse() || current->IsSyl() ) { return FUNCTOR_CONTINUE; } diff --git a/src/space.cpp b/src/space.cpp index 4e8eaaa7d88..dcb0241dc26 100644 --- a/src/space.cpp +++ b/src/space.cpp @@ -15,7 +15,7 @@ namespace vrv { //---------------------------------------------------------------------------- Space::Space( ): - LayerElement("space-") + LayerElement("space-"), DurationInterface() { Reset(); } From 7ec015c29fc7c800152c50755c30ce2be32d7aaf Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Fri, 17 Apr 2015 13:31:03 -0400 Subject: [PATCH 58/68] Fixed: improved accidental drawing, added customizability -Tightened up dot drawing to avoid the 1.5 unit dot that looks a bit weird -Added more macros in vrvdef.h to better control accidental drawing -The bottom quarter of flats are now ignored when drawing to more concisely pack accidentals --- include/vrv/vrvdef.h | 12 +++++++++ src/chord.cpp | 6 ++--- src/view_element.cpp | 61 ++++++++++++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index 091c46ca45b..e87e7245909 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -178,8 +178,20 @@ enum ClefId { perc = CLEFSHAPE_perc << 8 | 1 }; +//The next four macros were tuned using the Leipzig font. + //Width (in half-drawing units) of an accidental; used to prevent overlap on complex chords #define ACCID_WIDTH 4 + +//Height +#define ACCID_HEIGHT 12 + +//Only keeps track of this much of the top of flats so that their bottom can be drawn more concisely +//This can also be thought of as height(sharp)*F_B_H_M = height(flat) +#define FLAT_BOTTOM_HEIGHT_MULTIPLIER .75 + +//Ignores this much of the top/right of a flat for same purposes (empty space in top right of drawing) +#define FLAT_CORNER_IGNORE .25 } // namespace vrv diff --git a/src/chord.cpp b/src/chord.cpp index af08c74eaaf..57ab7db933c 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -181,7 +181,6 @@ void Chord::ResetAccidSpace(int fullUnit) //dimensional units, other variables int halfUnit = fullUnit / 2; - int doubleUnit = fullUnit * 2; int idx, setIdx; /* @@ -196,8 +195,9 @@ void Chord::ResetAccidSpace(int fullUnit) * Each accidental's Y position will be its vertical center; set the grid extremes to account for that * Resize m_accidSpace to be as tall as is possibly necessary; must accomodate every accidental stacked vertically. */ - m_accidSpaceTop = m_accidList.front()->GetDrawingY() + doubleUnit; - m_accidSpaceBot = m_accidList.back()->GetDrawingY() - doubleUnit; + int accidHeight = ACCID_HEIGHT * halfUnit; + m_accidSpaceTop = m_accidList.front()->GetDrawingY() + (accidHeight / 2); + m_accidSpaceBot = m_accidList.back()->GetDrawingY() - (accidHeight / 2); int height = (m_accidSpaceTop - m_accidSpaceBot) / halfUnit; m_accidSpace.resize(height); diff --git a/src/view_element.cpp b/src/view_element.cpp index d53835470f0..d6b989cc82d 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -811,8 +811,8 @@ void View::PrepareChordDots ( DeviceContext *dc, Chord *chord, int x, int y, uns int yMax, yMin; chord->GetYExtremes(&yMax, &yMin); - if (y > (yMax + doubleUnit)) return; - if (y < (yMin - doubleUnit)) return; + if (y > (yMax + fullUnit)) return; + if (y < (yMin - fullUnit)) return; dotsList->push_back(y); DrawDots(dc, x, y, dots, staff); @@ -1005,7 +1005,6 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St accidFwd->SetDrawingX(xAccid); CalculateAccidX(staff, accidFwd, chord, true); DrawAccid(dc, accidFwd, layer, staff, measure); - //same, except with an extra check that we're not doing the same note twice if (fwIdx != bwIdx) { accidBwd->SetDrawingX(xAccid); @@ -1229,30 +1228,33 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust //global drawing variables int fullUnit = m_doc->m_drawingUnit[staff->staffSize]; - int doubleUnit = fullUnit * 2; int halfUnit = fullUnit / 2; + int accidHeight = ACCID_HEIGHT * halfUnit; //drawing variables for the chord int xLength = (int)accidSpace->front().size(); + int yHeight = (int)accidSpace->size() - 1; int listTop = chord->m_accidSpaceTop; int listBot = chord->m_accidSpaceBot; //drawing variables for the accidental int type = accid->GetAccid(); int centerY = accid->GetDrawingY(); - int topY = centerY + doubleUnit; - int bottomY = centerY - doubleUnit; + int topY = centerY + (accidHeight / 2); + int bottomY = centerY - (accidHeight / 2); + //difference between left end and right end of the accidental + int accidWidthDiff = ACCID_WIDTH - 1; + //difference between top and bottom of the accidental + int accidHeightDiff = ACCID_HEIGHT - 1; //drawing variables for the accidental in accidSpace units int accidTop = std::max(0, listTop - topY) / halfUnit; - int accidBot = ((int)accidSpace->size() - 1) - ((std::max(0, bottomY - listBot)) / halfUnit); - - assert(accidBot > accidTop); //because the "origin" (0, 0) is in the top right - - //difference between left end and right end of the accidental - int accidDiff = ACCID_WIDTH - 1; + int accidBot; //the left side of the accidental; gets incremented to avoid conflicts - int currentX = accidDiff; + int currentX = accidWidthDiff; + + //another way of calculating accidBot + assert(((int)accidSpace->size() - 1) - ((std::max(0, bottomY - listBot)) / halfUnit) == accidTop + accidHeightDiff); /* * Make sure all four corners of the accidental are not on an already-taken spot. @@ -1260,25 +1262,46 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust * Move the accidental one half-unit left until it doesn't overlap. */ if (type == ACCIDENTAL_EXPLICIT_f) { + accidBot = accidTop + (accidHeightDiff * FLAT_BOTTOM_HEIGHT_MULTIPLIER); while (currentX < xLength) { - if (accidSpace->at(accidTop + 2)[currentX - accidDiff]) currentX += 1; - else if (accidSpace->at(accidTop)[currentX - accidDiff + 1]) currentX += 1; - else if (accidSpace->at(accidBot)[currentX - accidDiff]) currentX += 1; + if (accidSpace->at(accidTop + (ACCID_HEIGHT * FLAT_CORNER_IGNORE))[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX - accidWidthDiff + (ACCID_WIDTH * FLAT_CORNER_IGNORE)]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX - accidWidthDiff]) currentX += 1; else if (accidSpace->at(accidTop)[currentX]) currentX += 1; else if (accidSpace->at(accidBot)[currentX]) currentX += 1; else break; }; } else { + accidBot = accidTop + accidHeightDiff; while (currentX < xLength) { - if (accidSpace->at(accidTop)[currentX - accidDiff]) currentX += 1; - else if (accidSpace->at(accidBot)[currentX - accidDiff]) currentX += 1; + if (accidSpace->at(accidTop)[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX - accidWidthDiff]) currentX += 1; else if (accidSpace->at(accidTop)[currentX]) currentX += 1; else if (accidSpace->at(accidBot)[currentX]) currentX += 1; else break; }; } + + //If the accidental is lined up with the one above it, move it left by a halfunit to avoid visual confusion + //This doesn't need to be done with accidentals that are as far left or up as possible + if ((currentX < xLength) && (accidTop > 0)) + { + int yComp = accidTop - 1; + if((accidSpace->at(yComp)[currentX + 1] == false) && (accidSpace->at(yComp)[currentX] == true)) currentX += 1; + } + + //If the accidental is lined up with the one below it, move it left by a halfunit to avoid visual confusion + //This doesn't need to be done with accidentals that are as far left or down as possible + if ((currentX < xLength) && (accidBot < (yHeight - 1))) + { + int yComp = accidBot - 1; + if((accidSpace->at(yComp)[currentX + 1] == false) && (accidSpace->at(yComp)[currentX] == true)) currentX += 1; + } + //Just to make sure. + assert(currentX <= xLength); + //If we need to move the accidental horizontally, move it by currentX half-units. if (adjustHorizontally) { @@ -1320,7 +1343,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust // std::cout << std::endl; //Regardless of whether or not we moved it, return true if there was a conflict and currentX would have been moved - return (currentX - accidDiff == 0); + return (currentX - accidWidthDiff == 0); } void View::DrawAccid( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure, Accid *prevAccid ) From 3bd48b34f3cd42e4089d1c2849b0e8c6b032ce0a Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 17 Apr 2015 20:03:48 +0200 Subject: [PATCH 59/68] Fixing layout with (forcing bounding box to be updated) --- include/vrv/bboxdevicecontext.h | 6 ++++++ include/vrv/devicecontext.h | 6 ++++++ src/bboxdevicecontext.cpp | 7 ++++++- src/object.cpp | 4 ---- src/view_element.cpp | 1 + 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/vrv/bboxdevicecontext.h b/include/vrv/bboxdevicecontext.h index afd4d1be985..f3354305d0b 100644 --- a/include/vrv/bboxdevicecontext.h +++ b/include/vrv/bboxdevicecontext.h @@ -82,6 +82,12 @@ class BBoxDeviceContext: public DeviceContext virtual void DrawBackgroundImage( int x = 0, int y = 0 ) {}; ///@} + /** + * Special method for forcing bounding boxes to be updated + * Used for invisible elements (e.g. ) that needs to be take into account in spacing + */ + virtual void DrawPlaceholder( int x, int y ); + /** * @name Method for starting and ending a text */ diff --git a/include/vrv/devicecontext.h b/include/vrv/devicecontext.h index 584566886c1..be3c52f324d 100644 --- a/include/vrv/devicecontext.h +++ b/include/vrv/devicecontext.h @@ -101,6 +101,12 @@ class DeviceContext virtual void DrawSpline(int n, Point points[]) = 0; virtual void DrawBackgroundImage( int x = 0, int y = 0 ) = 0; ///@} + + /** + * Special method for forcing bounding boxes to be updated + * Used for invisible elements (e.g. ) that needs to be take into account in spacing + */ + virtual void DrawPlaceholder( int x, int y ) {}; /** * @name Method for starting and ending a text diff --git a/src/bboxdevicecontext.cpp b/src/bboxdevicecontext.cpp index 4353f76f4a3..efab3566dc1 100644 --- a/src/bboxdevicecontext.cpp +++ b/src/bboxdevicecontext.cpp @@ -283,6 +283,11 @@ void BBoxDeviceContext::DrawRoundedRectangle(int x, int y, int width, int height UpdateBB( x - penWidth / 2, y - penWidth / 2, x + width + penWidth / 2, y + height + penWidth / 2); } +void BBoxDeviceContext::DrawPlaceholder( int x, int y ) +{ + UpdateBB( x, y, x, y ); +} + void BBoxDeviceContext::StartText(int x, int y, char alignement) { assert( !m_drawingText ); @@ -357,7 +362,7 @@ void BBoxDeviceContext::DrawSpline(int n, Point points[]) } -void BBoxDeviceContext::UpdateBB(int x1, int y1, int x2, int y2) +void BBoxDeviceContext::UpdateBB(int x1, int y1, int x2, int y2) { if (m_isDeactivated) { return; diff --git a/src/object.cpp b/src/object.cpp index 015dc5cfc51..517aab85700 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1095,10 +1095,6 @@ int Object::SetBoundingBoxXShift( ArrayPtrVoid params ) return FUNCTOR_CONTINUE; } - if ( current->IsSpace() ) { - return FUNCTOR_CONTINUE; - } - if ( current->IsVerse() || current->IsSyl() ) { return FUNCTOR_CONTINUE; } diff --git a/src/view_element.cpp b/src/view_element.cpp index 0592eb3607b..67eb918bb5d 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1390,6 +1390,7 @@ void View::DrawSpace(DeviceContext *dc, LayerElement *element, Layer *layer, Sta assert(staff); // Pointer to staff cannot be NULL" dc->StartGraphic( element, "", element->GetUuid() ); + dc->DrawPlaceholder( ToDeviceContextX( element->GetDrawingX() ), ToDeviceContextY( element->GetDrawingY() ) ); dc->EndGraphic(element, this ); } From 321027a9334bb826e14b3661e3016e49b4a0a341 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 17 Apr 2015 20:04:12 +0200 Subject: [PATCH 60/68] Cross-staff with clef changes --- include/vrv/layerelement.h | 4 ++- src/doc.cpp | 2 +- src/layer.cpp | 28 ++++++++------------- src/layerelement.cpp | 51 ++++++++++++++++++++++++++++++-------- 4 files changed, 55 insertions(+), 30 deletions(-) diff --git a/include/vrv/layerelement.h b/include/vrv/layerelement.h index afa29dbee7f..0f98785b1f6 100644 --- a/include/vrv/layerelement.h +++ b/include/vrv/layerelement.h @@ -16,6 +16,7 @@ namespace vrv { class Alignment; class BeamElementCoord; +class Layer; class Mensur; class MeterSig; class Staff; @@ -149,10 +150,11 @@ class LayerElement: public DocObject */ BeamElementCoord *m_beamElementCoord; /** - * This store a pointer to the cross-staff (if any) + * This store a pointer to the cross-staff (if any) and the appropriate layer * Initialized in LayerElement::SetDrawingXY */ Staff *m_crossStaff; + Layer *m_crossLayer; protected: Alignment *m_alignment; diff --git a/src/doc.cpp b/src/doc.cpp index b0bcbb9536e..6b47b4d2303 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -406,7 +406,7 @@ short Doc::GetLeftMargin( const std::type_info *elementType ) short Doc::GetRightMargin( const std::type_info *elementType ) { - if (typeid(Clef) == *elementType) return 20; + if (typeid(Clef) == *elementType) return 30; else if (typeid(KeySig) == *elementType) return 30; else if (typeid(Mensur) == *elementType) return 30; else if (typeid(MeterSig) == *elementType) return 30; diff --git a/src/layer.cpp b/src/layer.cpp index 0612b4947ab..3a3f36908a3 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -1,4 +1,4 @@ -///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// // Name: layer.cpp // Author: Laurent Pugin // Created: 2011 @@ -112,19 +112,13 @@ LayerElement *Layer::GetPrevious( LayerElement *element ) LayerElement *Layer::GetAtPos( int x ) { LayerElement *element = dynamic_cast( this->GetFirst() ); - if ( !element ) - return NULL; - + if ( !element || element->GetDrawingX() > x ) return NULL; - int dif = x - element->GetDrawingX(); LayerElement *next = NULL; - while ( (next = dynamic_cast( this->GetNext() ) ) && (int)element->GetDrawingX() < x ){ - element = next; - if ( (int)element->GetDrawingX() > x && dif < (int)element->GetDrawingX() - x ) - return this->GetPrevious( element ); - dif = x - element->GetDrawingX(); + while ( (next = dynamic_cast( this->GetNext() ) ) ) { + if ( next->GetDrawingX() > x ) return element; + element = next; } - return element; } @@ -281,7 +275,7 @@ Clef* Layer::GetClef( LayerElement *test ) Object *testObject = test; if (!test) { - return NULL; + return m_currentClef; } //make sure list is set @@ -301,9 +295,7 @@ Clef* Layer::GetClef( LayerElement *test ) int Layer::GetClefOffset( LayerElement *test ) { Clef *clef = GetClef(test); - if (!clef) { - return 0; - } + if (!clef) return 0; return clef->GetClefOffset(); } @@ -439,9 +431,10 @@ int Layer::SetDrawingXY( ArrayPtrVoid params ) Layer **currentLayer = static_cast(params[4]); bool *processLayerElements = static_cast(params[6]); + (*currentLayer) = this; + // Second pass where we do just process layer elements if ((*processLayerElements)) { - (*currentLayer) = this; return FUNCTOR_CONTINUE; } @@ -459,8 +452,7 @@ int Layer::SetDrawingXY( ArrayPtrVoid params ) this->GetDrawingMeterSig()->SetDrawingX( this->GetDrawingMeterSig()->GetXRel() + (*currentMeasure)->GetDrawingX() ); } - // If we are here it means we are not processing LayerElements - return FUNCTOR_SIBLINGS; + return FUNCTOR_CONTINUE; } } // namespace vrv diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 1275162b9b9..e60d4ba289a 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -430,12 +430,32 @@ int LayerElement::SetDrawingXY( ArrayPtrVoid params ) // param 3: a pointer to the current staff // param 4: a pointer to the current layer // param 5: a pointer to the view - // param 6: a bool indicating if we are processing layer elements or not (unused) + // param 6: a bool indicating if we are processing layer elements or not Doc *doc = static_cast(params[0]); Measure **currentMeasure = static_cast(params[2]); Staff **currentStaff = static_cast(params[3]); Layer **currentLayer = static_cast(params[4]); View *view = static_cast(params[5]); + bool *processLayerElements = static_cast(params[6]); + + // First pass, only set the X position + if ((*processLayerElements)==false) { + // Here we set the appropriate x value to be used for drawing + // With Raw documents, we use m_drawingXRel that is calculated by the layout algorithm + // With Transcription documents, we use the m_xAbs + if ( this->m_xAbs == VRV_UNSET ) { + assert( doc->GetType() == Raw ); + this->SetDrawingX( this->GetXRel() + (*currentMeasure)->GetDrawingX() ); + } + else + { + assert( doc->GetType() == Transcription ); + this->SetDrawingX( this->m_xAbs ); + } + return FUNCTOR_CONTINUE; + } + + LayerElement *layerElementY = this; // Look for cross-staff situations // If we have one, make is available in m_crossStaff @@ -445,28 +465,39 @@ int LayerElement::SetDrawingXY( ArrayPtrVoid params ) m_crossStaff = dynamic_cast((*currentMeasure)->FindChildByAttComparison(&comparisonFirst, 1)); if (m_crossStaff) { if (m_crossStaff == (*currentStaff)) LogWarning("The cross staff reference '%d' for element '%s' seems to be identical to the parent staff", durElement->GetStaff(), this->GetUuid().c_str()); + // Now try to get the corresponding layer - for now look for the same layer @n + int layerN = (*currentLayer)->GetN(); + // When we will have allowed @layer in , we will have to do: + // int layerN = durElement->HasLayer() ? durElement->GetLayer() : (*currentLayer)->GetN(); + AttCommonNComparison comparisonFirstLayer( &typeid(Layer), layerN ); + m_crossLayer = dynamic_cast(m_crossStaff->FindChildByAttComparison(&comparisonFirstLayer, 1)); + if (m_crossLayer) { + // Now we need to yet the element at the same position in the cross-staff layer of getting the right clef + layerElementY = m_crossLayer->GetAtPos( this->GetDrawingX() ); + + } else { + LogWarning("Could not get the layer with cross-staff reference '%d' for element '%s'", durElement->GetStaff(), this->GetUuid().c_str()); + } + } else { + LogWarning("Could not get the cross staff reference '%d' for element '%s'", durElement->GetStaff(), this->GetUuid().c_str()); } - else LogWarning("Could not get the cross staff reference '%d' for element '%s'", durElement->GetStaff(), this->GetUuid().c_str()); // If we have a @layer we probably also want to change the layer element (for getting the right clef if different) } else { m_crossStaff = NULL; + m_crossLayer = NULL; } Staff *staffY = m_crossStaff ? m_crossStaff : (*currentStaff); + Layer *layerY = m_crossLayer ? m_crossLayer : (*currentLayer); - // Here we set the appropriate x value to be used for drawing - // With Raw documents, we use m_drawingXRel that is calculated by the layout algorithm - // With Transcription documents, we use the m_xAbs + // Here we set the appropriate Y value to be used for drawing if ( this->m_xAbs == VRV_UNSET ) { assert( doc->GetType() == Raw ); - this->SetDrawingX( this->GetXRel() + (*currentMeasure)->GetDrawingX() ); this->SetDrawingY( staffY->GetDrawingY() ); } else { assert( doc->GetType() == Transcription ); - this->SetDrawingX( this->m_xAbs ); - // cross staff with Transcription does not make sense anyway this->SetDrawingY( staffY->GetDrawingY() ); } @@ -474,7 +505,7 @@ int LayerElement::SetDrawingXY( ArrayPtrVoid params ) if (dynamic_cast(this)) { Note *note = dynamic_cast(this); - this->SetDrawingY( this->GetDrawingY() + view->CalculatePitchPosY( staffY, note->GetPname(), (*currentLayer)->GetClefOffset( this ), note->GetOct() ) ); + this->SetDrawingY( this->GetDrawingY() + view->CalculatePitchPosY( staffY, note->GetPname(), layerY->GetClefOffset( layerElementY ), note->GetOct() ) ); } else if (dynamic_cast(this)) { Rest *rest = dynamic_cast(this); @@ -483,7 +514,7 @@ int LayerElement::SetDrawingXY( ArrayPtrVoid params ) if (rest->GetPloc() == PITCHNAME_NONE) { this->SetDrawingY( this->GetDrawingY() + view->CalculateRestPosY( staffY, rest->GetActualDur()) ); } else { - this->SetDrawingY( this->GetDrawingY() + view->CalculatePitchPosY( staffY, rest->GetPloc(), (*currentLayer)->GetClefOffset( this ), rest->GetOloc()) ); + this->SetDrawingY( this->GetDrawingY() + view->CalculatePitchPosY( staffY, rest->GetPloc(), layerY->GetClefOffset( layerElementY ), rest->GetOloc()) ); } } From 08225f40c3378d2f2a2531a7fee3e9e01e516823 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Fri, 17 Apr 2015 15:00:42 -0400 Subject: [PATCH 61/68] WIP: one more round of accidental rendering changes Separated out naturals from sharps and added upper-right corner ignoring --- include/vrv/vrvdef.h | 7 +++++-- src/view_element.cpp | 27 +++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index e87e7245909..37a5dc250d5 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -190,8 +190,11 @@ enum ClefId { //This can also be thought of as height(sharp)*F_B_H_M = height(flat) #define FLAT_BOTTOM_HEIGHT_MULTIPLIER .75 -//Ignores this much of the top/right of a flat for same purposes (empty space in top right of drawing) -#define FLAT_CORNER_IGNORE .25 +//Ignores this much of the top/right of an accid for same purposes (empty space in top right of drawing) +#define FLAT_CORNER_HEIGHT_IGNORE .25 +#define FLAT_CORNER_WIDTH_IGNORE .5 +#define NATURAL_CORNER_HEIGHT_IGNORE .25 +#define NATURAL_CORNER_WIDTH_IGNORE .5 } // namespace vrv diff --git a/src/view_element.cpp b/src/view_element.cpp index d6b989cc82d..ae8e9e9699a 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1264,20 +1264,39 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust if (type == ACCIDENTAL_EXPLICIT_f) { accidBot = accidTop + (accidHeightDiff * FLAT_BOTTOM_HEIGHT_MULTIPLIER); while (currentX < xLength) { - if (accidSpace->at(accidTop + (ACCID_HEIGHT * FLAT_CORNER_IGNORE))[currentX - accidWidthDiff]) currentX += 1; - else if (accidSpace->at(accidTop)[currentX - accidWidthDiff + (ACCID_WIDTH * FLAT_CORNER_IGNORE)]) currentX += 1; + if (accidSpace->at(accidTop + (ACCID_HEIGHT * FLAT_CORNER_HEIGHT_IGNORE))[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX - accidWidthDiff + (ACCID_WIDTH * FLAT_CORNER_WIDTH_IGNORE)]) currentX += 1; else if (accidSpace->at(accidBot)[currentX - accidWidthDiff]) currentX += 1; else if (accidSpace->at(accidTop)[currentX]) currentX += 1; else if (accidSpace->at(accidBot)[currentX]) currentX += 1; else break; }; } + else if (type == ACCIDENTAL_EXPLICIT_n) { + accidBot = accidTop + accidHeightDiff; + //Midpoint needs to be checked for non-flats as there's a chance that a natural/sharp could completely overlap a flat + int accidMid = accidTop + (accidBot - accidTop) / 2; + while (currentX < xLength) { + if (accidSpace->at(accidTop + (ACCID_HEIGHT * NATURAL_CORNER_HEIGHT_IGNORE))[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX - accidWidthDiff + (ACCID_WIDTH * NATURAL_CORNER_WIDTH_IGNORE)]) currentX += 1; + else if (accidSpace->at(accidMid)[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX]) currentX += 1; + else if (accidSpace->at(accidMid)[currentX]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX]) currentX += 1; + else break; + }; + } else { accidBot = accidTop + accidHeightDiff; + //Midpoint needs to be checked for non-flats as there's a chance that a natural/sharp could completely overlap a flat + int accidMid = accidTop + (accidBot - accidTop) / 2; while (currentX < xLength) { if (accidSpace->at(accidTop)[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidMid)[currentX - accidWidthDiff]) currentX += 1; else if (accidSpace->at(accidBot)[currentX - accidWidthDiff]) currentX += 1; else if (accidSpace->at(accidTop)[currentX]) currentX += 1; + else if (accidSpace->at(accidMid)[currentX]) currentX += 1; else if (accidSpace->at(accidBot)[currentX]) currentX += 1; else break; }; @@ -1287,7 +1306,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust //This doesn't need to be done with accidentals that are as far left or up as possible if ((currentX < xLength) && (accidTop > 0)) { - int yComp = accidTop - 1; + int yComp = accidTop - 2; if((accidSpace->at(yComp)[currentX + 1] == false) && (accidSpace->at(yComp)[currentX] == true)) currentX += 1; } @@ -1295,7 +1314,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust //This doesn't need to be done with accidentals that are as far left or down as possible if ((currentX < xLength) && (accidBot < (yHeight - 1))) { - int yComp = accidBot - 1; + int yComp = accidBot - 2; if((accidSpace->at(yComp)[currentX + 1] == false) && (accidSpace->at(yComp)[currentX] == true)) currentX += 1; } From d0922d87b462b1648b9179caa2fb3fbfc13d7135 Mon Sep 17 00:00:00 2001 From: Andrew Horwitz Date: Fri, 17 Apr 2015 16:30:49 -0400 Subject: [PATCH 62/68] WIP: making alignment threshold generic --- src/view_element.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index ae8e9e9699a..8e71d605424 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1249,7 +1249,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust int accidHeightDiff = ACCID_HEIGHT - 1; //drawing variables for the accidental in accidSpace units int accidTop = std::max(0, listTop - topY) / halfUnit; - int accidBot; + int accidBot, alignmentThreshold; //the left side of the accidental; gets incremented to avoid conflicts int currentX = accidWidthDiff; @@ -1262,6 +1262,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust * Move the accidental one half-unit left until it doesn't overlap. */ if (type == ACCIDENTAL_EXPLICIT_f) { + alignmentThreshold = 2; accidBot = accidTop + (accidHeightDiff * FLAT_BOTTOM_HEIGHT_MULTIPLIER); while (currentX < xLength) { if (accidSpace->at(accidTop + (ACCID_HEIGHT * FLAT_CORNER_HEIGHT_IGNORE))[currentX - accidWidthDiff]) currentX += 1; @@ -1273,6 +1274,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust }; } else if (type == ACCIDENTAL_EXPLICIT_n) { + alignmentThreshold = 1; accidBot = accidTop + accidHeightDiff; //Midpoint needs to be checked for non-flats as there's a chance that a natural/sharp could completely overlap a flat int accidMid = accidTop + (accidBot - accidTop) / 2; @@ -1287,8 +1289,24 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust else break; }; } + else if (type == ACCIDENTAL_EXPLICIT_s) { + accidBot = accidTop + accidHeightDiff; + alignmentThreshold = 1; + //Midpoint needs to be checked for non-flats as there's a chance that a natural/sharp could completely overlap a flat + int accidMid = accidTop + (accidBot - accidTop) / 2; + while (currentX < xLength) { + if (accidSpace->at(accidTop)[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidMid)[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX - accidWidthDiff]) currentX += 1; + else if (accidSpace->at(accidTop)[currentX]) currentX += 1; + else if (accidSpace->at(accidMid)[currentX]) currentX += 1; + else if (accidSpace->at(accidBot)[currentX]) currentX += 1; + else break; + }; + } else { accidBot = accidTop + accidHeightDiff; + alignmentThreshold = 1; //Midpoint needs to be checked for non-flats as there's a chance that a natural/sharp could completely overlap a flat int accidMid = accidTop + (accidBot - accidTop) / 2; while (currentX < xLength) { @@ -1306,7 +1324,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust //This doesn't need to be done with accidentals that are as far left or up as possible if ((currentX < xLength) && (accidTop > 0)) { - int yComp = accidTop - 2; + int yComp = accidTop - alignmentThreshold; if((accidSpace->at(yComp)[currentX + 1] == false) && (accidSpace->at(yComp)[currentX] == true)) currentX += 1; } @@ -1314,7 +1332,7 @@ bool View::CalculateAccidX(Staff *staff, Accid *accid, Chord *chord, bool adjust //This doesn't need to be done with accidentals that are as far left or down as possible if ((currentX < xLength) && (accidBot < (yHeight - 1))) { - int yComp = accidBot - 2; + int yComp = accidBot - alignmentThreshold; if((accidSpace->at(yComp)[currentX + 1] == false) && (accidSpace->at(yComp)[currentX] == true)) currentX += 1; } From eac0d826d20ea7ce6b64be6a804befa2bdc04496 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Sat, 18 Apr 2015 09:06:08 +0200 Subject: [PATCH 63/68] Bug fix in chord - calculating stem direction before dots --- src/view_element.cpp | 52 ++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index fa90ad05beb..ae963d8e87b 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -894,6 +894,32 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St DrawLayerChildren(dc, chord, layer, staff, measure); + /************ Stems ************/ + + int drawingDur = chord->GetDur(); + + //(unless we're in a beam) + if (!(inBeam && drawingDur > DUR_4)) { + int yMax, yMin; + chord->GetYExtremes(&yMax, &yMin); + + if ( chord->HasStemDir() ) { + chord->SetDrawingStemDir(chord->GetStemDir()); + } + else if ( layer->GetDrawingStemDir() != STEMDIRECTION_NONE) { + chord->SetDrawingStemDir(layer->GetDrawingStemDir()); + } + else { + chord->SetDrawingStemDir(yMax - verticalCenter >= verticalCenter - yMin ? STEMDIRECTION_down : STEMDIRECTION_up); + } + + int beamX = chord->GetDrawingX(); + int originY = ( chord->GetDrawingStemDir() == STEMDIRECTION_down ? yMax : yMin ); + int heightY = yMax - yMin; + + DrawStem(dc, chord, staff, chord->GetDrawingStemDir(), radius, beamX, originY, heightY); + } + /************ Dots ************/ chord->m_dots.clear(); @@ -1021,32 +1047,6 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St } } - /************ Stems ************/ - - int drawingDur = chord->GetDur(); - - //(unless we're in a beam) - if (!(inBeam && drawingDur > DUR_4)) { - int yMax, yMin; - chord->GetYExtremes(&yMax, &yMin); - - if ( chord->HasStemDir() ) { - chord->SetDrawingStemDir(chord->GetStemDir()); - } - else if ( layer->GetDrawingStemDir() != STEMDIRECTION_NONE) { - chord->SetDrawingStemDir(layer->GetDrawingStemDir()); - } - else { - chord->SetDrawingStemDir(yMax - verticalCenter >= verticalCenter - yMin ? STEMDIRECTION_down : STEMDIRECTION_up); - } - - int beamX = chord->GetDrawingX(); - int originY = ( chord->GetDrawingStemDir() == STEMDIRECTION_down ? yMax : yMin ); - int heightY = yMax - yMin; - - DrawStem(dc, chord, staff, chord->GetDrawingStemDir(), radius, beamX, originY, heightY); - } - /************ Ledger lines ************/ //if there are double-length lines, we only need to draw single-length after they've been drawn From 3f5bfffea1e69697e255adce59349f6add9a385c Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 20 Apr 2015 10:08:08 +0200 Subject: [PATCH 64/68] Reinit ledger lines before drawing notes --- src/view_element.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/view_element.cpp b/src/view_element.cpp index ca8ffb9fe47..90b2cfa47b5 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -892,6 +892,16 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St } } + /************ Ledger line reset ************/ + + //if there are double-length lines, we only need to draw single-length after they've been drawn + chord->m_ledgerLines[0][0] = 0; + chord->m_ledgerLines[0][1] = 0; + chord->m_ledgerLines[1][0] = 0; + chord->m_ledgerLines[1][1] = 0; + + /************ Draw children (notes) ************/ + DrawLayerChildren(dc, chord, layer, staff, measure); /************ Stems ************/ From 05eb2db38b10659c174a77caeea141dd93d9c961 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 20 Apr 2015 11:44:59 +0200 Subject: [PATCH 65/68] Test --- src/view_element.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index 7e2b7cd93d2..c23f8796fca 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -355,7 +355,7 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St std::vector tmp; tmp.resize(4); tmp[3] = 3; - inChord->test[staff] = tmp; + inChord->test[NULL] = tmp; inChord->m_ledgerLines[doubleLengthLedger][aboveStaff] = ledgermax(numLines, inChord->m_ledgerLines[doubleLengthLedger][aboveStaff]); } //we do want to go ahead and draw if it's not in a chord @@ -364,9 +364,13 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St } } - if (inChord) { + if (inChord && inChord->test.size()) { + int s = inChord->test.size(); + int ts = inChord->test.count(staff); + int ts3 = inChord->test.count(NULL); std::vector *t = &inChord->test[staff]; std::vector *t3 = &inChord->test[NULL]; + std::cout << t3; } /************** Accidentals/dots/peripherals: **************/ From de802a80b88a6184232ddbfdec7bb5817fbb0ae1 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 20 Apr 2015 12:11:43 +0200 Subject: [PATCH 66/68] Adding Staff map for ledger lines in chords --- include/vrv/chord.h | 9 ++++--- include/vrv/vrvdef.h | 10 +++++--- src/chord.cpp | 5 +--- src/view_element.cpp | 61 +++++++++++++++++++++++--------------------- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/include/vrv/chord.h b/include/vrv/chord.h index f66b7089377..433ae5e4f63 100644 --- a/include/vrv/chord.h +++ b/include/vrv/chord.h @@ -107,11 +107,12 @@ class Chord: public LayerElement, public ObjectListInterface, public DurationInt /** * Number of ledger lines for the chord where: - * m_ledgerLines[0][x] is single-length, m_ledgerLines[1][x] is double-length - * m_ledgerLines[x][0] is below staff, m_ledgerLines[x][1] is above staff + * Staff * is each staff for which the chord has notes and maps to: + * a four char vector acting as a 2D array (2x2) where: + * [0][x] is single-length, [1][x] is double-length + * [x][0] is below staff, [x][1] is above staff */ - char m_ledgerLines[2][2]; - std::map > test; + MapOfLedgerLineFlags m_drawingLedgerLines; /** * Positions of dots in the chord to avoid overlapping diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index 091c46ca45b..c6e85c4898c 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -11,6 +11,7 @@ #include #include +#include #include //---------------------------------------------------------------------------- @@ -18,11 +19,12 @@ #include "attdef.h" namespace vrv { - -class Object; + class AttComparison; -class Note; class BeamElementCoord; +class Note; +class Object; +class Staff; typedef std::vector ArrayOfObjects; @@ -36,6 +38,8 @@ typedef std::vector ChordCluster; typedef std::vector ArrayOfBeamElementCoords; +typedef std::map > MapOfLedgerLineFlags; + //---------------------------------------------------------------------------- // Global defines //---------------------------------------------------------------------------- diff --git a/src/chord.cpp b/src/chord.cpp index 3ed387d9d49..61352daaa1c 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -30,10 +30,7 @@ LayerElement("chord-"), ObjectListInterface(), DurationInterface(), { Reset(); m_drawingStemDir = STEMDIRECTION_NONE; - m_ledgerLines[0][0] = 0; - m_ledgerLines[0][1] = 0; - m_ledgerLines[1][0] = 0; - m_ledgerLines[1][1] = 0; + m_drawingLedgerLines.clear(); //test[NULL][0][0] = 0; } diff --git a/src/view_element.cpp b/src/view_element.cpp index c23f8796fca..e6fb5244d71 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -352,11 +352,14 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St //if this is in a chord, we don't want to draw it yet, but we want to keep track of the maxima if (inChord) { - std::vector tmp; - tmp.resize(4); - tmp[3] = 3; - inChord->test[NULL] = tmp; - inChord->m_ledgerLines[doubleLengthLedger][aboveStaff] = ledgermax(numLines, inChord->m_ledgerLines[doubleLengthLedger][aboveStaff]); + if (inChord->m_drawingLedgerLines.count(staff)==0) { + std::vector legerLines; + legerLines.resize(4); + inChord->m_drawingLedgerLines[staff] = legerLines; + } + int idx = doubleLengthLedger + aboveStaff * 2; // 2x2 array + std::vector *legerLines = &inChord->m_drawingLedgerLines[staff]; + (*legerLines)[idx] = ledgermax(numLines, (*legerLines)[idx]); } //we do want to go ahead and draw if it's not in a chord else { @@ -364,15 +367,6 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St } } - if (inChord && inChord->test.size()) { - int s = inChord->test.size(); - int ts = inChord->test.count(staff); - int ts3 = inChord->test.count(NULL); - std::vector *t = &inChord->test[staff]; - std::vector *t3 = &inChord->test[NULL]; - std::cout << t3; - } - /************** Accidentals/dots/peripherals: **************/ if (note->GetAccid() != ACCIDENTAL_EXPLICIT_NONE) { @@ -1060,25 +1054,34 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St } /************ Ledger lines ************/ - - //if there are double-length lines, we only need to draw single-length after they've been drawn - chord->m_ledgerLines[0][0] -= chord->m_ledgerLines[1][0]; - chord->m_ledgerLines[0][1] -= chord->m_ledgerLines[1][1]; - + dc->SetPen( m_currentColour, ToDeviceContextX( m_doc->m_style->m_staffLineWidth ), AxSOLID ); dc->SetBrush(m_currentColour , AxTRANSPARENT ); - //double-length lines below the staff - DrawLedgerLines(dc, chord, staff, false, true, 0, chord->m_ledgerLines[1][0]); - - //remainder single-length lines below the staff - DrawLedgerLines(dc, chord, staff, false, false, chord->m_ledgerLines[1][0], chord->m_ledgerLines[0][0]); - - //double-length lines above the staff - DrawLedgerLines(dc, chord, staff, true, true, 0, chord->m_ledgerLines[1][1]); + MapOfLedgerLineFlags::iterator iter; + for(iter = chord->m_drawingLedgerLines.begin(); iter != chord->m_drawingLedgerLines.end(); iter++) { + + std::vector *legerLines = &(*iter).second; + + //if there are double-length lines, we only need to draw single-length after they've been drawn + (*legerLines)[0] -= (*legerLines)[1]; + (*legerLines)[2] -= (*legerLines)[3]; + + //double-length lines below the staff + DrawLedgerLines(dc, chord, staff, false, true, 0, (*legerLines)[1]); + + //remainder single-length lines below the staff + DrawLedgerLines(dc, chord, staff, false, false, (*legerLines)[1], (*legerLines)[0]); + + //double-length lines above the staff + DrawLedgerLines(dc, chord, staff, true, true, 0, (*legerLines)[3]); + + //remainder single-length lines above the staff + DrawLedgerLines(dc, chord, staff, true, false, (*legerLines)[3], (*legerLines)[2]); + + } - //remainder single-length lines above the staff - DrawLedgerLines(dc, chord, staff, true, false, chord->m_ledgerLines[1][1], chord->m_ledgerLines[0][1]); + dc->ResetPen(); dc->ResetBrush(); From c20240fba960f45937134f14e3d61ac3ea509dd1 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 20 Apr 2015 14:22:15 +0200 Subject: [PATCH 67/68] Fixing staff parameter for DrawLedgerLines --- src/view_element.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index a82d09ee782..a13b6ce69d3 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1069,21 +1069,19 @@ void View::DrawChord( DeviceContext *dc, LayerElement *element, Layer *layer, St (*legerLines)[2] -= (*legerLines)[3]; //double-length lines below the staff - DrawLedgerLines(dc, chord, staff, false, true, 0, (*legerLines)[1]); + DrawLedgerLines(dc, chord, (*iter).first, false, true, 0, (*legerLines)[1]); //remainder single-length lines below the staff - DrawLedgerLines(dc, chord, staff, false, false, (*legerLines)[1], (*legerLines)[0]); + DrawLedgerLines(dc, chord, (*iter).first, false, false, (*legerLines)[1], (*legerLines)[0]); //double-length lines above the staff - DrawLedgerLines(dc, chord, staff, true, true, 0, (*legerLines)[3]); + DrawLedgerLines(dc, chord, (*iter).first, true, true, 0, (*legerLines)[3]); //remainder single-length lines above the staff - DrawLedgerLines(dc, chord, staff, true, false, (*legerLines)[3], (*legerLines)[2]); + DrawLedgerLines(dc, chord, (*iter).first, true, false, (*legerLines)[3], (*legerLines)[2]); } - - dc->ResetPen(); dc->ResetBrush(); } From 0c38cc998d7e15433ae17a63c5e389c2d937a9f2 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 21 Apr 2015 21:33:43 +0200 Subject: [PATCH 68/68] Increasing default left margin for notes and chords --- src/doc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc.cpp b/src/doc.cpp index 6b47b4d2303..43df030cdb2 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -397,9 +397,10 @@ short Doc::GetLeftMargin( const std::type_info *elementType ) { if (typeid(Barline) == *elementType) return 5; + else if (typeid(Chord) == *elementType) return 10; else if (typeid(Clef) == *elementType) return -20; else if (typeid(MRest) == *elementType) return 30; - //else if (typeid(Note) == *elementType) return 10; + else if (typeid(Note) == *elementType) return 10; return 0; }