From 09544d99df6e92a260739409cb7c9e223db8712d Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Mon, 24 Aug 2015 09:05:13 -0400 Subject: [PATCH 01/85] Clean up HorizontalSpaceForDuration(). --- src/aligner.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/aligner.cpp b/src/aligner.cpp index 51dd1d3a122..8466e30c8e5 100644 --- a/src/aligner.cpp +++ b/src/aligner.cpp @@ -365,13 +365,11 @@ notation (CMN), this is a function of the interval; for short intervals, it may be enough to keep consecutive symbols from overlapping. For mensural notation, ideal spacing is as tight as possible without overlapping and with just a bit of space between symbols. */ -int Alignment::HorizontalSpaceForDuration(double intervalTime, bool isMensural) +int Alignment::HorizontalSpaceForDuration(double intervalTime, bool fixedSpacing) { int intervalXRel = 0; - if (isMensural) - intervalXRel = 20; // ??EXPERIMENTAL! A very small value => space as tightly as possible - else - intervalXRel = pow( intervalTime, 0.60 ) * 2.5; // 2.5 is an arbitrary value; so is 0.60 + if (!fixedSpacing) + intervalXRel = pow( intervalTime, 0.60 ) * 2.5; // 2.5 is an arbitrary value; so is 0.60 return intervalXRel; } From c99cf29d068862fec245ed660b236f894729a788 Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Tue, 1 Sep 2015 10:47:13 -0400 Subject: [PATCH 02/85] Correct typos in comments. --- src/page.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/page.cpp b/src/page.cpp index 52ba21cbd49..f28f28f0a48 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -122,11 +122,11 @@ void Page::LayOutHorizontally( ) 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 (!) + // Special case: because we redirect the functor, pass it a parameter to itself (!) params.push_back( &setAlignmentX ); this->Process( &setAlignmentX, ¶ms ); - // Render it for filling the bounding boxing + // Render it for filling the bounding box View view; BBoxDeviceContext bb_dc( &view, 0, 0 ); view.SetDoc(doc); @@ -147,12 +147,12 @@ void Page::LayOutHorizontally( ) // Once the m_xShift have been calculated, move all positions accordingly params.clear(); Functor integrateBoundingBoxGraceXShift( &Object::IntegrateBoundingBoxGraceXShift ); - // special case: because we redirect the functor, pass is a parameter to itself (!) + // Special case: because we redirect the functor, pass it a parameter to itself (!) params.push_back( &integrateBoundingBoxGraceXShift ); this->Process( &integrateBoundingBoxGraceXShift, ¶ms ); // Adjust the X shift of the Alignment looking at the bounding boxes - // Look at each LayerElement and changes the m_xShift if the bouding box is overlapping + // Look at each LayerElement and changes the m_xShift if the bounding box is overlapping params.clear(); int min_pos = 0; int measure_width = 0; @@ -171,7 +171,7 @@ void Page::LayOutHorizontally( ) params.push_back( &shift ); params.push_back( &justifiable_shift ); Functor integrateBoundingBoxXShift( &Object::IntegrateBoundingBoxXShift ); - // special case: because we redirect the functor, pass is a parameter to itself (!) + // Special case: because we redirect the functor, pass it a parameter to itself (!) params.push_back( &integrateBoundingBoxXShift ); this->Process( &integrateBoundingBoxXShift, ¶ms ); @@ -205,7 +205,7 @@ void Page::LayOutVertically( ) Functor alignVertically( &Object::AlignVertically ); this->Process( &alignVertically, ¶ms ); - // Render it for filling the bounding boxing + // Render it for filling the bounding box View view; BBoxDeviceContext bb_dc( &view, 0, 0 ); view.SetDoc(doc); @@ -234,7 +234,7 @@ void Page::LayOutVertically( ) params.push_back( &staffMargin ); params.push_back( &interlineSize ); Functor setAlignmentY( &Object::SetAligmentYPos ); - // special case: because we redirect the functor, pass is a parameter to itself (!) + // Special case: because we redirect the functor, pass it a parameter to itself (!) params.push_back( &setAlignmentY ); this->Process( &setAlignmentY, ¶ms ); @@ -244,7 +244,7 @@ void Page::LayOutVertically( ) int shift = 0; params.push_back( &shift ); Functor integrateBoundingBoxYShift( &Object::IntegrateBoundingBoxYShift ); - // special case: because we redirect the functor, pass is a parameter to itself (!) + // Special case: because we redirect the functor, pass it a parameter to itself (!) params.push_back( &integrateBoundingBoxYShift ); this->Process( &integrateBoundingBoxYShift, ¶ms ); @@ -285,7 +285,7 @@ void Page::JustifyHorizontally( ) params.push_back( &margin ); params.push_back( &systemFullWidth ); Functor justifyX( &Object::JustifyX ); - // special case: because we redirect the functor, pass is a parameter to itself (!) + // Special case: because we redirect the functor, pass it a parameter to itself (!) params.push_back( &justifyX ); this->Process( &justifyX, ¶ms ); } From 431d411112fa1af453ee8f07d190379d1aaa7dfe Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Thu, 3 Sep 2015 13:31:53 -0400 Subject: [PATCH 03/85] Make explicit that the standard stem length is 7/2 staff spaces. --- src/view_element.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/view_element.cpp b/src/view_element.cpp index 5b8e4732123..c23bca54594 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -436,6 +436,8 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St return; } +#define STANDARD_STEMLENGTH 7 // in half staff spaces ??BUT SHOULD BE 6 IF 2-VOICE NOTATION! + void View::DrawStem( DeviceContext *dc, LayerElement *object, Staff *staff, data_STEMDIRECTION dir, int radius, int xn, int originY, int heightY) { assert(dynamic_cast(object)); @@ -447,7 +449,7 @@ void View::DrawStem( DeviceContext *dc, LayerElement *object, Staff *staff, data bool drawingCueSize = object->IsCueSize(); int verticalCenter = staffY - m_doc->GetDrawingDoubleUnit(staffSize)*2; - baseStem = m_doc->GetDrawingUnit(staffSize)*7; + baseStem = m_doc->GetDrawingUnit(staffSize)*STANDARD_STEMLENGTH; flagStemHeight = m_doc->GetDrawingDoubleUnit(staffSize); if (drawingCueSize) { baseStem = m_doc->GetGraceSize(baseStem); From 6318498d133c561f710f7d50e17a023c8978b113 Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Thu, 3 Sep 2015 13:32:38 -0400 Subject: [PATCH 04/85] Clarify comments on HorizontalSpaceForDuration() --- src/aligner.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/aligner.cpp b/src/aligner.cpp index 264c0e38852..62fd945c98a 100644 --- a/src/aligner.cpp +++ b/src/aligner.cpp @@ -433,11 +433,11 @@ int MeasureAligner::SetAligmentXPos( ArrayPtrVoid *params ) } -/* Compute "ideal" horizontal space to allow for a given time interval. For modern -notation (CMN), this is a function of the interval; for short intervals, it may not -be enough to keep consecutive symbols from overlapping. For mensural notation, ideal -spacing is as tight as possible without overlapping and with just a bit of space -between symbols. */ +/* Compute "ideal" horizontal space to allow for a given time interval, ignoring the need +to keep consecutive symbols from overlapping or nearly overlapping: we assume spacing +will be increased as necessary later to avoid that. For modern notation (CMN), ideal space +is a function of time interval. For mensural notation, we set ideal spacing to zero so we'll +always end up with spacing as tight as possible. */ int Alignment::HorizontalSpaceForDuration(double intervalTime, bool fixedSpacing) { int intervalXRel = 0; @@ -458,7 +458,7 @@ int Alignment::SetAligmentXPos( ArrayPtrVoid *params ) int intervalXRel = 0; double intervalTime = (m_time - (*previousTime)); - if ( intervalTime > 0.0 ) intervalXRel = HorizontalSpaceForDuration(intervalTime, true); // ??2ND PARAM = IS MENSURAL! + if ( intervalTime > 0.0 ) intervalXRel = HorizontalSpaceForDuration(intervalTime, true); // ??2ND PARAM SHOULD BE true IFF MENSURAL! m_xRel = (*previousXRel) + (intervalXRel) * DEFINITON_FACTOR; (*previousTime) = m_time; From db7153f9933553bd50918adc3386c04ca3bda7f5 Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Tue, 8 Sep 2015 16:17:06 -0400 Subject: [PATCH 05/85] Add "even-note-spacing" command-line option, intended for use with mensural notation; fix typos & clarify some comments --- include/vrv/doc.h | 29 +++++++++++++++++++++-------- include/vrv/toolkit.h | 7 +++++++ src/aligner.cpp | 14 +++++++++----- src/doc.cpp | 1 + src/page.cpp | 28 +++++++++++++++------------- src/toolkit.cpp | 6 ++++++ tools/main.cpp | 17 +++++++++++------ 7 files changed, 70 insertions(+), 32 deletions(-) diff --git a/include/vrv/doc.h b/include/vrv/doc.h index 1b7bec84790..430982ddeb7 100644 --- a/include/vrv/doc.h +++ b/include/vrv/doc.h @@ -119,9 +119,9 @@ class Doc: public Object ///@} /** - * @name Getters for the object margins (left and right) - * The margin are given in x / PARAM_DENOMINATOR * UNIT - * With PARAM_DENOMINATOR == 10, a margin of 25 is 2.5 UNIT + * @name Getters for the object margins (left and right). + * The margins are given in x / PARAM_DENOMINATOR * UNIT + * With PARAM_DENOMINATOR == 10, a margin of 25 is 2.5 UNIT. * These should eventually be set at parameters. */ ///@{ @@ -131,16 +131,27 @@ class Doc: public Object /* * @name Setter and getter for the justification (x-axis) flag. - * Justification is enabled by default. It need to be disable - * for drawing all the document on one single system. + * Justification is enabled by default. It needs to be disabled + * for drawing the entire document on one single system. */ ///@{ void SetJustificationX( bool drawingJustifyX ) { m_drawingJustifyX = drawingJustifyX; }; bool GetJustificationX( ) { return m_drawingJustifyX; }; ///@} + /* + * @name Setter and getter for the duration-based-spacing flag. + * Spacing by duration is always used with CMN, and it's enabled by default. + * It should be disabled (so we get "even" note spacing) for mensural notation. + */ + ///@{ + void SetEvenSpacing( bool drawingEvenSpacing ) { m_drawingEvenSpacing = drawingEvenSpacing; }; + bool GetEvenSpacing( ) { return m_drawingEvenSpacing; }; + + ///@} + /** - * Set the initial scoreDef of each page + * Set the initial scoreDef of each page. * This is necessary for integrating changes that occur within a page. * It uses the MusObject::SetPageScoreDef functor method for parsing the file. * This will be done only if m_currentScoreDefDone is false or force is true. @@ -250,6 +261,8 @@ class Doc: public Object float m_drawingBeamMaxSlope; /** flag for disabling justification */ bool m_drawingJustifyX; + /** flag for disabling spacing by duration */ + bool m_drawingEvenSpacing; /** minimum measure width */ int m_drawingMinMeasureWidth; @@ -305,14 +318,14 @@ class Doc: public Object FontInfo m_drawingLyricFont; /** - * A flag for indicating whether the currentScoreDef has been set or not + * A flag to indicate whether the currentScoreDef has been set or not. * If yes, SetCurrentScoreDef will not parse the document (again) unless * the force parameter is set. */ bool m_currentScoreDefDone; /** - * A flag for indicating if the drawing preparation has been done. If yes, + * A flag to indicate if the drawing preparation has been done. If yes, * drawing preparation will be reset before being done again. */ bool m_drawingPreparationDone; diff --git a/include/vrv/toolkit.h b/include/vrv/toolkit.h index debac7e3094..905daf3675d 100644 --- a/include/vrv/toolkit.h +++ b/include/vrv/toolkit.h @@ -214,6 +214,12 @@ class Toolkit int GetAdjustPageHeight() { return m_adjustPageHeight; }; ///@} + + /** + * @name Space notes equally and close together (normally for mensural notation) */ + void SetEvenNoteSpacing( bool even ) { m_evenNoteSpacing = even; }; + int GetEvenNoteSpacing() { return m_evenNoteSpacing; }; + /** * @name Do not justify the system (for debugging purposes) */ @@ -318,6 +324,7 @@ class Toolkit bool m_adjustPageHeight; std::string m_rdgXPathQuery; bool m_scoreBasedMei; + bool m_evenNoteSpacing; // for debugging bool m_noJustification; bool m_showBoundingBoxes; diff --git a/src/aligner.cpp b/src/aligner.cpp index 62fd945c98a..3453fd6eedb 100644 --- a/src/aligner.cpp +++ b/src/aligner.cpp @@ -436,12 +436,16 @@ int MeasureAligner::SetAligmentXPos( ArrayPtrVoid *params ) /* Compute "ideal" horizontal space to allow for a given time interval, ignoring the need to keep consecutive symbols from overlapping or nearly overlapping: we assume spacing will be increased as necessary later to avoid that. For modern notation (CMN), ideal space -is a function of time interval. For mensural notation, we set ideal spacing to zero so we'll -always end up with spacing as tight as possible. */ -int Alignment::HorizontalSpaceForDuration(double intervalTime, bool fixedSpacing) +is a function of time interval. For mensural notation, we'd want ideal spacing to be zero +so as to end up with spacing as tight as possible. + +This function needs more flexibility: for example, for some purposes, spacing propoortional +to duration is desirable. The best solution is probably to get ideal spacing from a user- +definable table. */ +int Alignment::HorizontalSpaceForDuration(double intervalTime, bool evenSpacing) { int intervalXRel = 0; - if (!fixedSpacing) + if (!evenSpacing) intervalXRel = pow( intervalTime, 0.60 ) * 2.5; // 2.5 is an arbitrary value; so is 0.60 return intervalXRel; } @@ -458,7 +462,7 @@ int Alignment::SetAligmentXPos( ArrayPtrVoid *params ) int intervalXRel = 0; double intervalTime = (m_time - (*previousTime)); - if ( intervalTime > 0.0 ) intervalXRel = HorizontalSpaceForDuration(intervalTime, true); // ??2ND PARAM SHOULD BE true IFF MENSURAL! + if ( intervalTime > 0.0 ) intervalXRel = HorizontalSpaceForDuration(intervalTime, false); m_xRel = (*previousXRel) + (intervalXRel) * DEFINITON_FACTOR; (*previousTime) = m_time; diff --git a/src/doc.cpp b/src/doc.cpp index d4962bb1dd4..4b364b60857 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -71,6 +71,7 @@ void Doc::Reset( DocType type ) m_drawingPage = NULL; m_drawingJustifyX = true; + m_drawingEvenSpacing = true; m_currentScoreDefDone = false; m_drawingPreparationDone = false; diff --git a/src/page.cpp b/src/page.cpp index f28f28f0a48..543fb7c70c5 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -112,19 +112,21 @@ void Page::LayOutHorizontally( ) Functor alignHorizontallyEnd( &Object::AlignHorizontallyEnd ); this->Process( &alignHorizontally, ¶ms, &alignHorizontallyEnd ); - // Set the X position of each Alignment - // Does a duration-based non linear spacing looking at the duration space between two Alignment objects - 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 it a parameter to itself (!) - params.push_back( &setAlignmentX ); - this->Process( &setAlignmentX, ¶ms ); + // Unless duration-based spacing is disabled, get the X position of each Alignment. + // Does non-linear spacing based on the duration space between two Alignment objects. + if (!doc->GetEvenSpacing()) { + 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 it a parameter to itself (!) + params.push_back( &setAlignmentX ); + this->Process( &setAlignmentX, ¶ms ); + } // Render it for filling the bounding box View view; diff --git a/src/toolkit.cpp b/src/toolkit.cpp index 1933d539c1d..2169101378f 100644 --- a/src/toolkit.cpp +++ b/src/toolkit.cpp @@ -52,6 +52,7 @@ Toolkit::Toolkit( bool initFont ) m_ignoreLayout = false; m_adjustPageHeight = false; m_noJustification = false; + m_evenNoteSpacing = true; m_showBoundingBoxes = false; m_scoreBasedMei = false; @@ -303,6 +304,11 @@ bool Toolkit::LoadString( const std::string &data ) m_doc.SetJustificationX(false); } + // disable duration-based spacing if requested + if (!m_evenNoteSpacing) { + m_doc.SetEvenSpacing(false); + } + delete input; m_view.SetDoc( &m_doc ); diff --git a/tools/main.cpp b/tools/main.cpp index 0633168dc5b..5273f4bbc62 100644 --- a/tools/main.cpp +++ b/tools/main.cpp @@ -73,11 +73,11 @@ void display_usage() { cerr << " verovio [-f format] [-s scale] [-t type] [-r resources] [-o outfile] infile" << endl << endl; // These need to be kept in alphabetical order: - // -short options first - // -then long options only + // -options with both short and long forms first + // -then options with long forms only // -then debugging options - // Options + // Options with both short and long forms cerr << "Options" << endl; @@ -101,13 +101,15 @@ void display_usage() { cerr << " -w, --page-width=WIDTH Specify the page width (default is " << DEFAULT_PAGE_WIDTH << ")" << endl; - // long options only + // Options with long forms only cerr << endl << "Additional options" << endl; cerr << " --adjust-page-height Crop the page height to the height of the content" << endl; cerr << " --all-pages Output all pages with one output file per page" << endl; + cerr << " --even-note-spacing Space notes evenly and close together regardless of their durations" << endl; + cerr << " --font=FONT Select the music font to use (default is Leipzig; Bravura and Gootville are also available)" << endl; cerr << " --help Display this message" << endl; @@ -152,6 +154,7 @@ int main(int argc, char** argv) int no_layout = 0; int ignore_layout = 0; int no_justification = 0; + int even_note_spacing = 0; int show_bounding_boxes = 0; int page = 1; int show_help = 0; @@ -166,7 +169,7 @@ int main(int argc, char** argv) type = pae_file; if (argc < 2) { - cerr << "Expecting one input file." << endl << endl; + cerr << "Expected one input file but found none." << endl << endl; display_usage(); exit(1); } @@ -178,6 +181,7 @@ int main(int argc, char** argv) {"adjust-page-height", no_argument, &adjust_page_height, 1}, {"all-pages", no_argument, &all_pages, 1}, {"border", required_argument, 0, 'b'}, + {"even-note-spacing", no_argument, &even_note_spacing, 1}, {"font", required_argument, 0, 0}, {"format", required_argument, 0, 'f'}, {"help", no_argument, &show_help, 1}, @@ -301,13 +305,14 @@ int main(int argc, char** argv) toolkit.SetNoLayout(no_layout); toolkit.SetIgnoreLayout(ignore_layout); toolkit.SetNoJustification(no_justification); + toolkit.SetEvenNoteSpacing(even_note_spacing); toolkit.SetShowBoundingBoxes(show_bounding_boxes); if (optind <= argc - 1) { infile = string(argv[optind]); } else { - cerr << "Incorrect number of arguments: expecting one input file." << endl << endl; + cerr << "Incorrect number of arguments: expected one input file but found none." << endl << endl; display_usage(); exit(1); } From 8c48690bb8bcf687930b8b7fc780e1b076d6560f Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Tue, 8 Sep 2015 16:26:21 -0400 Subject: [PATCH 06/85] Fix recently-introduced bugs in mensural notation: dots in mensuration signs are too low and much too large; in mensural notation, make noteheads smaller relative to staff size; fix vertical position of half circle in mensuration sign; make proports much smaller; move proport-drawing functions from view_element.cp to view_mensural.cp. --- include/vrv/view.h | 3 +- src/view_element.cpp | 37 --------- src/view_mensural.cpp | 183 ++++++++++++++++++++++++++++++------------ src/view_page.cpp | 5 +- 4 files changed, 137 insertions(+), 91 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index ad895604b00..5fe440f2033 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -217,7 +217,6 @@ class View 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 DrawProport( 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 ); @@ -274,6 +273,7 @@ class View ///@{ void DrawMensur( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); void DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); + void DrawProport( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure ); /** * @name Methods for drawing parts of mensural LayerElement child classes. @@ -288,6 +288,7 @@ class View 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); + void DrawProportFigures( DeviceContext *dc, int x, int y, int num, int numBase, Staff *staff); ///@} /** diff --git a/src/view_element.cpp b/src/view_element.cpp index c23bca54594..bc03c87df6f 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1593,43 +1593,6 @@ void View::DrawDot( DeviceContext *dc, LayerElement *element, Layer *layer, Staf dc->EndGraphic(element, this ); } - - -void View::DrawProport( 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" - assert(dynamic_cast(element)); // Element must be a Mensur" - - int x1, x2, y1, y2; - - Proport *proport = dynamic_cast(element); - - dc->StartGraphic( element, "", element->GetUuid() ); - - int y = staff->GetDrawingY() - (m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*4); - int x = element->GetDrawingX(); - - x1 = x+120; x2 = x1+150; // ??TEST: JUST DRAW AN ARBITRARY RECTANGLE - y1 = y; y2 = y+50+(50*proport->GetNum()); - //DrawFullRectangle( dc,x1,y1,x2,y2); - DrawPartFullRectangle( dc,x1,y1,x2,y2, 0); - - if (proport->HasNum()) - { - x = element->GetDrawingX(); - //if (proport->GetSign() || proport->HasTempus()) // ??WHAT SHOULD THIS BE? - { - x += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 5; // step forward because we have a sign or a meter symbol - } - int numbase = proport->HasNumbase() ? proport->GetNumbase() : 0; - DrawMeterSigFigures ( dc, x, staff->GetDrawingY(), proport->GetNum(), numbase, staff); - } - - - dc->EndGraphic(element, this ); -} - int View::GetSylY( Syl *syl, Staff *staff ) { diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index 1cf21e1cb16..bb8f4279f15 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -19,12 +19,26 @@ #include "layer.h" #include "mensur.h" #include "note.h" +#include "proport.h" #include "smufl.h" #include "staff.h" #include "style.h" namespace vrv { +/* ??THESE #defines PROBABLY BELONG IN style.h . */ + +/* Set ratio of mensural notehead size to CMN notehead size for the same staff size */ +#define MENSUR_NOTEHEAD_FACTOR 0.60 +/* Set size of mensuration sign circle relative to space between staff lines. The entire mensuration sign fits + easily between two staff lines, so the radius is considerably less than half the distance between them. */ +#define MCIRCLE_RADIUS_FACTOR 0.32 +/* Set vertical position of center of mensuration sign as distance below top of the staff */ +#define MENSURSIGN_STAFFLINES_BELOW_TOP 1.5 +/* Set size rel. to dist. between staff lines of mensural-notation dot, e.g., within mensuration signs */ +#define MENSURSIGN_DOTSIZE 0.15 + + 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 @@ -44,12 +58,13 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l assert( note ); int staffSize = staff->m_drawingStaffSize; + // Mensural noteheads are quite a bit smaller than CMN noteheads; use _pseudoStaffSize_ to force this. + int pseudoStaffSize = (int)(MENSUR_NOTEHEAD_FACTOR * staff->m_drawingStaffSize); int noteY = element->GetDrawingY(); int xLedger, xNote, xStem; int drawingDur; - bool drawingCueSize; int staffY = staff->GetDrawingY(); - wchar_t fontNo; + wchar_t charCode; int ledge; int verticalCenter = 0; @@ -57,15 +72,14 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l xLedger = xStem; drawingDur = note->GetDrawingDur(); - drawingCueSize = note->HasGrace(); - int radius = m_doc->GetGlyphWidth(SMUFL_E0A3_noteheadHalf, staffSize, drawingCueSize); + int radius = m_doc->GetGlyphWidth(SMUFL_E0A3_noteheadHalf, pseudoStaffSize, false) / 2; if (drawingDur > DUR_1 || (drawingDur == DUR_1 && staff->notAnc)) { // annuler provisoirement la modif. des lignes addit. - ledge = m_doc->GetDrawingLedgerLineLength(staffSize, drawingCueSize); + ledge = m_doc->GetDrawingLedgerLineLength(pseudoStaffSize, false); } else { - ledge = m_doc->GetDrawingLedgerLineLength(staffSize, drawingCueSize); + ledge = m_doc->GetDrawingLedgerLineLength(pseudoStaffSize, false); radius += radius/3; } @@ -87,7 +101,7 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l /************** Noteheads: **************/ - // Long, breve and ligatures + // Ligature, maxima,longa, brevis, and semibrevis if ((note->GetLig()!=LIGATURE_NONE) && (drawingDur <= DUR_1)) { DrawLigature ( dc, noteY, element, layer, staff); } @@ -96,24 +110,24 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l } else if (drawingDur == DUR_1) { if (note->GetColored()) - fontNo = SMUFL_E938_mensuralNoteheadSemibrevisBlack; + charCode = SMUFL_E938_mensuralNoteheadSemibrevisBlack; else - fontNo = SMUFL_E939_mensuralNoteheadSemibrevisVoid; + charCode = SMUFL_E939_mensuralNoteheadSemibrevisVoid; - DrawSmuflCode( dc, xNote, noteY, fontNo, staff->m_drawingStaffSize, drawingCueSize ); + DrawSmuflCode( dc, xNote, noteY, charCode, pseudoStaffSize, false ); } - // Other values ??WE WANT MENSURAL NOTEHEADS, NOT CMN!!!!!!!! + // Shorter values ??WE WANT MENSURAL NOTEHEADS, NOT CMN!!!!!!!! else { if (note->GetColored()) { - if (drawingDur == DUR_2) fontNo = SMUFL_E0A4_noteheadBlack; - else fontNo = SMUFL_E0A3_noteheadHalf; + if (drawingDur == DUR_2) charCode = SMUFL_E0A3_noteheadHalf; + else charCode = SMUFL_E0A4_noteheadBlack; } else { - if (drawingDur > DUR_2) fontNo = SMUFL_E0A4_noteheadBlack; - else fontNo = SMUFL_E0A3_noteheadHalf; + if (drawingDur > DUR_2) charCode = SMUFL_E93C_mensuralNoteheadMinimaWhite; + else charCode = SMUFL_E0A3_noteheadHalf; } - DrawSmuflCode( dc, xNote, noteY, fontNo, staff->m_drawingStaffSize, drawingCueSize ); + DrawSmuflCode( dc, xNote, noteY, charCode, pseudoStaffSize, false ); DrawStem(dc, note, staff, note->GetDrawingStemDir(), radius, xStem, noteY); } @@ -140,11 +154,12 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l /************** dots **************/ if (note->GetDots()) { + int mensDrawingUnit = (int)(MENSUR_NOTEHEAD_FACTOR * m_doc->GetDrawingUnit(staffSize)); int xDot; if (note->GetDur() < DUR_2 || (note->GetDur() > DUR_8 && (note->GetDrawingStemDir() == STEMDIRECTION_up))) - xDot = xStem + m_doc->GetDrawingUnit(staffSize)*7/2; + xDot = xStem + mensDrawingUnit*7/2; else - xDot = xStem + m_doc->GetDrawingUnit(staffSize)*5/2; + xDot = xStem + mensDrawingUnit*5/2; DrawDots( dc, xDot, noteY, note->GetDots(), staff ); } @@ -196,29 +211,19 @@ void View::DrawMensur( DeviceContext *dc, LayerElement *element, Layer *layer, S x += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 5; // step forward because we have a sign or a meter symbol } int numbase = mensur->HasNumbase() ? mensur->GetNumbase() : 0; - DrawMeterSigFigures ( dc, x, staff->GetDrawingY(), mensur->GetNum(), numbase, staff); + DrawProportFigures ( dc, x, staff->GetDrawingY(), mensur->GetNum(), numbase, staff); } dc->EndGraphic(element, this ); } -/* Set size of mensuration sign circle relative to space between staff lines. The entire mensuration sign fits easily between two staff lines, so the radius is considerably less than half the distance between them. - ??THESE #defines PROBABLY BELONG IN style.h . */ -#define MCIRCLE_RADIUS_FACTOR 0.32 -/* Set default vertical position of mensuration sign circle as distance below the top of the staff for center - of the circle */ -#define MCIRCLE_STAFFLINES_BELOW_TOP 1.5 -/* Set size rel. to dist. between staff lines of mensural-notation dot, e.g., within mensuration signs */ -#define MENSUR_DOTSIZE 0.15 - - void View::DrawMensurCircle( DeviceContext *dc, int x, int yy, Staff *staff ) { assert( dc ); assert( staff ); - int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MCIRCLE_STAFFLINES_BELOW_TOP); + int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MENSURSIGN_STAFFLINES_BELOW_TOP); int r = ToDeviceContextX( m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize )); r = (int)(MCIRCLE_RADIUS_FACTOR*r); @@ -241,13 +246,16 @@ void View::DrawMensurHalfCircle( DeviceContext *dc, int x, int yy, Staff *staff dc->SetPen( m_currentColour, m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize), AxSOLID ); dc->SetBrush( m_currentColour, AxTRANSPARENT ); - int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MCIRCLE_STAFFLINES_BELOW_TOP); + int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MENSURSIGN_STAFFLINES_BELOW_TOP); int r = ToDeviceContextX( m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize )); r = (int)(MCIRCLE_RADIUS_FACTOR*r); x = ToDeviceContextX (x); x -= 3*r/3; + /* DrawEllipticArc expects x and y to specify the coordinates of the upper-left corner of the + rectangle that contains the ellipse; y is not the center of the circle it's an arc of. */ + y -= staff->m_drawingStaffSize / 2; dc->DrawEllipticArc( x, y, 2*r, 2*r, 45, 315 ); dc->ResetPen(); @@ -284,10 +292,8 @@ void View::DrawMensurDot ( DeviceContext *dc, int x, int yy, Staff *staff ) assert( dc ); assert( staff ); - //int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MCIRCLE_STAFFLINES_BELOW_TOP); - //int r = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * MENSUR_DOTSIZE; - int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * 2); - int r = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2 / 3; + int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MENSURSIGN_STAFFLINES_BELOW_TOP); + int r = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * MENSURSIGN_DOTSIZE; dc->SetPen( m_currentColour, 1, AxSOLID ); dc->SetBrush( m_currentColour, AxSOLID ); @@ -348,24 +354,27 @@ void View::DrawMaximaToBrevis( DeviceContext *dc, int y, LayerElement *element, Note *note = dynamic_cast(element); assert( note ); + // Mensural noteheads are quite a bit smaller than CMN noteheads; use _pseudoStaffSize_ to force this. + int pseudoStaffSize = (int)(MENSUR_NOTEHEAD_FACTOR * staff->m_drawingStaffSize); int xn, x1, x2, y1, y2, y3, y4; // int yy2, y5; // unused int verticalCenter, up, height; - height = m_doc->GetDrawingBeamWidth(staff->m_drawingStaffSize, false) / 2 ; + height = m_doc->GetDrawingBeamWidth(pseudoStaffSize, false) / 2 ; xn = element->GetDrawingX(); - // calcul des dimensions du rectangle - x1 = xn - m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize ); - x2 = xn + m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize ); + // Calculate size of the rectangle + x1 = xn - m_doc->GetDrawingBrevisWidth( pseudoStaffSize ); + x2 = xn + m_doc->GetDrawingBrevisWidth( pseudoStaffSize ); if (note->GetActualDur() == DUR_MX) { - x1 -= m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize ); - x2 += m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize ); + // Maxima is three times the width of brevis + x1 -= m_doc->GetDrawingBrevisWidth( pseudoStaffSize ); + x2 += m_doc->GetDrawingBrevisWidth( pseudoStaffSize ); } - y1 = y + m_doc->GetDrawingUnit(staff->m_drawingStaffSize); - y2 = y - m_doc->GetDrawingUnit(staff->m_drawingStaffSize); - y3 = (int)(y1 + m_doc->GetDrawingUnit(staff->m_drawingStaffSize)/2); // partie d'encadrement qui depasse - y4 = (int)(y2 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize)/2); + y1 = y + m_doc->GetDrawingUnit(pseudoStaffSize); + y2 = y - m_doc->GetDrawingUnit(pseudoStaffSize); + y3 = (int)(y1 + m_doc->GetDrawingUnit(pseudoStaffSize)/2); // partie d'encadrement qui depasse + y4 = (int)(y2 - m_doc->GetDrawingUnit(pseudoStaffSize)/2); if (note->GetColored()!=BOOLEAN_true) { // double base des carrees @@ -376,13 +385,13 @@ void View::DrawMaximaToBrevis( DeviceContext *dc, int y, LayerElement *element, DrawFullRectangle( dc,x1,y1,x2,y2); } - DrawVerticalLine ( dc, y3, y4, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) ); // corset lateral - DrawVerticalLine ( dc, y3, y4, x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) ); + DrawVerticalLine ( dc, y3, y4, x1, m_doc->GetDrawingStemWidth(pseudoStaffSize) ); // corset lateral + DrawVerticalLine ( dc, y3, y4, x2, m_doc->GetDrawingStemWidth(pseudoStaffSize) ); // stem if (note->GetActualDur() < DUR_BR) { - verticalCenter = staff->GetDrawingY() - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize)*2; + verticalCenter = staff->GetDrawingY() - m_doc->GetDrawingDoubleUnit(pseudoStaffSize)*2; up = (y < verticalCenter) ? true : false; if ( note->GetDrawingStemDir() != STEMDIRECTION_NONE ) { if ( note->GetDrawingStemDir() == STEMDIRECTION_up) { @@ -394,14 +403,14 @@ void View::DrawMaximaToBrevis( DeviceContext *dc, int y, LayerElement *element, } if (!up) { - y3 = y1 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*8; + y3 = y1 - m_doc->GetDrawingUnit(pseudoStaffSize)*8; y2 = y1; } else { - y3 = y1 + m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*6; + y3 = y1 + m_doc->GetDrawingUnit(pseudoStaffSize)*6; y2 = y1; } - DrawVerticalLine ( dc, y2,y3,x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) ); + DrawVerticalLine ( dc, y2,y3,x2, m_doc->GetDrawingStemWidth(pseudoStaffSize) ); } return; @@ -549,7 +558,79 @@ void View::DrawLigature ( DeviceContext *dc, int y, LayerElement *element, Layer return; } + +void View::DrawProportFigures( DeviceContext *dc, int x, int y, int num, int numBase, Staff *staff) +{ + assert( dc ); + assert( staff ); + + int ynum, yden; + int textSize = (1.0/2.0)*staff->m_drawingStaffSize; + std::wstring wtext; + + if (numBase) + { + ynum = y - (m_doc->GetDrawingUnit(textSize)*2); + yden = ynum - (m_doc->GetDrawingDoubleUnit(textSize)*2); + } + else + ynum = y - (m_doc->GetDrawingUnit(textSize)*4); + + if (numBase > 9 || num > 9) { + x += m_doc->GetDrawingUnit(textSize) * 2; + } + + dc->SetFont(m_doc->GetDrawingSmuflFont(textSize, false)); + + wtext = IntToTimeSigFigures(num); + DrawSmuflString ( dc, x, ynum, wtext, true, textSize); // true = center + + if (numBase) + { + wtext = IntToTimeSigFigures(numBase); + DrawSmuflString ( dc, x, yden, wtext, true, textSize); // '1' = center + } + + dc->ResetFont(); + + return; +} + +void View::DrawProport( 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" + assert(dynamic_cast(element)); // Element must be a Mensur" + + int x1, x2, y1, y2; + + Proport *proport = dynamic_cast(element); + + dc->StartGraphic( element, "", element->GetUuid() ); + + int y = staff->GetDrawingY() - (m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*4); + int x = element->GetDrawingX(); + + x1 = x+120; x2 = x1+150; // ??TEST: JUST DRAW AN ARBITRARY RECTANGLE + y1 = y; y2 = y+50+(50*proport->GetNum()); + //DrawFullRectangle( dc,x1,y1,x2,y2); + DrawPartFullRectangle( dc,x1,y1,x2,y2, 0); + + if (proport->HasNum()) + { + x = element->GetDrawingX(); + //if (proport->GetSign() || proport->HasTempus()) // ??WHAT SHOULD THIS BE? + { + x += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 5; // step forward because we have a sign or a meter symbol + } + int numbase = proport->HasNumbase() ? proport->GetNumbase() : 0; + DrawProportFigures ( dc, x, staff->GetDrawingY(), proport->GetNum(), numbase, staff); + } + + + dc->EndGraphic(element, this ); +} } // namespace vrv diff --git a/src/view_page.cpp b/src/view_page.cpp index 687271afeb4..265b66336a3 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -742,9 +742,10 @@ void View::DrawStaffLines( DeviceContext *dc, Staff *staff, Measure *measure, Sy x2 = x1 + measure->GetWidth(); //dc->SetPen( m_currentColour, ToDeviceContextX( m_doc->m_style->m_staffLineWidth ), AxSOLID ); - int lineWidth = (int)(m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize) * MENSURAL_LINEWIDTH_FACTOR); + int lineWidth = (int)(m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize)); + if (true) lineWidth = lineWidth * MENSURAL_LINEWIDTH_FACTOR; // ??DON'T DO IF NOT MENSURAL NOTATION! dc->SetPen( m_currentColour, ToDeviceContextX( lineWidth ), AxSOLID ); - dc->SetPen( m_currentColour, ToDeviceContextX( m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize) ), AxSOLID ); + //dc->SetPen( m_currentColour, ToDeviceContextX( m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize) ), AxSOLID ); dc->SetBrush( m_currentColour , AxSOLID ); for(j = 0;j < staff->m_drawingLines; j++) From 118eee5976725451ab6565165471c8c3ffd9977c Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 9 Sep 2015 23:08:33 +0200 Subject: [PATCH 07/85] Minor adjustments --- src/view_floating.cpp | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/view_floating.cpp b/src/view_floating.cpp index 7ef3eb4bb98..f38784467cb 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -183,7 +183,8 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff bool up = true; data_STEMDIRECTION noteStemDir = STEMDIRECTION_NONE; - int y1, y2; + int y1 = staff->GetDrawingY(); + int y2 = staff->GetDrawingY(); /************** parent layers **************/ @@ -222,26 +223,23 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff LogWarning("Slurs between different layers may not be fully supported."); } - /************** y positions **************/ + /************** note stem dir **************/ // the normal case - if ( spanningType == SPANNING_START_END ) { + if (spanningType == SPANNING_START_END) { noteStemDir = start->GetDrawingStemDir(); } // 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 ) { + else if (spanningType == SPANNING_START) { noteStemDir = start->GetDrawingStemDir(); } // Now this is the case when the tie is split but we are drawing the end of it - else if ( spanningType == SPANNING_END ) { + else if (spanningType == SPANNING_END) { noteStemDir = end->GetDrawingStemDir(); } // Finally, slur accross an entire system; use the staff position and up (see below) else { - // To be adjusted - y1 = staff->GetDrawingY(); - y2 = y1; noteStemDir = STEMDIRECTION_down; } @@ -268,7 +266,7 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff else if (noteStemDir == STEMDIRECTION_NONE) { // no information from the note stem directions, look at the position in the notes int center = staff->GetDrawingY() - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * 2; - up = (y1 > center) ? true : false; + up = (start->GetDrawingY() > center) ? true : false; } /************** adjusting y position **************/ @@ -321,7 +319,7 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff // (^)P if (endStemDir == STEMDIRECTION_down) y2 = end->GetDrawingY(); // d(^)d - else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsLastInBeam(end)) { + else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end)) { y2 = end->m_drawingStemEnd.y; } // (^)d @@ -335,7 +333,7 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff // (_)d if (endStemDir == STEMDIRECTION_up) y2 = end->GetDrawingY(); // P(_)P - else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsLastInBeam(end)) { + else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end)) { y2 = end->m_drawingStemEnd.y; } // (_)P @@ -346,6 +344,23 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff } } } + + if (spanningType == SPANNING_START) { + if (up) y2 = std::max(staff->GetDrawingY(), y1); + else y2 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y1); + } + // Now this is the case when the tie is split but we are drawing the end of it + else if (spanningType == SPANNING_END) { + if (up) y1 = std::max(staff->GetDrawingY(), y2); + else y1 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y2); + } + // Finally, slur accross an entire system; use the staff position and up (see below) + else if (spanningType != SPANNING_START_END) { + // To be adjusted + if (up) y1 = staff->GetDrawingY(); + else y1 = staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize); + y2 = y1; + } /************** y position **************/ From 1d660b95da04b5137ab28948d007b19a9c8050e9 Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Wed, 9 Sep 2015 21:06:19 -0400 Subject: [PATCH 08/85] Correct bad typo in comment ("get" should be "set"!) --- src/page.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page.cpp b/src/page.cpp index b9f1115d172..0dc47e34029 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -112,7 +112,7 @@ void Page::LayOutHorizontally( ) Functor alignHorizontallyEnd( &Object::AlignHorizontallyEnd ); this->Process( &alignHorizontally, ¶ms, &alignHorizontallyEnd ); - // Unless duration-based spacing is disabled, get the X position of each Alignment. + // Unless duration-based spacing is disabled, set the X position of each Alignment. // Does non-linear spacing based on the duration space between two Alignment objects. if (!doc->GetEvenSpacing()) { params.clear(); From 38ad7febe01a9f1c1944a9eed33d9cb2dfac8885 Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Wed, 9 Sep 2015 21:08:41 -0400 Subject: [PATCH 09/85] Rename #define'd constants for clarity; add a #define; clarify comments --- src/view_mensural.cpp | 44 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index bb8f4279f15..269ba384827 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -29,15 +29,17 @@ namespace vrv { /* ??THESE #defines PROBABLY BELONG IN style.h . */ /* Set ratio of mensural notehead size to CMN notehead size for the same staff size */ -#define MENSUR_NOTEHEAD_FACTOR 0.60 -/* Set size of mensuration sign circle relative to space between staff lines. The entire mensuration sign fits - easily between two staff lines, so the radius is considerably less than half the distance between them. */ -#define MCIRCLE_RADIUS_FACTOR 0.32 +#define MNOTEHEAD_SIZE_FACTOR 0.60 +/* Set size of mensuration sign circle relative to space between staff lines. (In early manuscripts, +the entire mensuration sign fits easily between two staff lines, so the radius is considerably less +than half the distance between them.) */ +#define MSIGN_CIRCLE_RADIUS_FACTOR 0.32 /* Set vertical position of center of mensuration sign as distance below top of the staff */ -#define MENSURSIGN_STAFFLINES_BELOW_TOP 1.5 -/* Set size rel. to dist. between staff lines of mensural-notation dot, e.g., within mensuration signs */ -#define MENSURSIGN_DOTSIZE 0.15 - +#define MSIGN_STAFFLINES_BELOW_TOP 1.5 +/* Set size rel. to dist. between staff lines of dot inside mensuration signs */ +#define MSIGN_DOTSIZE 0.15 +/* Set relative size of figures in proportions */ +#define PROPRT_SIZE_FACTOR 0.50 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 @@ -59,7 +61,7 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l int staffSize = staff->m_drawingStaffSize; // Mensural noteheads are quite a bit smaller than CMN noteheads; use _pseudoStaffSize_ to force this. - int pseudoStaffSize = (int)(MENSUR_NOTEHEAD_FACTOR * staff->m_drawingStaffSize); + int pseudoStaffSize = (int)(MNOTEHEAD_SIZE_FACTOR * staff->m_drawingStaffSize); int noteY = element->GetDrawingY(); int xLedger, xNote, xStem; int drawingDur; @@ -154,7 +156,7 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l /************** dots **************/ if (note->GetDots()) { - int mensDrawingUnit = (int)(MENSUR_NOTEHEAD_FACTOR * m_doc->GetDrawingUnit(staffSize)); + int mensDrawingUnit = (int)(MNOTEHEAD_SIZE_FACTOR * m_doc->GetDrawingUnit(staffSize)); int xDot; if (note->GetDur() < DUR_2 || (note->GetDur() > DUR_8 && (note->GetDrawingStemDir() == STEMDIRECTION_up))) xDot = xStem + mensDrawingUnit*7/2; @@ -223,9 +225,9 @@ void View::DrawMensurCircle( DeviceContext *dc, int x, int yy, Staff *staff ) assert( dc ); assert( staff ); - int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MENSURSIGN_STAFFLINES_BELOW_TOP); + int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MSIGN_STAFFLINES_BELOW_TOP); int r = ToDeviceContextX( m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize )); - r = (int)(MCIRCLE_RADIUS_FACTOR*r); + r = (int)(MSIGN_CIRCLE_RADIUS_FACTOR*r); int lineWidth = (int)(m_doc->GetDrawingStaffLineWidth( staff->m_drawingStaffSize ) * 0.5); dc->SetPen( m_currentColour, lineWidth, AxSOLID ); @@ -246,9 +248,9 @@ void View::DrawMensurHalfCircle( DeviceContext *dc, int x, int yy, Staff *staff dc->SetPen( m_currentColour, m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize), AxSOLID ); dc->SetBrush( m_currentColour, AxTRANSPARENT ); - int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MENSURSIGN_STAFFLINES_BELOW_TOP); + int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MSIGN_STAFFLINES_BELOW_TOP); int r = ToDeviceContextX( m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize )); - r = (int)(MCIRCLE_RADIUS_FACTOR*r); + r = (int)(MSIGN_CIRCLE_RADIUS_FACTOR*r); x = ToDeviceContextX (x); x -= 3*r/3; @@ -292,8 +294,8 @@ void View::DrawMensurDot ( DeviceContext *dc, int x, int yy, Staff *staff ) assert( dc ); assert( staff ); - int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MENSURSIGN_STAFFLINES_BELOW_TOP); - int r = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * MENSURSIGN_DOTSIZE; + int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MSIGN_STAFFLINES_BELOW_TOP); + int r = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * MSIGN_DOTSIZE; dc->SetPen( m_currentColour, 1, AxSOLID ); dc->SetBrush( m_currentColour, AxSOLID ); @@ -355,7 +357,7 @@ void View::DrawMaximaToBrevis( DeviceContext *dc, int y, LayerElement *element, assert( note ); // Mensural noteheads are quite a bit smaller than CMN noteheads; use _pseudoStaffSize_ to force this. - int pseudoStaffSize = (int)(MENSUR_NOTEHEAD_FACTOR * staff->m_drawingStaffSize); + int pseudoStaffSize = (int)(MNOTEHEAD_SIZE_FACTOR * staff->m_drawingStaffSize); int xn, x1, x2, y1, y2, y3, y4; // int yy2, y5; // unused int verticalCenter, up, height; @@ -565,7 +567,7 @@ void View::DrawProportFigures( DeviceContext *dc, int x, int y, int num, int num assert( staff ); int ynum, yden; - int textSize = (1.0/2.0)*staff->m_drawingStaffSize; + int textSize = PROPRT_SIZE_FACTOR*staff->m_drawingStaffSize; std::wstring wtext; if (numBase) @@ -599,9 +601,9 @@ void View::DrawProportFigures( DeviceContext *dc, int x, int y, int num, int num void View::DrawProport( 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" - assert(dynamic_cast(element)); // Element must be a Mensur" + assert( layer ); + assert( staff ); + assert( dynamic_cast(element) ); // Element must be a Proport" int x1, x2, y1, y2; From 109c5af5cdbfd129603031e7430f636c63470cb3 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 10 Sep 2015 22:04:24 +0200 Subject: [PATCH 10/85] Adjusting slurs (WIP) --- include/vrv/layerelement.h | 6 ++ include/vrv/view.h | 2 + include/vrv/vrvdef.h | 4 + src/layerelement.cpp | 23 ++++- src/view_floating.cpp | 172 +++++++++++++++++++++++++++++++------ 5 files changed, 181 insertions(+), 26 deletions(-) diff --git a/include/vrv/layerelement.h b/include/vrv/layerelement.h index 89005691c1b..61a10fe66f7 100644 --- a/include/vrv/layerelement.h +++ b/include/vrv/layerelement.h @@ -91,6 +91,12 @@ class LayerElement: public DocObject * (Could one day go in a drawing stem interface) */ data_STEMDIRECTION GetDrawingStemDir(); + + /** + * Returns the drawing top and bottom taking into accound stem, etc. + */ + int GetDrawingTop(); + int GetDrawingBottom(); /** * Alignment getter diff --git a/include/vrv/view.h b/include/vrv/view.h index a9274b296da..6f8532ed0de 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -333,6 +333,8 @@ class View ///@} float AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, Point points[]); + bool AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, + bool up, float angle ); /** * @name Used for calculating clustered information/dot position diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index 5622d063e3f..2cca0b4e73d 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -23,8 +23,10 @@ namespace vrv { class AttComparison; class BeamElementCoord; +class LayerElement; class Note; class Object; +class Point; class Staff; typedef std::vector ArrayOfObjects; @@ -40,6 +42,8 @@ typedef std::vector ChordCluster; typedef std::vector ArrayOfBeamElementCoords; typedef std::map > MapOfLedgerLineFlags; + +typedef std::vector > ArrayOfLayerElementPointPairs; //---------------------------------------------------------------------------- // Object defines diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 063820b1024..24b4775433b 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -129,6 +129,25 @@ data_STEMDIRECTION LayerElement::GetDrawingStemDir() return STEMDIRECTION_NONE; } +int LayerElement::GetDrawingTop() +{ + if ((this->Is() == NOTE) || (this->Is() == CHORD)){ + if (this->GetDrawingStemDir() == STEMDIRECTION_up) return this->m_drawingStemEnd.y; + else return this->m_drawingStemStart.y; + } + return this->GetDrawingY(); +} + + +int LayerElement::GetDrawingBottom() +{ + if ((this->Is() == NOTE) || (this->Is() == CHORD)){ + if (this->GetDrawingStemDir() == STEMDIRECTION_up) return this->m_drawingStemStart.y; + else return this->m_drawingStemEnd.y; + } + return this->GetDrawingY(); +} + bool LayerElement::IsCueSize() { if ( this->Is() == NOTE ) { @@ -437,8 +456,8 @@ int LayerElement::TimeSpanningLayerElements( ArrayPtrVoid *params ) int *min_pos = static_cast((*params).at(1)); int *max_pos = static_cast((*params).at(2)); - if (this->GetDrawingX() >= (*min_pos) && this->GetDrawingX() <= (*max_pos)) { - if (this->Is() == NOTE) spanningContent->push_back(this); + if (this->GetDrawingX() > (*min_pos) && this->GetDrawingX() < (*max_pos)) { + if ((this->Is() == NOTE) || (this->Is() == CHORD)) spanningContent->push_back(this); } else if (this->GetDrawingX() > (*max_pos) ) { return FUNCTOR_STOP; diff --git a/src/view_floating.cpp b/src/view_floating.cpp index f38784467cb..634ecd9d303 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -271,6 +271,9 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff /************** adjusting y position **************/ + bool isShortSlur = false; + if (x2 - x1 < 3 * m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize)) isShortSlur = true; + int yChordMax, yChordMin; if ((spanningType == SPANNING_START_END) || (spanningType == SPANNING_START)) { // first get the min max of the chord (if any) @@ -279,14 +282,15 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff // slur is up if (up) { // P(^) - if (noteStemDir == STEMDIRECTION_down) y1 = start->GetDrawingY(); + if (noteStemDir == STEMDIRECTION_down) y1 = start->GetDrawingTop(); // d(^)d - else if ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start)) { - y1 = start->m_drawingStemEnd.y; + else if (isShortSlur || ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start))) { + y1 = start->GetDrawingTop(); } // d(^) else { - x1 += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3 / 2; + // put it on the side, move it left + x1 += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 4 / 2; if (startChord || startParentChord) y1 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; else y1 = start->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; } @@ -294,14 +298,14 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff // slur is down else { // d(_) - if (noteStemDir == STEMDIRECTION_up) y1 = start->GetDrawingY(); + if (noteStemDir == STEMDIRECTION_up) y1 = start->GetDrawingBottom(); // P(_)P - else if ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start)) { - y1 = start->m_drawingStemEnd.y; + else if (isShortSlur || ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start))) { + y1 = start->GetDrawingBottom(); } // P(_) else { - //x1 += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3 / 2; + // put it on the side, but no need to move it left y1 = start->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; if (startChord || startParentChord) y1 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; else y1 = start->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; @@ -317,27 +321,28 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff // slur is up if (up) { // (^)P - if (endStemDir == STEMDIRECTION_down) y2 = end->GetDrawingY(); + if (endStemDir == STEMDIRECTION_down) y2 = end->GetDrawingTop(); // d(^)d - else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end)) { - y2 = end->m_drawingStemEnd.y; + else if (isShortSlur || ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end))) { + y2 = end->GetDrawingTop(); } // (^)d else { - //x1 += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3 / 2; + // put it on the side, no need to move it right if (endChord || endParentChord) y2 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; else y2 = end->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; } } else { // (_)d - if (endStemDir == STEMDIRECTION_up) y2 = end->GetDrawingY(); + if (endStemDir == STEMDIRECTION_up) y2 = end->GetDrawingBottom(); // P(_)P - else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end)) { - y2 = end->m_drawingStemEnd.y; + else if (isShortSlur || ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end))) { + y2 = end->GetDrawingBottom(); } // (_)P else { + // put it on the side, move it right x2 -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; if (endChord || endParentChord) y2 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; else y2 = end->GetDrawingY() - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; @@ -345,16 +350,16 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff } } + // Positions not attached to a note if (spanningType == SPANNING_START) { if (up) y2 = std::max(staff->GetDrawingY(), y1); else y2 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y1); } - // Now this is the case when the tie is split but we are drawing the end of it else if (spanningType == SPANNING_END) { if (up) y1 = std::max(staff->GetDrawingY(), y2); else y1 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y2); } - // Finally, slur accross an entire system; use the staff position and up (see below) + // slur accross an entire system; use the staff position else if (spanningType != SPANNING_START_END) { // To be adjusted if (up) y1 = staff->GetDrawingY(); @@ -377,7 +382,9 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff points[0] = Point(x1, y1); points[1] = Point(x2, y2); - float angle = AdjustSlurPosition(slur, staff, layer1->GetN(), up, points); + float angle = 0.0; + // We do not want to ajdust the position when calculating bounding boxes (at least for now) + if (dynamic_cast(dc) == NULL) angle = AdjustSlurPosition(slur, staff, layer1->GetN(), up, points); int thickness = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * m_doc->GetSlurThickness() / DEFINITON_FACTOR ; @@ -386,7 +393,6 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff dc->DeactivateGraphic(); DrawThickBezierCurve(dc, points[0], points[1], points[2], points[3], thickness, staff->m_drawingStaffSize, angle); dc->ReactivateGraphic(); - if ( graphic ) dc->EndResumedGraphic(graphic, this); else dc->EndGraphic(slur, this); } @@ -438,17 +444,17 @@ float View::AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, P /************** rotation **************/ // control points - Point rotatecC1, rotatedC2; + Point rotatedC1, rotatedC2; int cPos = std::min((rotatedP2.x - p1->x) / TEMP_STYLE_SLUR_CONTROL_POINT_FACTOR, m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize)); - rotatecC1.x = p1->x + cPos; // point at 1/4 + rotatedC1.x = p1->x + cPos; // point at 1/4 rotatedC2.x = rotatedP2.x - cPos;; // point at 3/4 if (up) { - rotatecC1.y = p1->y + height; + rotatedC1.y = p1->y + height; rotatedC2.y = rotatedP2.y + height; } else { - rotatecC1.y = p1->y - height; + rotatedC1.y = p1->y - height; rotatedC2.y = rotatedP2.y - height; } @@ -475,9 +481,36 @@ float View::AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, P system->Process( &timeSpanningLayerElements, ¶ms, NULL, &filters ); if (spanningContent.size() > 12) LogDebug("### %d %s", spanningContent.size(), slur->GetUuid().c_str()); + LogDebug("--------" ) ; + + ArrayOfLayerElementPointPairs spanningContentPoints; + std::vector::iterator it; + for (it = spanningContent.begin(); it != spanningContent.end(); it++) + { + Note *note = NULL; + if (((*it)->Is() != NOTE) && ((*it)->Is() != CHORD)) continue; + if ((note = dynamic_cast(*it)) && note->IsChordTone()) continue; + Point p; + if (up) { + p.y = (*it)->GetDrawingTop(); + } + else { + p.y = (*it)->GetDrawingBottom(); + } + p.x = (*it)->GetDrawingX(); + p = View::CalcPositionAfterRotation(p, -slurAngle, *p1); + if (up) p.y += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; + else p.y -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; + spanningContentPoints.push_back(std::make_pair((*it), p)); + } + + bool maxHeight = false; + while (!spanningContentPoints.empty() && !maxHeight) { + maxHeight = AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle ); + } points[1] = View::CalcPositionAfterRotation(rotatedP2, slurAngle, *p1); - points[2] = View::CalcPositionAfterRotation(rotatecC1, slurAngle, *p1); + points[2] = View::CalcPositionAfterRotation(rotatedC1, slurAngle, *p1); points[3] = View::CalcPositionAfterRotation(rotatedC2, slurAngle, *p1); @@ -499,6 +532,97 @@ float View::AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, P return slurAngle; } +/* +bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle) +{ + Point bezier[4]; + bezier[0] = *p1; + bezier[1] = *c1; + bezier[2] = *c2; + bezier[3] = *p2; + + int dist = abs(p2->x - p1->x); + int maxHeight = 0; + int step = m_doc->GetDrawingUnit(100) * 4 / 3; + + float maxHeightFactor = std::max(0.2, fabs(angle)); + maxHeight = dist / (maxHeightFactor * 5); + + ArrayOfLayerElementPointPairs::iterator itPoint; + for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end();) { + if (up && (View::CalcBezierAtPosition(bezier, itPoint->second.x) > itPoint->second.y)) { + //LogDebug("Removing %d - %d", itPoint->first->GetDrawingX(), itPoint->first->GetDrawingY() ) ; + itPoint = spanningPoints->erase( itPoint ); + } + else { + //LogDebug("KEEPING %d - %d", itPoint->first->GetDrawingX(), itPoint->first->GetDrawingY() ) ; + itPoint++; + } + } + + if (abs(c1->y - p1->y) + step > maxHeight) return true; + + if (!spanningPoints->empty()) { + if (up) { + c1->y += step; + c2->y = c1->y; + } + else { + c1->y -= step; + c2->y = c1->y; + } + } + return false; +} +*/ + +bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle) +{ + Point bezier[4]; + bezier[0] = *p1; + bezier[1] = *c1; + bezier[2] = *c2; + bezier[3] = *p2; + + int dist = abs(p2->x - p1->x); + int currentHeight = abs(c1->y - p1->y); + int maxHeight = 0; + int step = m_doc->GetDrawingUnit(100) * 4 / 3; + + float maxHeightFactor = std::max(0.2, fabs(angle)); + maxHeight = dist / (maxHeightFactor * 5); + + int y; + float maxRatio = 1.0; + ArrayOfLayerElementPointPairs::iterator itPoint; + for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end(); itPoint++) { + y = View::CalcBezierAtPosition(bezier, itPoint->second.x); + if (up) { + if (y < itPoint->second.y) { + float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y); + maxRatio = ratio > maxRatio ? ratio : maxRatio; + } + } + } + + int desiredHeight = currentHeight * maxRatio; + if (desiredHeight > maxHeight) { + maxRatio = (float)maxHeight / (float)currentHeight; + } + + if (!spanningPoints->empty()) { + if (up) { + c1->y = p1->y + currentHeight * maxRatio; + c2->y = c1->y; + } + else { + c1->y = p1->y - currentHeight * maxRatio; + c2->y = c1->y; + } + } + return true; +} + void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, char spanningType, DocObject *graphic ) { From 66d7d69ab04b1f358ff4ff78351a11e3b2bafb73 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 10 Sep 2015 22:11:21 +0200 Subject: [PATCH 11/85] Fixing bug introduced in a merge - needs investigation --- src/page.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page.cpp b/src/page.cpp index 0dc47e34029..aebb1fd8e99 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -121,7 +121,7 @@ void Page::LayOutHorizontally( ) int minMeasureWidth = doc->m_drawingMinMeasureWidth; params.push_back( &previousTime ); params.push_back( &previousXRel ); - params.push_back( &minMeasureWidth ); + //params.push_back( &minMeasureWidth ); Functor setAlignmentX( &Object::SetAligmentXPos ); // Special case: because we redirect the functor, pass it a parameter to itself (!) params.push_back( &setAlignmentX ); From 8dbbdf511d0c6ce660c359f03d22b351072cd06b Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 11 Sep 2015 11:44:10 +0200 Subject: [PATCH 12/85] More adjustments --- include/vrv/layerelement.h | 5 +- include/vrv/view.h | 4 +- src/layerelement.cpp | 12 +-- src/view_floating.cpp | 156 ++++++++++++++++++++++--------------- 4 files changed, 108 insertions(+), 69 deletions(-) diff --git a/include/vrv/layerelement.h b/include/vrv/layerelement.h index 61a10fe66f7..ebab918fc29 100644 --- a/include/vrv/layerelement.h +++ b/include/vrv/layerelement.h @@ -94,9 +94,10 @@ class LayerElement: public DocObject /** * Returns the drawing top and bottom taking into accound stem, etc. + * We pass the doc as parameter in order to have access to the current drawing parameters. */ - int GetDrawingTop(); - int GetDrawingBottom(); + int GetDrawingTop(Doc* doc, int staffSize); + int GetDrawingBottom(Doc* doc, int staffSize); /** * Alignment getter diff --git a/include/vrv/view.h b/include/vrv/view.h index 6f8532ed0de..c0078ead0f9 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -332,9 +332,11 @@ class View int GetSylY( Syl* syl, Staff *staff ); ///@} - float AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, Point points[]); + float AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point points[]); bool AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle ); + bool AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, + bool up, float angle ); /** * @name Used for calculating clustered information/dot position diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 24b4775433b..2dc0c471972 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -129,20 +129,22 @@ data_STEMDIRECTION LayerElement::GetDrawingStemDir() return STEMDIRECTION_NONE; } -int LayerElement::GetDrawingTop() +int LayerElement::GetDrawingTop(Doc *doc, int staffSize) { if ((this->Is() == NOTE) || (this->Is() == CHORD)){ + // We should also take into accound the stem shift to the right if (this->GetDrawingStemDir() == STEMDIRECTION_up) return this->m_drawingStemEnd.y; - else return this->m_drawingStemStart.y; + else return this->m_drawingStemStart.y + doc->GetDrawingUnit(staffSize); } return this->GetDrawingY(); } -int LayerElement::GetDrawingBottom() +int LayerElement::GetDrawingBottom(Doc *doc, int staffSize) { if ((this->Is() == NOTE) || (this->Is() == CHORD)){ - if (this->GetDrawingStemDir() == STEMDIRECTION_up) return this->m_drawingStemStart.y; + if (this->GetDrawingStemDir() == STEMDIRECTION_up) return this->m_drawingStemStart.y - doc->GetDrawingUnit(staffSize); + // We should also take into accound the stem shift to the left else return this->m_drawingStemEnd.y; } return this->GetDrawingY(); @@ -457,7 +459,7 @@ int LayerElement::TimeSpanningLayerElements( ArrayPtrVoid *params ) int *max_pos = static_cast((*params).at(2)); if (this->GetDrawingX() > (*min_pos) && this->GetDrawingX() < (*max_pos)) { - if ((this->Is() == NOTE) || (this->Is() == CHORD)) spanningContent->push_back(this); + spanningContent->push_back(this); } else if (this->GetDrawingX() > (*max_pos) ) { return FUNCTOR_STOP; diff --git a/src/view_floating.cpp b/src/view_floating.cpp index 634ecd9d303..d0e9be85c30 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -282,33 +282,33 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff // slur is up if (up) { // P(^) - if (noteStemDir == STEMDIRECTION_down) y1 = start->GetDrawingTop(); + if (noteStemDir == STEMDIRECTION_down) y1 = start->GetDrawingTop(m_doc, staff->m_drawingStaffSize); // d(^)d else if (isShortSlur || ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start))) { - y1 = start->GetDrawingTop(); + y1 = start->GetDrawingTop(m_doc, staff->m_drawingStaffSize); } // d(^) else { // put it on the side, move it left x1 += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 4 / 2; - if (startChord || startParentChord) y1 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; - else y1 = start->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; + if (startChord || startParentChord) y1 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; + else y1 = start->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; } } // slur is down else { // d(_) - if (noteStemDir == STEMDIRECTION_up) y1 = start->GetDrawingBottom(); + if (noteStemDir == STEMDIRECTION_up) y1 = start->GetDrawingBottom(m_doc, staff->m_drawingStaffSize); // P(_)P else if (isShortSlur || ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start))) { - y1 = start->GetDrawingBottom(); + y1 = start->GetDrawingBottom(m_doc, staff->m_drawingStaffSize); } // P(_) else { // put it on the side, but no need to move it left y1 = start->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; - if (startChord || startParentChord) y1 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; - else y1 = start->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; + if (startChord || startParentChord) y1 = yChordMin - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; + else y1 = start->GetDrawingY() - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; } } } @@ -321,31 +321,31 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff // slur is up if (up) { // (^)P - if (endStemDir == STEMDIRECTION_down) y2 = end->GetDrawingTop(); + if (endStemDir == STEMDIRECTION_down) y2 = end->GetDrawingTop(m_doc, staff->m_drawingStaffSize); // d(^)d else if (isShortSlur || ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end))) { - y2 = end->GetDrawingTop(); + y2 = end->GetDrawingTop(m_doc, staff->m_drawingStaffSize); } // (^)d else { // put it on the side, no need to move it right - if (endChord || endParentChord) y2 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; - else y2 = end->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; + if (endChord || endParentChord) y2 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; + else y2 = end->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; } } else { // (_)d - if (endStemDir == STEMDIRECTION_up) y2 = end->GetDrawingBottom(); + if (endStemDir == STEMDIRECTION_up) y2 = end->GetDrawingBottom(m_doc, staff->m_drawingStaffSize); // P(_)P else if (isShortSlur || ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end))) { - y2 = end->GetDrawingBottom(); + y2 = end->GetDrawingBottom(m_doc, staff->m_drawingStaffSize); } // (_)P else { // put it on the side, move it right x2 -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; - if (endChord || endParentChord) y2 = yChordMin + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; - else y2 = end->GetDrawingY() - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; + if (endChord || endParentChord) y2 = yChordMin - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; + else y2 = end->GetDrawingY() - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; } } } @@ -370,12 +370,12 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff /************** y position **************/ if (up) { - y1 += 2 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); - y2 += 2 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + y1 += 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + y2 += 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); } else { - y1 -= 2 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); - y2 -= 2 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + y1 -= 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + y2 -= 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize); } Point points[4]; @@ -384,7 +384,7 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff float angle = 0.0; // We do not want to ajdust the position when calculating bounding boxes (at least for now) - if (dynamic_cast(dc) == NULL) angle = AdjustSlurPosition(slur, staff, layer1->GetN(), up, points); + if (dynamic_cast(dc) == NULL) angle = AdjustSlur(slur, staff, layer1->GetN(), up, points); int thickness = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * m_doc->GetSlurThickness() / DEFINITON_FACTOR ; @@ -397,7 +397,7 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff else dc->EndGraphic(slur, this); } -float View::AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, Point points[]) +float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point points[]) { // For readability makes them p1 and p2 Point *p1 = &points[0]; @@ -441,14 +441,14 @@ float View::AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, P // the height of the control points height = height * 4 / 3; - /************** rotation **************/ + /************** control points **************/ - // control points Point rotatedC1, rotatedC2; + // Set the x position of the control points int cPos = std::min((rotatedP2.x - p1->x) / TEMP_STYLE_SLUR_CONTROL_POINT_FACTOR, m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize)); - rotatedC1.x = p1->x + cPos; // point at 1/4 - rotatedC2.x = rotatedP2.x - cPos;; // point at 3/4 + rotatedC1.x = p1->x + cPos; + rotatedC2.x = rotatedP2.x - cPos; if (up) { rotatedC1.y = p1->y + height; @@ -460,7 +460,6 @@ float View::AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, P /************** content **************/ - System *system = dynamic_cast(staff->GetFirstParent(SYSTEM)); assert(system); std::vectorspanningContent; @@ -477,36 +476,38 @@ float View::AdjustSlurPosition(Slur *slur, Staff *staff, int layerN, bool up, P filters.push_back( &matchLayer ); Functor timeSpanningLayerElements( &Object::TimeSpanningLayerElements ); - //LogDebug("*** %d - %d", note1->GetDrawingX(), note2->GetDrawingX() ) ; system->Process( &timeSpanningLayerElements, ¶ms, NULL, &filters ); - if (spanningContent.size() > 12) LogDebug("### %d %s", spanningContent.size(), slur->GetUuid().c_str()); - - LogDebug("--------" ) ; + //if (spanningContent.size() > 12) LogDebug("### %d %s", spanningContent.size(), slur->GetUuid().c_str()); ArrayOfLayerElementPointPairs spanningContentPoints; std::vector::iterator it; for (it = spanningContent.begin(); it != spanningContent.end(); it++) { Note *note = NULL; + // We keep only notes and chords for now if (((*it)->Is() != NOTE) && ((*it)->Is() != CHORD)) continue; + // Also skip notes that are part of a chords since we already have the chord if ((note = dynamic_cast(*it)) && note->IsChordTone()) continue; Point p; if (up) { - p.y = (*it)->GetDrawingTop(); + p.y = (*it)->GetDrawingTop(m_doc, staff->m_drawingStaffSize); } else { - p.y = (*it)->GetDrawingBottom(); + p.y = (*it)->GetDrawingBottom(m_doc, staff->m_drawingStaffSize); } p.x = (*it)->GetDrawingX(); p = View::CalcPositionAfterRotation(p, -slurAngle, *p1); - if (up) p.y += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; - else p.y -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3; + if (up) p.y += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; + else p.y -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; spanningContentPoints.push_back(std::make_pair((*it), p)); } - bool maxHeight = false; - while (!spanningContentPoints.empty() && !maxHeight) { - maxHeight = AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle ); + bool needPositionAdjustment = false; + if (!spanningContentPoints.empty()) { + needPositionAdjustment = AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle ); + } + if (needPositionAdjustment) { + LogDebug("### %d notes for %s will need position adjustment", spanningContentPoints.size(), slur->GetUuid().c_str()); } points[1] = View::CalcPositionAfterRotation(rotatedP2, slurAngle, *p1); @@ -584,43 +585,76 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo bezier[2] = *c2; bezier[3] = *p2; + ArrayOfLayerElementPointPairs::iterator itPoint; + int y; + int dist = abs(p2->x - p1->x); int currentHeight = abs(c1->y - p1->y); int maxHeight = 0; - int step = m_doc->GetDrawingUnit(100) * 4 / 3; float maxHeightFactor = std::max(0.2, fabs(angle)); - maxHeight = dist / (maxHeightFactor * 5); - - int y; - float maxRatio = 1.0; - ArrayOfLayerElementPointPairs::iterator itPoint; - for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end(); itPoint++) { - y = View::CalcBezierAtPosition(bezier, itPoint->second.x); - if (up) { - if (y < itPoint->second.y) { - float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y); - maxRatio = ratio > maxRatio ? ratio : maxRatio; + maxHeight = dist / (maxHeightFactor * 5); // 5 is the minimum - can be increased for limiting curvature + + if (maxHeight > currentHeight) { + float maxRatio = 1.0; + float posXRatio = 1.0; + int posX; + for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end(); itPoint++) { + y = View::CalcBezierAtPosition(bezier, itPoint->second.x); + // Weight the desired height according to the x position + posXRatio = 0.0; + posX = itPoint->second.x - p1->x; + if (posX > dist / 2) posX = p2->x - itPoint->second.x; + if (dist != 0) posXRatio = (float)posX / ((float)dist / 2.0); + // Keep the maximum desired ratio + if (up) { + if (y < itPoint->second.y) { + float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y) * posXRatio; + maxRatio = ratio > maxRatio ? ratio : maxRatio; + } + } + else { + if (y > itPoint->second.y) { + float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y); + maxRatio = ratio > maxRatio ? ratio : maxRatio; + } + } + } + + int desiredHeight = currentHeight * maxRatio; + if (desiredHeight > maxHeight) { + maxRatio = (float)maxHeight / (float)currentHeight; + } + + if (maxRatio > 1.0) { + if (up) { + c1->y = p1->y + currentHeight * maxRatio; + c2->y = c1->y; + } + else { + c1->y = p1->y - currentHeight * maxRatio; + c2->y = c1->y; } } } - int desiredHeight = currentHeight * maxRatio; - if (desiredHeight > maxHeight) { - maxRatio = (float)maxHeight / (float)currentHeight; - } - - if (!spanningPoints->empty()) { + // filter the points + bezier[1] = *c1; + bezier[2] = *c2; + for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end();) { + y = View::CalcBezierAtPosition(bezier, itPoint->second.x); if (up) { - c1->y = p1->y + currentHeight * maxRatio; - c2->y = c1->y; + if (y > itPoint->second.y) itPoint = spanningPoints->erase( itPoint ); + else itPoint++; } else { - c1->y = p1->y - currentHeight * maxRatio; - c2->y = c1->y; + if (y < itPoint->second.y) itPoint = spanningPoints->erase( itPoint ); + else itPoint++; } } - return true; + + // We will need to adjust the further if the list is not empty + return (!spanningPoints->empty()); } void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, From 1cee371086301c70a5a0def8a52e02a7d124af60 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 11 Sep 2015 14:51:13 +0200 Subject: [PATCH 13/85] WIP --- include/vrv/view.h | 6 +- src/view_floating.cpp | 205 +++++++++++++++++++++++++++++++----------- 2 files changed, 156 insertions(+), 55 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index c0078ead0f9..e4587d43689 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -334,9 +334,11 @@ class View float AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point points[]); bool AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, - bool up, float angle ); + bool up, float angle, bool posRatio = true ); bool AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, - bool up, float angle ); + bool up, float *angle ); + float GetAdjustedSlurAngle(Point *p1, Point *p2, bool up); + void GetControlPoints(Point *p1, Point *p2, Point *c1, Point *c2, bool up, int height, int staffSize); /** * @name Used for calculating clustered information/dot position diff --git a/src/view_floating.cpp b/src/view_floating.cpp index d0e9be85c30..260c49dfafd 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -405,22 +405,7 @@ float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point poi /************** angle **************/ - float slurAngle = atan2(p2->y - p1->y, p2->x - p1->x); - - // the slope of the slur is high and needs to be corrected - if (fabs(slurAngle) > TEMP_STYLE_MAX_SLUR_SLOPE) { - int side = (p2->x - p1->x) * sin(TEMP_STYLE_MAX_SLUR_SLOPE) / sin(M_PI / 2 - TEMP_STYLE_MAX_SLUR_SLOPE); - if (p2->y > p1->y) { - if (up) p1->y = p2->y - side; - else p2->y = p1->y + side; - slurAngle = TEMP_STYLE_MAX_SLUR_SLOPE; - } - else { - if (up) p2->y = p1->y - side; - else p1->y = p2->y + side; - slurAngle = -TEMP_STYLE_MAX_SLUR_SLOPE; - } - } + float slurAngle = GetAdjustedSlurAngle(p1, p2, up); Point rotatedP2 = View::CalcPositionAfterRotation(*p2, -slurAngle, *p1); //LogDebug("P1 %d %d, P2 %d %d, Angle %f, Pres %d %d", x1, y1, x2, y2, slurAnge, rotadedP2.x, rotatedP2.y); @@ -444,19 +429,7 @@ float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point poi /************** control points **************/ Point rotatedC1, rotatedC2; - - // Set the x position of the control points - int cPos = std::min((rotatedP2.x - p1->x) / TEMP_STYLE_SLUR_CONTROL_POINT_FACTOR, m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize)); - rotatedC1.x = p1->x + cPos; - rotatedC2.x = rotatedP2.x - cPos; - - if (up) { - rotatedC1.y = p1->y + height; - rotatedC2.y = rotatedP2.y + height; - } else { - rotatedC1.y = p1->y - height; - rotatedC2.y = rotatedP2.y - height; - } + GetControlPoints(p1, &rotatedP2, &rotatedC1, &rotatedC2, up, height, staff->m_drawingStaffSize); /************** content **************/ @@ -502,37 +475,75 @@ float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point poi spanningContentPoints.push_back(std::make_pair((*it), p)); } + // We need to keep the original control points + Point adjustedRotatedC1 = rotatedC1; + Point adjustedRotatedC2 = rotatedC2; + bool needPositionAdjustment = false; if (!spanningContentPoints.empty()) { - needPositionAdjustment = AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle ); + needPositionAdjustment = AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, slurAngle ); } if (needPositionAdjustment) { - LogDebug("### %d notes for %s will need position adjustment", spanningContentPoints.size(), slur->GetUuid().c_str()); + // Use the adjusted control points for ajusting the position (p1, p2 and angle will be updated) + AdjustSlurPosition(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, &slurAngle ); + // Now readjust the curvature with the new p1 and p2 with the original control points + GetControlPoints(p1, &rotatedP2, &rotatedC1, &rotatedC2, up, height, staff->m_drawingStaffSize); + AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle, false ); + if (!spanningContentPoints.empty()) { + // Something went wrong since now all spanning points should be gone... + LogDebug("### %d notes for %s will need position adjustment", spanningContentPoints.size(), slur->GetUuid().c_str()); + } + } + else { + rotatedC1 = adjustedRotatedC1; + rotatedC2 = adjustedRotatedC2; } points[1] = View::CalcPositionAfterRotation(rotatedP2, slurAngle, *p1); points[2] = View::CalcPositionAfterRotation(rotatedC1, slurAngle, *p1); points[3] = View::CalcPositionAfterRotation(rotatedC2, slurAngle, *p1); + return slurAngle; +} - /* - Point bezier[4]; - bezier[0].x = 100; - bezier[1].x = 200; - bezier[2].x = 300; - bezier[3].x = 400; - bezier[0].y = 000; - bezier[1].y = 100; - bezier[2].y = 100; - bezier[3].y = 000; - - int p = View::CalcBezierAtPosition(bezier, 24550); - p; - */ +float View::GetAdjustedSlurAngle(Point *p1, Point *p2, bool up) +{ + float slurAngle = atan2(p2->y - p1->y, p2->x - p1->x); + + // the slope of the slur is high and needs to be corrected + if (fabs(slurAngle) > TEMP_STYLE_MAX_SLUR_SLOPE) { + int side = (p2->x - p1->x) * sin(TEMP_STYLE_MAX_SLUR_SLOPE) / sin(M_PI / 2 - TEMP_STYLE_MAX_SLUR_SLOPE); + if (p2->y > p1->y) { + if (up) p1->y = p2->y - side; + else p2->y = p1->y + side; + slurAngle = TEMP_STYLE_MAX_SLUR_SLOPE; + } + else { + if (up) p2->y = p1->y - side; + else p1->y = p2->y + side; + slurAngle = -TEMP_STYLE_MAX_SLUR_SLOPE; + } + } return slurAngle; } +void View::GetControlPoints(Point *p1, Point *p2, Point *c1, Point *c2, bool up, int height, int staffSize) +{ + // Set the x position of the control points + int cPos = std::min((p2->x - p1->x) / TEMP_STYLE_SLUR_CONTROL_POINT_FACTOR, m_doc->GetDrawingStaffSize(staffSize)); + c1->x = p1->x + cPos; + c2->x = p2->x - cPos; + + if (up) { + c1->y = p1->y + height; + c2->y = p2->y + height; + } else { + c1->y = p1->y - height; + c2->y = p2->y - height; + } +} + /* bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle) { @@ -577,7 +588,7 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo } */ -bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle) +bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle, bool posRatio) { Point bezier[4]; bezier[0] = *p1; @@ -599,24 +610,36 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo float maxRatio = 1.0; float posXRatio = 1.0; int posX; - for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end(); itPoint++) { + for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end();) { y = View::CalcBezierAtPosition(bezier, itPoint->second.x); - // Weight the desired height according to the x position - posXRatio = 0.0; - posX = itPoint->second.x - p1->x; - if (posX > dist / 2) posX = p2->x - itPoint->second.x; - if (dist != 0) posXRatio = (float)posX / ((float)dist / 2.0); + + // Weight the desired height according to the x position if wanted + posXRatio = 1.0; + if (posRatio && (dist != 0)) { + posX = itPoint->second.x - p1->x; + if (posX > dist / 2) posX = p2->x - itPoint->second.x; + if (dist != 0) posXRatio = (float)posX / ((float)dist / 2.0); + } + // Keep the maximum desired ratio if (up) { if (y < itPoint->second.y) { float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y) * posXRatio; maxRatio = ratio > maxRatio ? ratio : maxRatio; + itPoint++; + } + else { + itPoint = spanningPoints->erase(itPoint); } } - else { + else { if (y > itPoint->second.y) { float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y); maxRatio = ratio > maxRatio ? ratio : maxRatio; + itPoint++; + } + else { + itPoint = spanningPoints->erase(itPoint); } } } @@ -657,6 +680,82 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo return (!spanningPoints->empty()); } +bool View::AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float *angle) +{ + Point bezier[4]; + bezier[0] = *p1; + bezier[1] = *c1; + bezier[2] = *c2; + bezier[3] = *p2; + + int maxShiftLeft = 0; + int maxShiftRight = 0; + int shift, leftShift, rightShift; + + int dist = abs(p2->x - p1->x); + float posXRatio = 1.0; + int posX; + + ArrayOfLayerElementPointPairs::iterator itPoint; + int y; + + for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end();) { + y = View::CalcBezierAtPosition(bezier, itPoint->second.x); + + // Weight the desired height according to the x position on the other side + posXRatio = 1.0; + bool leftPoint = true; + posX = itPoint->second.x - p1->x; + if (posX > dist / 2) { + posX = p2->x - itPoint->second.x; + leftPoint = false; + } + if (dist != 0) posXRatio = (float)posX / ((float)dist / 2.0); + + // Keep the maximum shift on the left and right + if (up) { + if (y < itPoint->second.y) { + shift = (itPoint->second.y - p1->y) - (y - p1->y); + } + } + else { + if (y > itPoint->second.y) { + shift = (p1->y - itPoint->second.y) - (p1->y - y); + } + } + if (shift > 0) { + leftShift = leftPoint ? shift : shift * posXRatio; + rightShift = !leftPoint ? shift : shift * posXRatio; + maxShiftLeft = leftShift > maxShiftLeft ? leftShift : maxShiftLeft; + maxShiftRight = rightShift > maxShiftRight ? rightShift : maxShiftRight; + itPoint++; + } + else { + itPoint = spanningPoints->erase(itPoint); + } + } + + // Actually nothing to do + if (spanningPoints->empty()) return true; + + // Unrotated the slur + *p2 = View::CalcPositionAfterRotation(*p2, (*angle), *p1); + + if (up) { + p1->y += maxShiftLeft; + p2->y += maxShiftRight; + } + else { + p1->y -= maxShiftLeft; + p2->y -= maxShiftRight; + } + + *angle = GetAdjustedSlurAngle(p1, p2, up); + *p2 = View::CalcPositionAfterRotation(*p2, -(*angle), *p1); + + return false; +} + void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, char spanningType, DocObject *graphic ) { From 2f80b5a1daeee179c7b9697a990bb432158a38a4 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 11 Sep 2015 22:38:03 +0200 Subject: [PATCH 14/85] Fixing bug with grace notes at the beginning of a measure --- src/aligner.cpp | 7 +++++-- src/measure.cpp | 5 +++-- src/object.cpp | 2 +- src/page.cpp | 1 + 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/aligner.cpp b/src/aligner.cpp index 3b3f941de58..db90c92d1e9 100644 --- a/src/aligner.cpp +++ b/src/aligner.cpp @@ -15,6 +15,7 @@ //---------------------------------------------------------------------------- +#include "doc.h" #include "note.h" #include "style.h" #include "vrv.h" @@ -352,13 +353,15 @@ int MeasureAligner::IntegrateBoundingBoxXShift( ArrayPtrVoid *params ) // param 0: the accumulated shift // param 1: the accumulated justifiable shift // param 2: the minimum measure with (unused) - // param 3: the functor to be redirected to the MeasureAligner (unused) + // param 3: the doc for accessing drawing parameters + // param 4: the functor to be redirected to the MeasureAligner (unused) int *shift = static_cast((*params).at(0)); int *justifiable_shift = static_cast((*params).at(1)); + Doc *doc = static_cast((*params).at(3)); // We start a new MeasureAligner // Reset the accumulated shift to 0; - (*shift) = 0; + (*shift) = doc->GetLeftPosition() * doc->GetDrawingUnit(100) / PARAM_DENOMINATOR;; (*justifiable_shift) = -1; return FUNCTOR_CONTINUE; diff --git a/src/measure.cpp b/src/measure.cpp index adfd8281ab4..bf2df13f51c 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -203,8 +203,9 @@ int Measure::IntegrateBoundingBoxXShift( ArrayPtrVoid *params ) // param 0: the cumulated shift (unused) // param 1: the cumulated justifiable shift (unused) // param 2: the minimum measure with (unused) - // param 3: the functor to be redirected to Aligner - Functor *integrateBoundingBoxShift = static_cast((*params).at(3)); + // param 3: the doc for accessing drawing parameters (unused) + // param 4: the functor to be redirected to Aligner + Functor *integrateBoundingBoxShift = static_cast((*params).at(4)); m_measureAligner.Process( integrateBoundingBoxShift, params ); diff --git a/src/object.cpp b/src/object.cpp index eb336829dd1..7d7f69ee61d 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -1128,7 +1128,7 @@ int Object::SetBoundingBoxXShift( ArrayPtrVoid *params ) if (this->Is() == LAYER) { Layer *current_layer = dynamic_cast(this); assert( current_layer ); - (*min_pos) = doc->GetLeftPosition() * doc->GetDrawingUnit(100) / PARAM_DENOMINATOR; + (*min_pos) = 0; // set scoreDef attr if (current_layer->GetDrawingClef()) { current_layer->GetDrawingClef()->SetBoundingBoxXShift( params ); diff --git a/src/page.cpp b/src/page.cpp index b66c94cc6c9..1a41a275823 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -170,6 +170,7 @@ void Page::LayOutHorizontally( ) params.push_back( &shift ); params.push_back( &justifiable_shift ); params.push_back( &minMeasureWidth ); + params.push_back( doc ); Functor integrateBoundingBoxXShift( &Object::IntegrateBoundingBoxXShift ); // special case: because we redirect the functor, pass is a parameter to itself (!) params.push_back( &integrateBoundingBoxXShift ); From 7aeff991434f35a5234f76480ccbcc2e94b05959 Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Sun, 13 Sep 2015 11:20:10 -0400 Subject: [PATCH 15/85] Remove the _fixedSpacing_ parameter to HorizontalSpaceForDuration(); it's no longer needed. --- include/vrv/aligner.h | 2 +- src/aligner.cpp | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/vrv/aligner.h b/include/vrv/aligner.h index 8ff753aa9da..e446ad4b719 100644 --- a/include/vrv/aligner.h +++ b/include/vrv/aligner.h @@ -226,7 +226,7 @@ class Alignment: public Object virtual int IntegrateBoundingBoxXShift( ArrayPtrVoid *params ); - virtual int HorizontalSpaceForDuration(double intervalTime, bool isMensural); + virtual int HorizontalSpaceForDuration(double intervalTime); /** * Set the position of the Alignment. diff --git a/src/aligner.cpp b/src/aligner.cpp index 4ab9cb289e5..f3e4228f6e6 100644 --- a/src/aligner.cpp +++ b/src/aligner.cpp @@ -449,17 +449,16 @@ int MeasureAligner::SetAligmentXPos( ArrayPtrVoid *params ) /* Compute "ideal" horizontal space to allow for a given time interval, ignoring the need to keep consecutive symbols from overlapping or nearly overlapping: we assume spacing will be increased as necessary later to avoid that. For modern notation (CMN), ideal space -is a function of time interval. For mensural notation, we'd want ideal spacing to be zero -so as to end up with spacing as tight as possible. +is a function of time interval. -This function needs more flexibility: for example, for some purposes, spacing propoortional -to duration is desirable. The best solution is probably to get ideal spacing from a user- -definable table. */ -int Alignment::HorizontalSpaceForDuration(double intervalTime, bool evenSpacing) +??The power function we currently use is all wrong; see _Behind Bars_, p. 39. We also need more +flexibility: for example, for some purposes, spacing propoortional to duration is desirable. +The best solution is probably to get ideal spacing from a user-definable table. */ + +int Alignment::HorizontalSpaceForDuration(double intervalTime) { - int intervalXRel = 0; - if (!evenSpacing) - intervalXRel = pow( intervalTime, 0.60 ) * 2.5; // 2.5 is an arbitrary value; so is 0.60 + int intervalXRel; + intervalXRel = pow( intervalTime, 0.60 ) * 2.5; // 2.5 is an arbitrary value; so is 0.60 return intervalXRel; } @@ -474,7 +473,7 @@ int Alignment::SetAligmentXPos( ArrayPtrVoid *params ) int intervalXRel = 0; double intervalTime = (m_time - (*previousTime)); // HARDCODED parameter for HorizontalSpaceForDuration - if ( intervalTime > 0.0 ) intervalXRel = HorizontalSpaceForDuration(intervalTime, false); + if ( intervalTime > 0.0 ) intervalXRel = HorizontalSpaceForDuration(intervalTime); m_xRel = (*previousXRel) + (intervalXRel) * DEFINITON_FACTOR; (*previousTime) = m_time; From 8bd0755fb08ba0b291d9c25750df18c6c1e050bc Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Sun, 13 Sep 2015 11:23:00 -0400 Subject: [PATCH 16/85] Rename & rewrite comments on some #define's for clarity; change values of #define's for size of noteheads & for size & position of mensuration signs. --- src/view_mensural.cpp | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index 269ba384827..4be08c3b532 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -29,15 +29,13 @@ namespace vrv { /* ??THESE #defines PROBABLY BELONG IN style.h . */ /* Set ratio of mensural notehead size to CMN notehead size for the same staff size */ -#define MNOTEHEAD_SIZE_FACTOR 0.60 -/* Set size of mensuration sign circle relative to space between staff lines. (In early manuscripts, -the entire mensuration sign fits easily between two staff lines, so the radius is considerably less -than half the distance between them.) */ -#define MSIGN_CIRCLE_RADIUS_FACTOR 0.32 +#define MNOTEHEAD_SIZE_FACTOR 0.90 +/* Set size of mensuration sign circle relative to space between staff lines */ +#define MSIGN_CIRCLE_DIAM 1.7 /* Set vertical position of center of mensuration sign as distance below top of the staff */ -#define MSIGN_STAFFLINES_BELOW_TOP 1.5 -/* Set size rel. to dist. between staff lines of dot inside mensuration signs */ -#define MSIGN_DOTSIZE 0.15 +#define MSIGN_STAFFLINES_BELOW_TOP 2.0 +/* Set size of dot inside mensuration signs relative to space between staff lines */ +#define MSIGN_DOT_DIAM 0.5 /* Set relative size of figures in proportions */ #define PROPRT_SIZE_FACTOR 0.50 @@ -227,9 +225,10 @@ void View::DrawMensurCircle( DeviceContext *dc, int x, int yy, Staff *staff ) int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MSIGN_STAFFLINES_BELOW_TOP); int r = ToDeviceContextX( m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize )); - r = (int)(MSIGN_CIRCLE_RADIUS_FACTOR*r); + r = (int)(MSIGN_CIRCLE_DIAM/2.0*r); - int lineWidth = (int)(m_doc->GetDrawingStaffLineWidth( staff->m_drawingStaffSize ) * 0.5); + int lineWidth = m_doc->GetDrawingStaffLineWidth( staff->m_drawingStaffSize ); + lineWidth = lineWidth * 1.0; dc->SetPen( m_currentColour, lineWidth, AxSOLID ); dc->SetPen( m_currentColour, m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize), AxSOLID ); dc->SetBrush( m_currentColour, AxTRANSPARENT ); @@ -248,16 +247,16 @@ void View::DrawMensurHalfCircle( DeviceContext *dc, int x, int yy, Staff *staff dc->SetPen( m_currentColour, m_doc->GetDrawingStaffLineWidth(staff->m_drawingStaffSize), AxSOLID ); dc->SetBrush( m_currentColour, AxTRANSPARENT ); - int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MSIGN_STAFFLINES_BELOW_TOP); + /* DrawEllipticArc expects x and y to specify the coordinates of the upper-left corner of the + rectangle that contains the ellipse; y is not the center of the circle it's an arc of. */ + double halfDistBelowTop = MSIGN_STAFFLINES_BELOW_TOP - (MSIGN_CIRCLE_DIAM/2.0); + int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * halfDistBelowTop); int r = ToDeviceContextX( m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize )); - r = (int)(MSIGN_CIRCLE_RADIUS_FACTOR*r); + r = (int)(MSIGN_CIRCLE_DIAM/2.0*r); x = ToDeviceContextX (x); x -= 3*r/3; - /* DrawEllipticArc expects x and y to specify the coordinates of the upper-left corner of the - rectangle that contains the ellipse; y is not the center of the circle it's an arc of. */ - y -= staff->m_drawingStaffSize / 2; dc->DrawEllipticArc( x, y, 2*r, 2*r, 45, 315 ); dc->ResetPen(); @@ -295,7 +294,7 @@ void View::DrawMensurDot ( DeviceContext *dc, int x, int yy, Staff *staff ) assert( staff ); int y = ToDeviceContextY (yy - m_doc->GetDrawingDoubleUnit( staff->m_drawingStaffSize ) * MSIGN_STAFFLINES_BELOW_TOP); - int r = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * MSIGN_DOTSIZE; + int r = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * MSIGN_DOT_DIAM; dc->SetPen( m_currentColour, 1, AxSOLID ); dc->SetBrush( m_currentColour, AxSOLID ); @@ -590,7 +589,7 @@ void View::DrawProportFigures( DeviceContext *dc, int x, int y, int num, int num if (numBase) { wtext = IntToTimeSigFigures(numBase); - DrawSmuflString ( dc, x, yden, wtext, true, textSize); // '1' = center + DrawSmuflString ( dc, x, yden, wtext, true, textSize); // true = center } dc->ResetFont(); From f12be9518b9563760fbb9458bfeddc1eeca53f56 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Mon, 14 Sep 2015 17:07:17 +0200 Subject: [PATCH 17/85] More adjustments --- include/vrv/view.h | 1 + src/view_floating.cpp | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index e4587d43689..cdf0610e81b 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -339,6 +339,7 @@ class View bool up, float *angle ); float GetAdjustedSlurAngle(Point *p1, Point *p2, bool up); void GetControlPoints(Point *p1, Point *p2, Point *c1, Point *c2, bool up, int height, int staffSize); + void GetSpanningPointPositions( ArrayOfLayerElementPointPairs *spanningPoints, Point p1, float angle, bool up, int staffSize); /** * @name Used for calculating clustered information/dot position diff --git a/src/view_floating.cpp b/src/view_floating.cpp index 260c49dfafd..81c72405f82 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -396,6 +396,7 @@ void View::DrawSlur( DeviceContext *dc, Slur *slur, int x1, int x2, Staff *staff if ( graphic ) dc->EndResumedGraphic(graphic, this); else dc->EndGraphic(slur, this); } + float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point points[]) { @@ -462,19 +463,11 @@ float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point poi // Also skip notes that are part of a chords since we already have the chord if ((note = dynamic_cast(*it)) && note->IsChordTone()) continue; Point p; - if (up) { - p.y = (*it)->GetDrawingTop(m_doc, staff->m_drawingStaffSize); - } - else { - p.y = (*it)->GetDrawingBottom(m_doc, staff->m_drawingStaffSize); - } - p.x = (*it)->GetDrawingX(); - p = View::CalcPositionAfterRotation(p, -slurAngle, *p1); - if (up) p.y += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; - else p.y -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; spanningContentPoints.push_back(std::make_pair((*it), p)); } + GetSpanningPointPositions( &spanningContentPoints, *p1, slurAngle, up, staff->m_drawingStaffSize); + // We need to keep the original control points Point adjustedRotatedC1 = rotatedC1; Point adjustedRotatedC2 = rotatedC2; @@ -488,6 +481,7 @@ float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point poi AdjustSlurPosition(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, &slurAngle ); // Now readjust the curvature with the new p1 and p2 with the original control points GetControlPoints(p1, &rotatedP2, &rotatedC1, &rotatedC2, up, height, staff->m_drawingStaffSize); + GetSpanningPointPositions( &spanningContentPoints, *p1, slurAngle, up, staff->m_drawingStaffSize); AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle, false ); if (!spanningContentPoints.empty()) { // Something went wrong since now all spanning points should be gone... @@ -544,6 +538,26 @@ void View::GetControlPoints(Point *p1, Point *p2, Point *c1, Point *c2, bool up, } } + + +void View::GetSpanningPointPositions( ArrayOfLayerElementPointPairs *spanningPoints, Point p1, float angle, bool up, int staffSize) +{ + ArrayOfLayerElementPointPairs::iterator itPoint; + for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end(); itPoint++) { + Point p; + if (up) { + p.y = itPoint->first->GetDrawingTop(m_doc, staffSize); + } + else { + p.y = itPoint->first->GetDrawingBottom(m_doc, staffSize); + } + p.x = itPoint->first->GetDrawingX(); + itPoint->second = View::CalcPositionAfterRotation(p, -angle, p1); + if (up) itPoint->second.y += m_doc->GetDrawingUnit(staffSize) * 3; + else itPoint->second.y -= m_doc->GetDrawingUnit(staffSize) * 3; + } +} + /* bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle) { @@ -604,7 +618,10 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo int maxHeight = 0; float maxHeightFactor = std::max(0.2, fabs(angle)); - maxHeight = dist / (maxHeightFactor * 5); // 5 is the minimum - can be increased for limiting curvature + maxHeight = dist / (maxHeightFactor * 15); // 5 is the minimum - can be increased for limiting curvature + if (posRatio) { + //maxHeight = std::min( maxHeight, m_doc->GetDrawingStaffSize(100) ); + } if (maxHeight > currentHeight) { float maxRatio = 1.0; @@ -712,6 +729,7 @@ bool View::AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spannin } if (dist != 0) posXRatio = (float)posX / ((float)dist / 2.0); + shift = 0; // Keep the maximum shift on the left and right if (up) { if (y < itPoint->second.y) { From e72bc2a4861db9e853d3ca3250c3d459a44d2a78 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 15 Sep 2015 09:55:29 +0200 Subject: [PATCH 18/85] Adjusting position of slurs --- include/vrv/style.h | 3 +- include/vrv/view.h | 4 +++ src/view_floating.cpp | 69 +++++++++++-------------------------------- 3 files changed, 23 insertions(+), 53 deletions(-) diff --git a/include/vrv/style.h b/include/vrv/style.h index 842d0e190b0..0b8db8b54cd 100644 --- a/include/vrv/style.h +++ b/include/vrv/style.h @@ -137,7 +137,8 @@ namespace vrv { #define TEMP_STYLE_LYIRC_LINE_SPACE 5.0 * PARAM_DENOMINATOR // the maximum angle of a slur -#define TEMP_STYLE_MAX_SLUR_SLOPE (45 * M_PI / 180) +#define TEMP_STYLE_SLUR_MAX_SLOPE (45 * M_PI / 180) +#define TEMP_STYLE_SLUR_CURVE_FACTOR 10 // a factor for allow more (0) or less (100) curved slurs #define TEMP_STYLE_SLUR_HEIGHT_FACTOR 8 // high value means flatter slurs #define TEMP_STYLE_SLUR_CONTROL_POINT_FACTOR 5 // higher value means more curved at the end diff --git a/include/vrv/view.h b/include/vrv/view.h index cdf0610e81b..0566a0df5a9 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -332,6 +332,9 @@ class View int GetSylY( Syl* syl, Staff *staff ); ///@} + /** + * @name Internal methods used for calculating slurs + */ float AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point points[]); bool AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle, bool posRatio = true ); @@ -340,6 +343,7 @@ class View float GetAdjustedSlurAngle(Point *p1, Point *p2, bool up); void GetControlPoints(Point *p1, Point *p2, Point *c1, Point *c2, bool up, int height, int staffSize); void GetSpanningPointPositions( ArrayOfLayerElementPointPairs *spanningPoints, Point p1, float angle, bool up, int staffSize); + ///@} /** * @name Used for calculating clustered information/dot position diff --git a/src/view_floating.cpp b/src/view_floating.cpp index 81c72405f82..8bbfad8a0ce 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -505,17 +505,17 @@ float View::GetAdjustedSlurAngle(Point *p1, Point *p2, bool up) float slurAngle = atan2(p2->y - p1->y, p2->x - p1->x); // the slope of the slur is high and needs to be corrected - if (fabs(slurAngle) > TEMP_STYLE_MAX_SLUR_SLOPE) { - int side = (p2->x - p1->x) * sin(TEMP_STYLE_MAX_SLUR_SLOPE) / sin(M_PI / 2 - TEMP_STYLE_MAX_SLUR_SLOPE); + if (fabs(slurAngle) > TEMP_STYLE_SLUR_MAX_SLOPE) { + int side = (p2->x - p1->x) * sin(TEMP_STYLE_SLUR_MAX_SLOPE) / sin(M_PI / 2 - TEMP_STYLE_SLUR_MAX_SLOPE); if (p2->y > p1->y) { if (up) p1->y = p2->y - side; else p2->y = p1->y + side; - slurAngle = TEMP_STYLE_MAX_SLUR_SLOPE; + slurAngle = TEMP_STYLE_SLUR_MAX_SLOPE; } else { if (up) p2->y = p1->y - side; else p1->y = p2->y + side; - slurAngle = -TEMP_STYLE_MAX_SLUR_SLOPE; + slurAngle = -TEMP_STYLE_SLUR_MAX_SLOPE; } } @@ -552,56 +552,16 @@ void View::GetSpanningPointPositions( ArrayOfLayerElementPointPairs *spanningPoi p.y = itPoint->first->GetDrawingBottom(m_doc, staffSize); } p.x = itPoint->first->GetDrawingX(); + // Not sure if it is better to add the margin before or after the rotation... + if (up) p.y += m_doc->GetDrawingUnit(staffSize) * 3; + else p.y -= m_doc->GetDrawingUnit(staffSize) * 3; itPoint->second = View::CalcPositionAfterRotation(p, -angle, p1); - if (up) itPoint->second.y += m_doc->GetDrawingUnit(staffSize) * 3; - else itPoint->second.y -= m_doc->GetDrawingUnit(staffSize) * 3; + // This would add it after + //if (up) itPoint->second.y += m_doc->GetDrawingUnit(staffSize) * 3; + //else itPoint->second.y -= m_doc->GetDrawingUnit(staffSize) * 3; } } -/* -bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle) -{ - Point bezier[4]; - bezier[0] = *p1; - bezier[1] = *c1; - bezier[2] = *c2; - bezier[3] = *p2; - - int dist = abs(p2->x - p1->x); - int maxHeight = 0; - int step = m_doc->GetDrawingUnit(100) * 4 / 3; - - float maxHeightFactor = std::max(0.2, fabs(angle)); - maxHeight = dist / (maxHeightFactor * 5); - - ArrayOfLayerElementPointPairs::iterator itPoint; - for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end();) { - if (up && (View::CalcBezierAtPosition(bezier, itPoint->second.x) > itPoint->second.y)) { - //LogDebug("Removing %d - %d", itPoint->first->GetDrawingX(), itPoint->first->GetDrawingY() ) ; - itPoint = spanningPoints->erase( itPoint ); - } - else { - //LogDebug("KEEPING %d - %d", itPoint->first->GetDrawingX(), itPoint->first->GetDrawingY() ) ; - itPoint++; - } - } - - if (abs(c1->y - p1->y) + step > maxHeight) return true; - - if (!spanningPoints->empty()) { - if (up) { - c1->y += step; - c2->y = c1->y; - } - else { - c1->y -= step; - c2->y = c1->y; - } - } - return false; -} -*/ - bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle, bool posRatio) { Point bezier[4]; @@ -617,9 +577,11 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo int currentHeight = abs(c1->y - p1->y); int maxHeight = 0; + // 0.2 for avoiding / by 0 (below) float maxHeightFactor = std::max(0.2, fabs(angle)); - maxHeight = dist / (maxHeightFactor * 15); // 5 is the minimum - can be increased for limiting curvature + maxHeight = dist / (maxHeightFactor * (TEMP_STYLE_SLUR_CURVE_FACTOR + 5)); // 5 is the minimum - can be increased for limiting curvature if (posRatio) { + // Do we want to set a max height? //maxHeight = std::min( maxHeight, m_doc->GetDrawingStaffSize(100) ); } @@ -645,6 +607,7 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo maxRatio = ratio > maxRatio ? ratio : maxRatio; itPoint++; } + // The point is below, we can drop it else { itPoint = spanningPoints->erase(itPoint); } @@ -655,12 +618,14 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo maxRatio = ratio > maxRatio ? ratio : maxRatio; itPoint++; } + // the point is above, we can drop it else { itPoint = spanningPoints->erase(itPoint); } } } + // We should not adjust it more than the maximum height int desiredHeight = currentHeight * maxRatio; if (desiredHeight > maxHeight) { maxRatio = (float)maxHeight / (float)currentHeight; @@ -678,7 +643,7 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo } } - // filter the points + // filter the points with the adjusted curve bezier[1] = *c1; bezier[2] = *c2; for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end();) { From 1b693d4bf8452e18af2b31c7ddfba6118ca7babe Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 15 Sep 2015 10:03:24 +0200 Subject: [PATCH 19/85] Adding storing of scoreDef width for improving justification (WIP) --- include/vrv/scoredef.h | 10 ++++++ include/vrv/style.h | 3 ++ include/vrv/system.h | 8 +++-- include/vrv/view.h | 6 ++++ src/doc.cpp | 2 +- src/scoredef.cpp | 6 ++++ src/system.cpp | 12 +++++++- src/view_element.cpp | 2 +- src/view_page.cpp | 69 +++++++++++++++++++++++++++++++++++++----- 9 files changed, 105 insertions(+), 13 deletions(-) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index c2c6533213c..673be52ae4d 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -157,6 +157,14 @@ class ScoreDef: public ScoreDefElement, public ObjectListInterface void SetDrawLabels( bool drawLabels ) { m_drawLabels = drawLabels; }; ///@} + /** + * @name Set and get the scoreDef drawing width. + */ + ///@{ + bool GetDrawingWidth() const { return m_drawingWidth; }; + void SetDrawingWidth( int drawingWidth ); + ///@} + //----------// // Functors // //----------// @@ -182,6 +190,8 @@ class ScoreDef: public ScoreDefElement, public ObjectListInterface private: /** Flags for indicating whether lables needs to be drawn or not */ bool m_drawLabels; + /** Store the drawing width (clef and key sig) of the scoreDef */ + int m_drawingWidth; }; diff --git a/include/vrv/style.h b/include/vrv/style.h index 842d0e190b0..4532e7370af 100644 --- a/include/vrv/style.h +++ b/include/vrv/style.h @@ -136,6 +136,9 @@ namespace vrv { // the space between each lyric line in units #define TEMP_STYLE_LYIRC_LINE_SPACE 5.0 * PARAM_DENOMINATOR +// the key signature spacing factor +#define TEMP_STYLE_KEYSIG_STEP 1.3 + // the maximum angle of a slur #define TEMP_STYLE_MAX_SLUR_SLOPE (45 * M_PI / 180) #define TEMP_STYLE_SLUR_HEIGHT_FACTOR 8 // high value means flatter slurs diff --git a/include/vrv/system.h b/include/vrv/system.h index 568dc5bdcfa..8755b495581 100644 --- a/include/vrv/system.h +++ b/include/vrv/system.h @@ -61,11 +61,13 @@ class System: public DocObject, public DrawingListInterface ///@} /** - * @name Set and get the labels drawing width. + * @name Set and get the labels drawing width (normal and abbreviated) */ ///@{ int GetDrawingLabelsWidth() const { return m_drawingLabelsWidth; }; void SetDrawingLabelsWidth( int width ); + int GetDrawingAbbrLabelsWidth() const { return m_drawingAbbrLabelsWidth; }; + void SetDrawingAbbrLabelsWidth( int width ); ///@} /** @@ -157,7 +159,7 @@ class System: public DocObject, public DrawingListInterface int m_systemLeftMar; /** System right margin (MEI scoredef@system.rightmar). Saved if != 0 */ int m_systemRightMar; - /** + /** * The Y absolute position of the staff for facsimile (transcription) encodings. * This is the top left corner of the system. */ @@ -182,6 +184,8 @@ class System: public DocObject, public DrawingListInterface * It is used internally when calculating the layout andd it is not stored in the file. */ int m_drawingLabelsWidth; + /** The width used by the abbreviated labels */ + int m_drawingAbbrLabelsWidth; /** * @name The total width of the system. * It is computed during the layout processed and used for calculating the justification ratio. diff --git a/include/vrv/view.h b/include/vrv/view.h index c0078ead0f9..8ff476ac295 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -319,6 +319,12 @@ class View void DrawDot ( DeviceContext *dc, int x, int y, int staffSize ); ///@} + /** + * Calculate the ScoreDef width by taking into account its widest key signature + * This is used in justifiation for anticipating the width of initial scoreDefs that are not drawn in the un-casted system + */ + void SetScoreDefDrawingWidth(DeviceContext *dc, ScoreDef *scoreDef); + private: /** * @name Internal methods used for calculating tuplets diff --git a/src/doc.cpp b/src/doc.cpp index 45a3b999f9c..77aee9896dc 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -343,7 +343,7 @@ void Doc::CastOff( ) System *currentSystem = new System(); contentPage->AddSystem( currentSystem ); - int shift = 0; + int shift = -contentSystem->GetDrawingLabelsWidth(); int systemFullWidth = this->m_drawingPageWidth - this->m_drawingPageLeftMar - this->m_drawingPageRightMar - currentSystem->m_systemLeftMar - currentSystem->m_systemRightMar; ArrayPtrVoid params; diff --git a/src/scoredef.cpp b/src/scoredef.cpp index aa2ddf25914..10334032529 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -196,6 +196,7 @@ void ScoreDef::Reset() { ScoreDefElement::Reset(); m_drawLabels = false; + m_drawingWidth = 0; } void ScoreDef::AddStaffGrp( StaffGrp *staffGrp ) @@ -337,6 +338,11 @@ void ScoreDef::SetRedrawFlags( bool clef, bool keySig, bool mensur, bool meterSi Functor setStaffDefDraw( &Object::SetStaffDefRedrawFlags ); this->Process( &setStaffDefDraw, ¶ms ); } + +void ScoreDef::SetDrawingWidth(int drawingWidth) +{ + m_drawingWidth = drawingWidth; +} //---------------------------------------------------------------------------- // StaffGrp diff --git a/src/system.cpp b/src/system.cpp index 399b520405e..00b9958d9a9 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -52,6 +52,8 @@ void System::Reset() m_drawingYRel = 0; m_drawingY = 0; m_drawingTotalWidth = 0; + m_drawingLabelsWidth = 0; + m_drawingAbbrLabelsWidth = 0; } void System::AddMeasure( Measure *measure ) @@ -78,6 +80,7 @@ void System::ResetHorizontalAlignment() m_drawingXRel = 0; m_drawingX = 0; m_drawingLabelsWidth = 0; + m_drawingAbbrLabelsWidth = 0; } @@ -101,7 +104,14 @@ void System::SetDrawingLabelsWidth( int width ) m_drawingLabelsWidth = width; } } - + +void System::SetDrawingAbbrLabelsWidth( int width ) +{ + if ( m_drawingAbbrLabelsWidth < width ) { + m_drawingAbbrLabelsWidth = width; + } +} + //---------------------------------------------------------------------------- // System functor methods //---------------------------------------------------------------------------- diff --git a/src/view_element.cpp b/src/view_element.cpp index d8fd4fa0bf7..50d581701f7 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -1866,7 +1866,7 @@ void View::DrawKeySig( DeviceContext *dc, LayerElement *element, Layer *layer, S x = element->GetDrawingX(); // HARDCODED - int step = m_doc->GetGlyphWidth(SMUFL_E262_accidentalSharp, staff->m_drawingStaffSize, false) * 1.3; + int step = m_doc->GetGlyphWidth(SMUFL_E262_accidentalSharp, staff->m_drawingStaffSize, false) * TEMP_STYLE_KEYSIG_STEP; // Show cancellation if C major (0) or if any cancellation and show cancellation (showchange) is true (false by default) if ( (keySig->GetAlterationNumber() == 0) || (layer->DrawKeySigCancellation() && keySig->m_drawingShowchange) ) { diff --git a/src/view_page.cpp b/src/view_page.cpp index 3577573fa87..1310b806bed 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -70,11 +70,14 @@ void View::DrawCurrentPage( DeviceContext *dc, bool background ) processLayerElement = true; m_currentPage->Process( &setDrawingXY, ¶ms ); + // Keep the width of the initial scoreDef + SetScoreDefDrawingWidth(dc, &m_currentPage->m_drawingScoreDef); + // 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( ); @@ -92,14 +95,41 @@ void View::DrawCurrentPage( DeviceContext *dc, bool background ) dc->EndPage(); } + +void View::SetScoreDefDrawingWidth(DeviceContext *dc, ScoreDef *scoreDef) +{ + assert(dc); + assert(scoreDef); + + char numAlteration = 0; + + // key signature of the scoreDef + if (scoreDef->HasKeySigInfo()) { + KeySig *keySig = scoreDef->GetKeySigCopy(); + assert(keySig); + numAlteration = (keySig->GetAlterationNumber() > numAlteration) ? keySig->GetAlterationNumber() : numAlteration; + delete keySig; + } + + // longest key signature of the staffDefs + ListOfObjects* scoreDefList = scoreDef->GetList(scoreDef); //make sure it's initialized + for (ListOfObjects::iterator it = scoreDefList->begin(); it != scoreDefList->end(); it++) { + StaffDef *staffDef = dynamic_cast(*it); + assert( staffDef) ; + if (!staffDef->HasKeySigInfo()) continue; + KeySig *keySig = staffDef->GetKeySigCopy(); + assert(keySig); + numAlteration = (keySig->GetAlterationNumber() > numAlteration) ? keySig->GetAlterationNumber() : numAlteration; + delete keySig; + } + + scoreDef->SetDrawingWidth(100); +} //---------------------------------------------------------------------------- // View - System //---------------------------------------------------------------------------- - -// drawing - void View::DrawSystem( DeviceContext *dc, System *system ) { assert( dc ); @@ -238,10 +268,15 @@ void View::DrawStaffGrp( DeviceContext *dc, Measure *measure, StaffGrp *staffGrp y_bottom -= m_doc->GetDrawingStaffLineWidth(100) / 2; if (staffGrp->HasLabel()) { + std::string abbrLabel; std::string label = staffGrp->GetLabel(); - if ( abbreviations ) { + if (abbreviations) { label = staffGrp->GetLabelAbbr(); } + // We still store the abbreviated label for calculating max width with abbreviations (see below) + else { + abbrLabel = staffGrp->GetLabelAbbr(); + } if ( label.length() != 0) { // HARDCODED @@ -266,6 +301,12 @@ void View::DrawStaffGrp( DeviceContext *dc, Measure *measure, StaffGrp *staffGrp dc->StartText( ToDeviceContextX( x_label ), ToDeviceContextY( y_label ), RIGHT ); dc->DrawText( label ); dc->EndText( ); + + // also store in the system the maximum width with abbreviations + if (!abbreviations && (abbrLabel.length() > 0)) { + dc->GetTextExtent( abbrLabel, &w, &h); + system->SetDrawingAbbrLabelsWidth( w + space ); + } dc->ResetFont(); dc->ResetBrush(); @@ -328,10 +369,15 @@ void View::DrawStaffDefLabels( DeviceContext *dc, Measure *measure, ScoreDef *sc continue; } + std::string abbrLabel; std::string label = staffDef->GetLabel(); - if ( abbreviations ) { + if (abbreviations) { label = staffDef->GetLabelAbbr(); } + // We still store the abbreviated label for calculating max width with abbreviations (see below) + else { + abbrLabel = staffDef->GetLabelAbbr(); + } if ( label.length() == 0) { ++iter; @@ -354,6 +400,12 @@ void View::DrawStaffDefLabels( DeviceContext *dc, Measure *measure, ScoreDef *sc dc->DrawText( label ); dc->EndText( ); + // also store in the system the maximum width with abbreviations + if (!abbreviations && (abbrLabel.length() > 0)) { + dc->GetTextExtent( abbrLabel, &w, &h); + system->SetDrawingAbbrLabelsWidth( w + space ); + } + dc->ResetFont(); dc->ResetBrush(); @@ -945,8 +997,9 @@ void View::DrawSystemChildren( DeviceContext *dc, Object *parent, System *system // scoreDef are not drawn directly, but anything else should not be possible else if (current->Is() == SCOREDEF) { // nothing to do, then - // ScoreDef *scoreDef = dynamic_cast(current); - // assert( scoreDef ); + ScoreDef *scoreDef = dynamic_cast(current); + assert( scoreDef ); + SetScoreDefDrawingWidth(dc, scoreDef); } else { assert(false); From 196bbddf629509e417c07ab3e29f27d483a4cfe7 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 15 Sep 2015 13:11:14 +0200 Subject: [PATCH 20/85] Fixing bugs with ClassId in Annot and App --- include/vrv/editorial.h | 1 + src/view_page.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/vrv/editorial.h b/include/vrv/editorial.h index 585a7132e7a..1124cacf155 100644 --- a/include/vrv/editorial.h +++ b/include/vrv/editorial.h @@ -242,6 +242,7 @@ class Annot: public EditorialElement, virtual ~Annot(); virtual void Reset(); virtual std::string GetClassName( ) { return "Annot"; }; + virtual ClassId Is() { return ANNOT; }; ///@} protected: diff --git a/src/view_page.cpp b/src/view_page.cpp index 1310b806bed..4fe408be589 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -1106,7 +1106,7 @@ void View::DrawSystemEditorialElement( DeviceContext *dc, EditorialElement *elem void View::DrawMeasureEditorialElement( DeviceContext *dc, EditorialElement *element, Measure *measure, System *system ) { assert( element ); - if ( element->Object::Is() == APP ) { + if ( element->Is() == APP ) { assert( dynamic_cast(element)->GetLevel() == EDITORIAL_MEASURE ); } From 38bcfceb051447a73f7aa95de91cb7aa9bf79bdf Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 16 Sep 2015 07:29:32 +0200 Subject: [PATCH 21/85] Improved justification (finalized) --- include/vrv/scoredef.h | 2 +- src/doc.cpp | 3 +++ src/editorial.cpp | 1 + src/measure.cpp | 4 +++- src/scoredef.cpp | 7 +++++++ src/view_page.cpp | 11 +++++++++-- 6 files changed, 24 insertions(+), 4 deletions(-) diff --git a/include/vrv/scoredef.h b/include/vrv/scoredef.h index 673be52ae4d..d48f73deeb4 100644 --- a/include/vrv/scoredef.h +++ b/include/vrv/scoredef.h @@ -161,7 +161,7 @@ class ScoreDef: public ScoreDefElement, public ObjectListInterface * @name Set and get the scoreDef drawing width. */ ///@{ - bool GetDrawingWidth() const { return m_drawingWidth; }; + int GetDrawingWidth() const { return m_drawingWidth; }; void SetDrawingWidth( int drawingWidth ); ///@} diff --git a/src/doc.cpp b/src/doc.cpp index 77aee9896dc..ad036ae161a 100644 --- a/src/doc.cpp +++ b/src/doc.cpp @@ -346,12 +346,15 @@ void Doc::CastOff( ) int shift = -contentSystem->GetDrawingLabelsWidth(); int systemFullWidth = this->m_drawingPageWidth - this->m_drawingPageLeftMar - this->m_drawingPageRightMar - currentSystem->m_systemLeftMar - currentSystem->m_systemRightMar; + // The width of the initial scoreDef is stored in the page scoreDef + int scoreDefWidth = contentPage->m_drawingScoreDef.GetDrawingWidth() + contentSystem->GetDrawingAbbrLabelsWidth(); ArrayPtrVoid params; params.push_back( contentSystem ); params.push_back( contentPage ); params.push_back( ¤tSystem ); params.push_back( &shift ); params.push_back( &systemFullWidth ); + params.push_back( &scoreDefWidth ); Functor castOffSystems( &Object::CastOffSystems ); contentSystem->Process( &castOffSystems, ¶ms ); delete contentSystem; diff --git a/src/editorial.cpp b/src/editorial.cpp index aec177a4de2..e13badf9688 100644 --- a/src/editorial.cpp +++ b/src/editorial.cpp @@ -256,6 +256,7 @@ int EditorialElement::CastOffSystems( ArrayPtrVoid *params ) // param 2: a pointer to the current system // param 3: the cummulated shift (m_drawingXRel of the first measure of the current system) (unused) // param 4: the system width (unused) + // param 5: the current scoreDef width (unused) System *contentSystem = static_cast((*params).at(0)); System **currentSystem = static_cast((*params).at(2)); diff --git a/src/measure.cpp b/src/measure.cpp index adfd8281ab4..315da0a51b9 100644 --- a/src/measure.cpp +++ b/src/measure.cpp @@ -268,13 +268,15 @@ int Measure::CastOffSystems( ArrayPtrVoid *params ) // param 2: a pointer to the current system // param 3: the cummulated shift (m_drawingXRel of the first measure of the current system) // param 4: the system width + // param 5: the current scoreDef width System *contentSystem = static_cast((*params).at(0)); Page *page = static_cast((*params).at(1)); System **currentSystem = static_cast((*params).at(2)); int *shift = static_cast((*params).at(3)); int *systemWidth = static_cast((*params).at(4)); + int *currentScoreDefWidth = static_cast((*params).at(5)); - if ( ( (*currentSystem)->GetChildCount() > 0 ) && ( this->m_drawingXRel + this->GetWidth() - (*shift) > (*systemWidth) ) ) { + if ( ( (*currentSystem)->GetChildCount() > 0 ) && ( this->m_drawingXRel + this->GetWidth() + (*currentScoreDefWidth) - (*shift) > (*systemWidth) ) ) { (*currentSystem) = new System(); page->AddSystem( *currentSystem ); (*shift) = this->m_drawingXRel;; diff --git a/src/scoredef.cpp b/src/scoredef.cpp index 10334032529..5c87fa50483 100644 --- a/src/scoredef.cpp +++ b/src/scoredef.cpp @@ -447,8 +447,10 @@ int ScoreDef::CastOffSystems( ArrayPtrVoid *params ) // param 2: a pointer to the current system // param 3: the cummulated shift (m_drawingXRel of the first measure of the current system) (unused) // param 4: the system width (unused) + // param 5: the current scoreDef width System *contentSystem = static_cast((*params).at(0)); System **currentSystem = static_cast((*params).at(2)); + int *currentScoreDefWidth = static_cast((*params).at(5)); // Since the functor returns FUNCTOR_SIBLINGS we should never go lower than the system children assert( dynamic_cast(this->m_parent)); @@ -459,6 +461,11 @@ int ScoreDef::CastOffSystems( ArrayPtrVoid *params ) // the ownership of the Measure - the contentSystem will be deleted afterwards. ScoreDef *scoreDef = dynamic_cast( contentSystem->Relinquish( this->GetIdx()) ); (*currentSystem)->AddScoreDef( scoreDef ); + // This is not perfect since now the scoreDefWith is the one of the intermediate scoreDef (and not + // the initial one - for this to be corrected, we would need to parameters, one for the current initial + // scoreDef and one for the current that will be the initial one at the next system + // Also, the abbr label (width) changes would not be taken into account + (*currentScoreDefWidth) = this->GetDrawingWidth() + contentSystem->GetDrawingAbbrLabelsWidth();; return FUNCTOR_SIBLINGS; } diff --git a/src/view_page.cpp b/src/view_page.cpp index 4fe408be589..3d2ae7c6345 100644 --- a/src/view_page.cpp +++ b/src/view_page.cpp @@ -123,7 +123,14 @@ void View::SetScoreDefDrawingWidth(DeviceContext *dc, ScoreDef *scoreDef) delete keySig; } - scoreDef->SetDrawingWidth(100); + int width = 0; + // G-clef as default width + width += m_doc->GetLeftMargin(CLEF) + m_doc->GetGlyphWidth(SMUFL_E050_gClef, 100, false) + m_doc->GetRightMargin(CLEF); + if (numAlteration > 0) { + width += m_doc->GetLeftMargin(KEYSIG) + m_doc->GetGlyphWidth(SMUFL_E262_accidentalSharp, 100, false) * TEMP_STYLE_KEYSIG_STEP + m_doc->GetRightMargin(KEYSIG); + } + + scoreDef->SetDrawingWidth(width); } //---------------------------------------------------------------------------- @@ -400,7 +407,7 @@ void View::DrawStaffDefLabels( DeviceContext *dc, Measure *measure, ScoreDef *sc dc->DrawText( label ); dc->EndText( ); - // also store in the system the maximum width with abbreviations + // also store in the system the maximum width with abbreviations for justification if (!abbreviations && (abbrLabel.length() > 0)) { dc->GetTextExtent( abbrLabel, &w, &h); system->SetDrawingAbbrLabelsWidth( w + space ); From 1abcd389f9dd40062e16860445a4ac7c94e58f2d Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 16 Sep 2015 16:45:57 +0200 Subject: [PATCH 22/85] WIP on stem drawing --- include/vrv/chord.h | 3 +- include/vrv/drawinginterface.h | 48 ++++++++++++++++++++++++++++++++ include/vrv/layerelement.h | 10 ------- include/vrv/note.h | 2 +- src/chord.cpp | 5 ++-- src/drawinginterface.cpp | 22 +++++++++++++++ src/layerelement.cpp | 23 ++++++++++++---- src/note.cpp | 3 +- src/view_beam.cpp | 35 +++++++++++------------- src/view_element.cpp | 50 ++++++++++++++++------------------ src/view_tuplet.cpp | 21 +++++++++----- 11 files changed, 149 insertions(+), 73 deletions(-) diff --git a/include/vrv/chord.h b/include/vrv/chord.h index 8769df47468..4b1574a63ac 100644 --- a/include/vrv/chord.h +++ b/include/vrv/chord.h @@ -10,6 +10,7 @@ #define __VRV_CHORD_H__ #include "atts_shared.h" +#include "drawinginterface.h" #include "durationinterface.h" #include "layerelement.h" @@ -29,7 +30,7 @@ namespace vrv { * It contains notes. */ -class Chord: public LayerElement, public ObjectListInterface, public DurationInterface, +class Chord: public LayerElement, public ObjectListInterface, public StemmedDrawingInterface, public DurationInterface, public AttCommon, public AttStemmed, public AttTiepresent diff --git a/include/vrv/drawinginterface.h b/include/vrv/drawinginterface.h index 445b164e80d..bf10ac23f7d 100644 --- a/include/vrv/drawinginterface.h +++ b/include/vrv/drawinginterface.h @@ -9,6 +9,7 @@ #ifndef __VRV_DRAWING_INTERFACE_H__ #define __VRV_DRAWING_INTERFACE_H__ +#include "devicecontextbase.h" #include "vrvdef.h" namespace vrv { @@ -167,6 +168,53 @@ class StaffDefDrawingInterface }; + +//---------------------------------------------------------------------------- +// StemmedDrawingInterface +//---------------------------------------------------------------------------- + +/** + * This class is an interface for MEI stemmed element. + * It stores stem drawing values for notes and chords. + */ +class StemmedDrawingInterface +{ +public: + /** + * @name Constructors, destructors, and other standard methods + */ + ///@{ + StemmedDrawingInterface(); + virtual ~StemmedDrawingInterface(); + virtual void Reset(); + ///@} + + /** + * @name Set and get the stem direction and stem positions + * The methods are virtual because they need to be overriden for Chords. + */ + ///@{ + virtual void SetDrawingStemDir(data_STEMDIRECTION stemDir); + virtual data_STEMDIRECTION GetDrawingStemDir(); + virtual void SetDrawingStemStart(Point stemStart); + virtual Point GetDrawingStemStart(); + virtual void SetDrawingStemEnd(Point stemEnd); + virtual Point GetDrawingStemEnd(); + ///@} + +protected: + /** + * If this is a note, store here the stem coordinates (useful for ex. tuplets) + */ + Point m_drawingStemStart; // beginning point, the one near the note + Point m_drawingStemEnd; // end point (!), near beam or stem + /** + * Stem direction as drawn + */ + data_STEMDIRECTION m_drawingStemDir; + +}; + } // namespace vrv #endif diff --git a/include/vrv/layerelement.h b/include/vrv/layerelement.h index ebab918fc29..bd8271abad7 100644 --- a/include/vrv/layerelement.h +++ b/include/vrv/layerelement.h @@ -9,7 +9,6 @@ #ifndef __VRV_LAYER_ELEMENT_H__ #define __VRV_LAYER_ELEMENT_H__ -#include "devicecontextbase.h" #include "object.h" namespace vrv { @@ -138,15 +137,6 @@ class LayerElement: public DocObject public: /** Absolute position X. This is used for facsimile (transcription) encoding */ int m_xAbs; - /** - * If this is a note, store here the stem coordinates (useful for ex. tuplets) - */ - Point m_drawingStemStart; // beginning point, the one near the note - Point m_drawingStemEnd; // end point (!), near beam or stem - /** - * Stem direction as drawn - */ - data_STEMDIRECTION m_drawingStemDir; /** * This store a pointer to the corresponding BeamElementCoord(currentDur > DUR_4) */ diff --git a/include/vrv/note.h b/include/vrv/note.h index 98e8174b83e..aa8cd4d64bf 100644 --- a/include/vrv/note.h +++ b/include/vrv/note.h @@ -42,7 +42,7 @@ typedef std::vector ChordCluster; #define EMB_TRILL 1 #define EMB_MORDENT 2 -class Note: public LayerElement, public DurationInterface, public PitchInterface, +class Note: public LayerElement, public StemmedDrawingInterface, public DurationInterface, public PitchInterface, public AttColoration, public AttGraced, public AttNoteLogMensural, diff --git a/src/chord.cpp b/src/chord.cpp index dc91a5c8490..d12a2c901c4 100644 --- a/src/chord.cpp +++ b/src/chord.cpp @@ -23,7 +23,7 @@ namespace vrv { //---------------------------------------------------------------------------- Chord::Chord( ): - LayerElement("chord-"), ObjectListInterface(), DurationInterface(), + LayerElement("chord-"), StemmedDrawingInterface(), ObjectListInterface(), DurationInterface(), AttCommon(), AttStemmed(), AttTiepresent() @@ -48,7 +48,8 @@ Chord::~Chord() void Chord::Reset() { ClearClusters(); - DocObject::Reset(); + LayerElement::Reset(); + StemmedDrawingInterface::Reset(); DurationInterface::Reset(); ResetCommon(); ResetStemmed(); diff --git a/src/drawinginterface.cpp b/src/drawinginterface.cpp index 7bde16d591f..e24044ba049 100644 --- a/src/drawinginterface.cpp +++ b/src/drawinginterface.cpp @@ -175,4 +175,26 @@ StaffDefDrawingInterface& StaffDefDrawingInterface::operator=( const StaffDefDra return *this; } + +//---------------------------------------------------------------------------- +// StemmedDrawingInterface +//---------------------------------------------------------------------------- + +StemmedDrawingInterface::StemmedDrawingInterface() +{ + Reset(); +} + +StemmedDrawingInterface::~StemmedDrawingInterface() +{ +} + +void StemmedDrawingInterface::Reset() +{ + m_drawingStemDir = STEMDIRECTION_NONE; + m_drawingStemStart = Point(0, 0); + m_drawingStemEnd = Point(0, 0); +} + + } // namespace vrv diff --git a/src/layerelement.cpp b/src/layerelement.cpp index 2dc0c471972..fe7ce14cea2 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -71,7 +71,6 @@ void LayerElement::Reset() m_isScoreOrStaffDefAttr = false; m_alignment = NULL; - m_drawingStemDir = STEMDIRECTION_NONE; m_beamElementCoord = NULL; } @@ -133,8 +132,14 @@ int LayerElement::GetDrawingTop(Doc *doc, int staffSize) { if ((this->Is() == NOTE) || (this->Is() == CHORD)){ // We should also take into accound the stem shift to the right - if (this->GetDrawingStemDir() == STEMDIRECTION_up) return this->m_drawingStemEnd.y; - else return this->m_drawingStemStart.y + doc->GetDrawingUnit(staffSize); + StemmedDrawingInterface *stemmedDrawingInterface = dynamic_cast(this); + assert(stemmedDrawingInterface); + if (stemmedDrawingInterface->GetDrawingStemDir() == STEMDIRECTION_up) { + return stemmedDrawingInterface->GetDrawingStemEnd().y; + } + else { + return stemmedDrawingInterface->GetDrawingStemStart().y + doc->GetDrawingUnit(staffSize); + } } return this->GetDrawingY(); } @@ -143,9 +148,15 @@ int LayerElement::GetDrawingTop(Doc *doc, int staffSize) int LayerElement::GetDrawingBottom(Doc *doc, int staffSize) { if ((this->Is() == NOTE) || (this->Is() == CHORD)){ - if (this->GetDrawingStemDir() == STEMDIRECTION_up) return this->m_drawingStemStart.y - doc->GetDrawingUnit(staffSize); - // We should also take into accound the stem shift to the left - else return this->m_drawingStemEnd.y; + // We should also take into accound the stem shift to the right + StemmedDrawingInterface *stemmedDrawingInterface = dynamic_cast(this); + assert(stemmedDrawingInterface); + if (stemmedDrawingInterface->GetDrawingStemDir() == STEMDIRECTION_up) { + return stemmedDrawingInterface->GetDrawingStemStart().y + doc->GetDrawingUnit(staffSize); + } + else { + return stemmedDrawingInterface->GetDrawingStemEnd().y; + } } return this->GetDrawingY(); } diff --git a/src/note.cpp b/src/note.cpp index b8455e70cbd..452d3fb70ca 100644 --- a/src/note.cpp +++ b/src/note.cpp @@ -27,7 +27,7 @@ namespace vrv { //---------------------------------------------------------------------------- Note::Note(): - LayerElement("note-"), DurationInterface(), PitchInterface(), + LayerElement("note-"), StemmedDrawingInterface(), DurationInterface(), PitchInterface(), AttColoration(), AttGraced(), AttNoteLogMensural(), @@ -67,6 +67,7 @@ Note::~Note() void Note::Reset() { LayerElement::Reset(); + StemmedDrawingInterface::Reset(); DurationInterface::Reset(); PitchInterface::Reset(); diff --git a/src/view_beam.cpp b/src/view_beam.cpp index 9c7e871fc4c..c8300244c45 100644 --- a/src/view_beam.cpp +++ b/src/view_beam.cpp @@ -359,25 +359,18 @@ void View::DrawBeam( DeviceContext *dc, LayerElement *element, Layer *layer, Sta fy2 = (*beamElementCoords).at(i)->m_yTop - m_doc->GetDrawingUnit(staff->m_drawingStaffSize)/4; } - // All notes and chords, including notes within chords, get their stem value stored - LayerElement *el = (*beamElementCoords).at(i)->m_element; - el->m_drawingStemStart.x = el->m_drawingStemEnd.x = (*beamElementCoords).at(i)->m_x; - el->m_drawingStemStart.y = fy2; - el->m_drawingStemEnd.y = fy1; - el->m_drawingStemDir = stemDir; - - if ( (*beamElementCoords).at(i)->m_element->Is() == CHORD ) { - Chord *chord = (Chord*)(*beamElementCoords).at(i)->m_element; - for (ListOfObjects::iterator it = chord->GetList(chord)->begin(); it != chord->GetList(chord)->end(); it++) - { - Note *note = dynamic_cast(*it); - assert(note); - note->m_drawingStemStart.x = el->m_drawingStemEnd.x = (*beamElementCoords).at(i)->m_x; - note->m_drawingStemStart.y = fy2; - note->m_drawingStemEnd.y = fy1; - note->SetDrawingStemDir(stemDir); - } + // All notes and chords get their stem value stored + if ( (current->Is() == NOTE) || (current->Is() == CHORD) ) { + StemmedDrawingInterface *interface = dynamic_cast(current); + assert(interface); + + interface->SetDrawingStemDir(stemDir); + interface->SetDrawingStemStart(Point((*beamElementCoords).at(i)->m_x, fy2)); + interface->SetDrawingStemEnd(Point((*beamElementCoords).at(i)->m_x, fy1)); + } + + } @@ -393,7 +386,11 @@ void View::DrawBeam( DeviceContext *dc, LayerElement *element, Layer *layer, Sta { LayerElement *el = (*beamElementCoords).at(i)->m_element; if( ( (el->Is() == NOTE) && !dynamic_cast(el)->IsChordTone()) || (el->Is() == CHORD) ) { - DrawVerticalLine (dc, el->m_drawingStemStart.y, el->m_drawingStemEnd.y, el->m_drawingStemStart.x, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize)); + StemmedDrawingInterface *interface = dynamic_cast(current); + assert(interface); + + DrawVerticalLine (dc, interface->GetDrawingStemStart().y, interface->GetDrawingStemEnd().y, + interface->GetDrawingStemStart().x, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize)); } } diff --git a/src/view_element.cpp b/src/view_element.cpp index 50d581701f7..f19a7a6448b 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -501,11 +501,6 @@ void View::DrawStem( DeviceContext *dc, LayerElement *object, Staff *staff, data if (dir == STEMDIRECTION_up) { DrawFullRectangle( dc, x2 - m_doc->GetDrawingStemWidth(staffSize), stemY1, x2, stemY2); - object->m_drawingStemStart.x = object->m_drawingStemEnd.x = x2 - (m_doc->GetDrawingStemWidth(staffSize) / 2); - object->m_drawingStemStart.y = y1; - object->m_drawingStemEnd.y = y2; - object->m_drawingStemDir = STEMDIRECTION_up; - if (drawingDur > DUR_4) { DrawSmuflCode( dc, x2 - m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize), y2, SMUFL_E240_flag8thUp, staff->m_drawingStaffSize, drawingCueSize ); for (int i=0; i < nbFlags; i++) @@ -515,11 +510,6 @@ void View::DrawStem( DeviceContext *dc, LayerElement *object, Staff *staff, data else { DrawFullRectangle( dc, x2, stemY1, x2 + m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize), stemY2); - object->m_drawingStemStart.x = object->m_drawingStemEnd.x = x2 - (m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) / 2); - object->m_drawingStemStart.y = y1; - object->m_drawingStemEnd.y = y2; - object->m_drawingStemDir = STEMDIRECTION_down; - if (drawingDur > DUR_4) { DrawSmuflCode( dc, x2 , y2, SMUFL_E241_flag8thDown , staff->m_drawingStaffSize, drawingCueSize ); for (int i=0; i < nbFlags; i++) @@ -527,6 +517,13 @@ void View::DrawStem( DeviceContext *dc, LayerElement *object, Staff *staff, data } } + // Store the start and end values + StemmedDrawingInterface *interface = dynamic_cast(object); + assert(interface); + interface->SetDrawingStemStart(Point(x2 - (m_doc->GetDrawingStemWidth(staffSize) / 2), y1)); + interface->SetDrawingStemEnd(Point(x2 - (m_doc->GetDrawingStemWidth(staffSize) / 2), y2)); + interface->SetDrawingStemDir(dir); + // cast to note is check when setting drawingCueSize value if ( drawingCueSize && ( dynamic_cast(object)->GetGrace() == GRACE_acc ) ) { DrawAcciaccaturaSlash(dc, object); @@ -607,9 +604,9 @@ void View::DrawRest ( DeviceContext *dc, LayerElement *element, Layer *layer, St int y = element->GetDrawingY(); // Temporary fix for rest within tuplet because drawing tuplet requires m_drawingStemXXX to be set - element->m_drawingStemStart.x = element->m_drawingStemEnd.x = element->GetDrawingX() - (m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) / 2); - element->m_drawingStemEnd.y = element->GetDrawingY(); - element->m_drawingStemStart.y = element->GetDrawingY(); + //element->m_drawingStemStart.x = element->m_drawingStemEnd.x = element->GetDrawingX() - (m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) / 2); + //element->m_drawingStemEnd.y = element->GetDrawingY(); + //element->m_drawingStemStart.y = element->GetDrawingY(); if (drawingDur > DUR_2) { @@ -1311,8 +1308,8 @@ void View::DrawClef( DeviceContext *dc, LayerElement *element, Layer *layer, Sta // force cue size for intermediate clefs if (clef->GetFirstParent( LAYER )) cueSize = true; - if (!cueSize) - a -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; + //if (!cueSize) + // a -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2; DrawSmuflCode ( dc, a, b, sym, staff->m_drawingStaffSize, cueSize ); @@ -1593,8 +1590,8 @@ void View::DrawAccid( DeviceContext *dc, LayerElement *element, Layer *layer, St if ( note->GetDrawingY() > y ) { y = note->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize); } - if ( (note->GetDrawingStemDir() == STEMDIRECTION_up) && (note->m_drawingStemEnd.y > y )) { - y = note->m_drawingStemEnd.y; + if ( (note->GetDrawingStemDir() == STEMDIRECTION_up) && (note->GetDrawingStemEnd().y > y )) { + y = note->GetDrawingStemEnd().y; } // adjust the x position so it is centered @@ -1928,19 +1925,20 @@ void View::DrawAcciaccaturaSlash(DeviceContext *dc, LayerElement *element) int positionShiftY1 = positionShift * 2; int positionShiftX2 = positionShift * 3; int positionShiftY2 = positionShift * 6; + Point startPoint = note->GetDrawingStemStart(); // HARDCODED - if (element->m_drawingStemDir == STEMDIRECTION_up) { + if (note->GetDrawingStemDir() == STEMDIRECTION_up) { dc->DrawLine( - ToDeviceContextX(element->m_drawingStemStart.x - positionShiftX1 ), - ToDeviceContextY(element->m_drawingStemStart.y + positionShiftY1), - ToDeviceContextX(element->m_drawingStemStart.x + positionShiftX2), - ToDeviceContextY(element->m_drawingStemStart.y + positionShiftY2)); + ToDeviceContextX(startPoint.x - positionShiftX1 ), + ToDeviceContextY(startPoint.y + positionShiftY1), + ToDeviceContextX(startPoint.x + positionShiftX2), + ToDeviceContextY(note->GetDrawingStemStart().y + positionShiftY2)); } else { - dc->DrawLine(ToDeviceContextX(element->m_drawingStemStart.x - positionShiftX1), - ToDeviceContextY(element->m_drawingStemStart.y - positionShiftY1), - ToDeviceContextX(element->m_drawingStemStart.x + positionShiftX2), - ToDeviceContextY(element->m_drawingStemStart.y - positionShiftY2)); + dc->DrawLine(ToDeviceContextX(startPoint.x - positionShiftX1), + ToDeviceContextY(startPoint.y - positionShiftY1), + ToDeviceContextX(startPoint.x + positionShiftX2), + ToDeviceContextY(startPoint.y - positionShiftY2)); } dc->ResetPen(); diff --git a/src/view_tuplet.cpp b/src/view_tuplet.cpp index 92482d9481c..a5987c457a2 100644 --- a/src/view_tuplet.cpp +++ b/src/view_tuplet.cpp @@ -17,6 +17,7 @@ #include "beam.h" #include "devicecontext.h" #include "doc.h" +#include "note.h" #include "smufl.h" #include "staff.h" #include "style.h" @@ -96,20 +97,26 @@ data_STEMDIRECTION View::GetTupletCoordinates(Tuplet* tuplet, Layer *layer, Poin LayerElement *firstNote = dynamic_cast(tupletChildren->front()); LayerElement *lastNote = dynamic_cast(tupletChildren->back()); + + // AllNotesBeamed tries to figure out if all the notes are in the same beam if (OneBeamInTuplet(tuplet)) { // yes they are in a beam - // get the x position centered from the STEM so it looks better - // NOTE start and end are left to 0, this is the signal that no bracket has to be drawn - x = firstNote->m_drawingStemStart.x + (lastNote->m_drawingStemStart.x - firstNote->m_drawingStemStart.x) / 2; + x = firstNote->GetDrawingX() + (lastNote->GetDrawingX() - firstNote->GetDrawingX() + lastNote->m_selfBB_x2) / 2; // align the center point at the exact center of the first an last stem // TUPLET_OFFSET is summed so it does not collide with the stem - if (firstNote->m_drawingStemDir == STEMDIRECTION_up) - y = lastNote->m_drawingStemEnd.y + (firstNote->m_drawingStemEnd.y - lastNote->m_drawingStemEnd.y) / 2 + TUPLET_OFFSET; - else - y = lastNote->m_drawingStemEnd.y + (firstNote->m_drawingStemEnd.y - lastNote->m_drawingStemEnd.y) / 2 - TUPLET_OFFSET; + Note* note = dynamic_cast(tuplet->GetFirstChild(NOTE)); + Note* lastNote = dynamic_cast(tuplet->GetLastChild(NOTE)); + + y = firstNote->GetDrawingY(); + if (note) { + if (note->GetDrawingStemDir() == STEMDIRECTION_up) + y = note->GetDrawingStemEnd().y + (firstNote->note->GetDrawingStemEnd().y - lastNote->m_drawingStemEnd.y) / 2 + TUPLET_OFFSET; + else + y = lastNote->m_drawingStemEnd.y + (firstNote->m_drawingStemEnd.y - lastNote->m_drawingStemEnd.y) / 2 - TUPLET_OFFSET; + } // Copy the generated coordinates center->x = x; From 5a8a9761a57a049b49159d3d1890a3397007a9bc Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 17 Sep 2015 14:27:32 +0200 Subject: [PATCH 23/85] Fixing minor bugs --- include/vrv/view.h | 6 ++--- src/view_floating.cpp | 63 +++++++++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index 5f31b5e9e22..5bd0177e477 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -342,10 +342,10 @@ class View * @name Internal methods used for calculating slurs */ float AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point points[]); - bool AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, + int AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle, bool posRatio = true ); - bool AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, - bool up, float *angle ); + void AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, + bool up, float *angle, bool forceBothSides ); float GetAdjustedSlurAngle(Point *p1, Point *p2, bool up); void GetControlPoints(Point *p1, Point *p2, Point *c1, Point *c2, bool up, int height, int staffSize); void GetSpanningPointPositions( ArrayOfLayerElementPointPairs *spanningPoints, Point p1, float angle, bool up, int staffSize); diff --git a/src/view_floating.cpp b/src/view_floating.cpp index 8bbfad8a0ce..ad0547143d2 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -472,20 +472,23 @@ float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point poi Point adjustedRotatedC1 = rotatedC1; Point adjustedRotatedC2 = rotatedC2; - bool needPositionAdjustment = false; if (!spanningContentPoints.empty()) { - needPositionAdjustment = AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, slurAngle ); - } - if (needPositionAdjustment) { + AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, slurAngle ); // Use the adjusted control points for ajusting the position (p1, p2 and angle will be updated) - AdjustSlurPosition(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, &slurAngle ); + AdjustSlurPosition(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, &slurAngle, false ); // Now readjust the curvature with the new p1 and p2 with the original control points GetControlPoints(p1, &rotatedP2, &rotatedC1, &rotatedC2, up, height, staff->m_drawingStaffSize); + GetSpanningPointPositions( &spanningContentPoints, *p1, slurAngle, up, staff->m_drawingStaffSize); - AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle, false ); - if (!spanningContentPoints.empty()) { + int maxHeight = AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, slurAngle, false ); + + if (maxHeight) { // Something went wrong since now all spanning points should be gone... - LogDebug("### %d notes for %s will need position adjustment", spanningContentPoints.size(), slur->GetUuid().c_str()); + //LogDebug("### %d notes for %s will need position adjustment", spanningContentPoints.size(), slur->GetUuid().c_str()); + // Use the normal control points for ajusting the position (p1, p2 and angle will be updated) + // Move it and forcing both side to move + AdjustSlurPosition(slur, &spanningContentPoints, p1, &rotatedP2, &rotatedC1, &rotatedC2, up, &slurAngle, true ); + GetControlPoints(p1, &rotatedP2, &rotatedC1, &rotatedC2, up, maxHeight, staff->m_drawingStaffSize); } } else { @@ -553,16 +556,16 @@ void View::GetSpanningPointPositions( ArrayOfLayerElementPointPairs *spanningPoi } p.x = itPoint->first->GetDrawingX(); // Not sure if it is better to add the margin before or after the rotation... - if (up) p.y += m_doc->GetDrawingUnit(staffSize) * 3; - else p.y -= m_doc->GetDrawingUnit(staffSize) * 3; + //if (up) p.y += m_doc->GetDrawingUnit(staffSize) * 2; + //else p.y -= m_doc->GetDrawingUnit(staffSize) * 2; itPoint->second = View::CalcPositionAfterRotation(p, -angle, p1); // This would add it after - //if (up) itPoint->second.y += m_doc->GetDrawingUnit(staffSize) * 3; - //else itPoint->second.y -= m_doc->GetDrawingUnit(staffSize) * 3; + if (up) itPoint->second.y += m_doc->GetDrawingUnit(staffSize) * 2; + else itPoint->second.y -= m_doc->GetDrawingUnit(staffSize) * 2; } } -bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle, bool posRatio) +int View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float angle, bool posRatio) { Point bezier[4]; bezier[0] = *p1; @@ -585,6 +588,8 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo //maxHeight = std::min( maxHeight, m_doc->GetDrawingStaffSize(100) ); } + bool hasReachedMaxHeight = false; + if (maxHeight > currentHeight) { float maxRatio = 1.0; float posXRatio = 1.0; @@ -614,7 +619,7 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo } else { if (y > itPoint->second.y) { - float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y); + float ratio = (float)(p1->y - itPoint->second.y) / (float)(p1->y - y) * posXRatio; maxRatio = ratio > maxRatio ? ratio : maxRatio; itPoint++; } @@ -628,6 +633,7 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo // We should not adjust it more than the maximum height int desiredHeight = currentHeight * maxRatio; if (desiredHeight > maxHeight) { + hasReachedMaxHeight = true; maxRatio = (float)maxHeight / (float)currentHeight; } @@ -643,26 +649,32 @@ bool View::AdjustSlurCurve(Slur *slur, ArrayOfLayerElementPointPairs *spanningPo } } - // filter the points with the adjusted curve + // Check if we need further adjustment the points with the adjusted curve + /* bezier[1] = *c1; bezier[2] = *c2; for (itPoint = spanningPoints->begin(); itPoint != spanningPoints->end();) { y = View::CalcBezierAtPosition(bezier, itPoint->second.x); if (up) { - if (y > itPoint->second.y) itPoint = spanningPoints->erase( itPoint ); - else itPoint++; + //if (y > itPoint->second.y) itPoint = spanningPoints->erase( itPoint ); + //else itPoint++; } else { - if (y < itPoint->second.y) itPoint = spanningPoints->erase( itPoint ); - else itPoint++; + //if (y < itPoint->second.y) itPoint = spanningPoints->erase( itPoint ); + //else itPoint++; } + itPoint++; } // We will need to adjust the further if the list is not empty return (!spanningPoints->empty()); + */ + + if (hasReachedMaxHeight) return maxHeight; + else return 0; } -bool View::AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float *angle) +void View::AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spanningPoints, Point *p1, Point *p2, Point *c1, Point *c2, bool up, float *angle, bool forceBothSides) { Point bezier[4]; bezier[0] = *p1; @@ -707,19 +719,20 @@ bool View::AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spannin } } if (shift > 0) { - leftShift = leftPoint ? shift : shift * posXRatio; - rightShift = !leftPoint ? shift : shift * posXRatio; + leftShift = (forceBothSides || leftPoint) ? shift : shift * posXRatio; + rightShift = (forceBothSides || !leftPoint) ? shift : shift * posXRatio; maxShiftLeft = leftShift > maxShiftLeft ? leftShift : maxShiftLeft; maxShiftRight = rightShift > maxShiftRight ? rightShift : maxShiftRight; itPoint++; } else { - itPoint = spanningPoints->erase(itPoint); + //itPoint = spanningPoints->erase(itPoint); + itPoint++; } } // Actually nothing to do - if (spanningPoints->empty()) return true; + if (spanningPoints->empty()) return; // Unrotated the slur *p2 = View::CalcPositionAfterRotation(*p2, (*angle), *p1); @@ -735,8 +748,6 @@ bool View::AdjustSlurPosition(Slur *slur, ArrayOfLayerElementPointPairs *spannin *angle = GetAdjustedSlurAngle(p1, p2, up); *p2 = View::CalcPositionAfterRotation(*p2, -(*angle), *p1); - - return false; } void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, From 826e04c270e37d18dbc6122f151fb92b130510f8 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 17 Sep 2015 14:45:56 +0200 Subject: [PATCH 24/85] Adding mensural clef (E901, 904, 909) --- data/Bravura.xml | 3 + data/Bravura/E901-mensuralGclefPetrucci.xml | 8 + data/Bravura/E904-mensuralFclefPetrucci.xml | 8 + .../E909-mensuralCclefPetrucciPosMiddle.xml | 8 + data/Gootville.xml | 3 + data/Gootville/E901-mensuralGclefPetrucci.xml | 8 + data/Gootville/E904-mensuralFclefPetrucci.xml | 8 + .../E909-mensuralCclefPetrucciPosMiddle.xml | 8 + data/Leipzig.xml | 3 + .../E4A8-articStaccatissimoWedgeAbove.xml | 2 +- .../E4A9-articStaccatissimoWedgeBelow.xml | 2 +- data/Leipzig/E500-repeat1Bar.xml | 2 +- data/Leipzig/E501-repeat2Bars.xml | 2 +- data/Leipzig/E502-repeat4Bars.xml | 2 +- data/Leipzig/E521-dynamicMezzo.xml | 2 +- data/Leipzig/E522-dynamicForte.xml | 2 +- data/Leipzig/E52F-dynamicFF.xml | 2 +- data/Leipzig/E531-dynamicFFFF.xml | 2 +- data/Leipzig/E532-dynamicFFFFF.xml | 2 +- data/Leipzig/E567-ornamentTurn.xml | 2 +- data/Leipzig/E568-ornamentTurnInverted.xml | 2 +- data/Leipzig/E56A-ornamentTurnUp.xml | 2 +- data/Leipzig/E56B-ornamentTurnUpS.xml | 2 +- data/Leipzig/E56E-ornamentTremblement.xml | 2 +- data/Leipzig/E901-mensuralGclefPetrucci.xml | 8 + data/Leipzig/E904-mensuralFclefPetrucci.xml | 8 + .../E909-mensuralCclefPetrucciPosMiddle.xml | 8 + fonts/Leipzig-5.2.sfd | 239 +++++++++++++++++- fonts/Leipzig.svg | 163 ++++++------ fonts/supported.xsl | 6 +- include/vrv/smufl.h | 5 +- 31 files changed, 425 insertions(+), 99 deletions(-) create mode 100644 data/Bravura/E901-mensuralGclefPetrucci.xml create mode 100644 data/Bravura/E904-mensuralFclefPetrucci.xml create mode 100644 data/Bravura/E909-mensuralCclefPetrucciPosMiddle.xml create mode 100644 data/Gootville/E901-mensuralGclefPetrucci.xml create mode 100644 data/Gootville/E904-mensuralFclefPetrucci.xml create mode 100644 data/Gootville/E909-mensuralCclefPetrucciPosMiddle.xml create mode 100644 data/Leipzig/E901-mensuralGclefPetrucci.xml create mode 100644 data/Leipzig/E904-mensuralFclefPetrucci.xml create mode 100644 data/Leipzig/E909-mensuralCclefPetrucciPosMiddle.xml diff --git a/data/Bravura.xml b/data/Bravura.xml index 023eb2ac331..0b139bb697d 100644 --- a/data/Bravura.xml +++ b/data/Bravura.xml @@ -103,6 +103,9 @@ + + + diff --git a/data/Bravura/E901-mensuralGclefPetrucci.xml b/data/Bravura/E901-mensuralGclefPetrucci.xml new file mode 100644 index 00000000000..72026ec8be3 --- /dev/null +++ b/data/Bravura/E901-mensuralGclefPetrucci.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Bravura/E904-mensuralFclefPetrucci.xml b/data/Bravura/E904-mensuralFclefPetrucci.xml new file mode 100644 index 00000000000..f5ee6368076 --- /dev/null +++ b/data/Bravura/E904-mensuralFclefPetrucci.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Bravura/E909-mensuralCclefPetrucciPosMiddle.xml b/data/Bravura/E909-mensuralCclefPetrucciPosMiddle.xml new file mode 100644 index 00000000000..ea11f5ace3e --- /dev/null +++ b/data/Bravura/E909-mensuralCclefPetrucciPosMiddle.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Gootville.xml b/data/Gootville.xml index 0c8dde65e05..262bbd1de2b 100644 --- a/data/Gootville.xml +++ b/data/Gootville.xml @@ -103,6 +103,9 @@ + + + diff --git a/data/Gootville/E901-mensuralGclefPetrucci.xml b/data/Gootville/E901-mensuralGclefPetrucci.xml new file mode 100644 index 00000000000..b11f8f63c1c --- /dev/null +++ b/data/Gootville/E901-mensuralGclefPetrucci.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Gootville/E904-mensuralFclefPetrucci.xml b/data/Gootville/E904-mensuralFclefPetrucci.xml new file mode 100644 index 00000000000..36a690e8ae2 --- /dev/null +++ b/data/Gootville/E904-mensuralFclefPetrucci.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Gootville/E909-mensuralCclefPetrucciPosMiddle.xml b/data/Gootville/E909-mensuralCclefPetrucciPosMiddle.xml new file mode 100644 index 00000000000..d1574e34255 --- /dev/null +++ b/data/Gootville/E909-mensuralCclefPetrucciPosMiddle.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Leipzig.xml b/data/Leipzig.xml index b4908963b42..3d1540bbeb8 100644 --- a/data/Leipzig.xml +++ b/data/Leipzig.xml @@ -107,4 +107,7 @@ + + + diff --git a/data/Leipzig/E4A8-articStaccatissimoWedgeAbove.xml b/data/Leipzig/E4A8-articStaccatissimoWedgeAbove.xml index 67247e91415..2e4eb2534ae 100644 --- a/data/Leipzig/E4A8-articStaccatissimoWedgeAbove.xml +++ b/data/Leipzig/E4A8-articStaccatissimoWedgeAbove.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="153"> - + diff --git a/data/Leipzig/E4A9-articStaccatissimoWedgeBelow.xml b/data/Leipzig/E4A9-articStaccatissimoWedgeBelow.xml index 939e754fa81..20cd3c2010a 100644 --- a/data/Leipzig/E4A9-articStaccatissimoWedgeBelow.xml +++ b/data/Leipzig/E4A9-articStaccatissimoWedgeBelow.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="153"> - + diff --git a/data/Leipzig/E500-repeat1Bar.xml b/data/Leipzig/E500-repeat1Bar.xml index 537d9e14db0..10ad368c74f 100644 --- a/data/Leipzig/E500-repeat1Bar.xml +++ b/data/Leipzig/E500-repeat1Bar.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="508"> - + diff --git a/data/Leipzig/E501-repeat2Bars.xml b/data/Leipzig/E501-repeat2Bars.xml index 04ea5ab7981..1f1f45be1ee 100644 --- a/data/Leipzig/E501-repeat2Bars.xml +++ b/data/Leipzig/E501-repeat2Bars.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="751"> - + diff --git a/data/Leipzig/E502-repeat4Bars.xml b/data/Leipzig/E502-repeat4Bars.xml index 8245027e5df..2c508da2ced 100644 --- a/data/Leipzig/E502-repeat4Bars.xml +++ b/data/Leipzig/E502-repeat4Bars.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="1234"> - + diff --git a/data/Leipzig/E521-dynamicMezzo.xml b/data/Leipzig/E521-dynamicMezzo.xml index 00ae427e3d4..00430b7d11e 100644 --- a/data/Leipzig/E521-dynamicMezzo.xml +++ b/data/Leipzig/E521-dynamicMezzo.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="405"> - + diff --git a/data/Leipzig/E522-dynamicForte.xml b/data/Leipzig/E522-dynamicForte.xml index a285762bd96..bc40b716211 100644 --- a/data/Leipzig/E522-dynamicForte.xml +++ b/data/Leipzig/E522-dynamicForte.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="232"> - + diff --git a/data/Leipzig/E52F-dynamicFF.xml b/data/Leipzig/E52F-dynamicFF.xml index 606acdbe7c0..c1c14b906e1 100644 --- a/data/Leipzig/E52F-dynamicFF.xml +++ b/data/Leipzig/E52F-dynamicFF.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="479"> - + diff --git a/data/Leipzig/E531-dynamicFFFF.xml b/data/Leipzig/E531-dynamicFFFF.xml index b769b0d2966..9a614b8b5d3 100644 --- a/data/Leipzig/E531-dynamicFFFF.xml +++ b/data/Leipzig/E531-dynamicFFFF.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="925"> - + diff --git a/data/Leipzig/E532-dynamicFFFFF.xml b/data/Leipzig/E532-dynamicFFFFF.xml index cce0a5e65ff..a89b39938eb 100644 --- a/data/Leipzig/E532-dynamicFFFFF.xml +++ b/data/Leipzig/E532-dynamicFFFFF.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="1158"> - + diff --git a/data/Leipzig/E567-ornamentTurn.xml b/data/Leipzig/E567-ornamentTurn.xml index 409fcfa968c..8fc2883485e 100644 --- a/data/Leipzig/E567-ornamentTurn.xml +++ b/data/Leipzig/E567-ornamentTurn.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="468"> - + diff --git a/data/Leipzig/E568-ornamentTurnInverted.xml b/data/Leipzig/E568-ornamentTurnInverted.xml index 6f6550210fb..fbd88327cf2 100644 --- a/data/Leipzig/E568-ornamentTurnInverted.xml +++ b/data/Leipzig/E568-ornamentTurnInverted.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="468"> - + diff --git a/data/Leipzig/E56A-ornamentTurnUp.xml b/data/Leipzig/E56A-ornamentTurnUp.xml index 5080ed5688a..0757374e0f7 100644 --- a/data/Leipzig/E56A-ornamentTurnUp.xml +++ b/data/Leipzig/E56A-ornamentTurnUp.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="248"> - + diff --git a/data/Leipzig/E56B-ornamentTurnUpS.xml b/data/Leipzig/E56B-ornamentTurnUpS.xml index 2e7912f4e19..01b3c36be21 100644 --- a/data/Leipzig/E56B-ornamentTurnUpS.xml +++ b/data/Leipzig/E56B-ornamentTurnUpS.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="248"> - + diff --git a/data/Leipzig/E56E-ornamentTremblement.xml b/data/Leipzig/E56E-ornamentTremblement.xml index 3665869dfe4..93b0ffb1499 100644 --- a/data/Leipzig/E56E-ornamentTremblement.xml +++ b/data/Leipzig/E56E-ornamentTremblement.xml @@ -3,6 +3,6 @@ overflow="inherit" horiz-adv-x="711"> - + diff --git a/data/Leipzig/E901-mensuralGclefPetrucci.xml b/data/Leipzig/E901-mensuralGclefPetrucci.xml new file mode 100644 index 00000000000..d9d8c956684 --- /dev/null +++ b/data/Leipzig/E901-mensuralGclefPetrucci.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Leipzig/E904-mensuralFclefPetrucci.xml b/data/Leipzig/E904-mensuralFclefPetrucci.xml new file mode 100644 index 00000000000..00ae58f9e5f --- /dev/null +++ b/data/Leipzig/E904-mensuralFclefPetrucci.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/data/Leipzig/E909-mensuralCclefPetrucciPosMiddle.xml b/data/Leipzig/E909-mensuralCclefPetrucciPosMiddle.xml new file mode 100644 index 00000000000..87ec6d99729 --- /dev/null +++ b/data/Leipzig/E909-mensuralCclefPetrucciPosMiddle.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/fonts/Leipzig-5.2.sfd b/fonts/Leipzig-5.2.sfd index 5f040880a9a..467efa0d2eb 100644 --- a/fonts/Leipzig-5.2.sfd +++ b/fonts/Leipzig-5.2.sfd @@ -4,7 +4,7 @@ FullName: Leipzig FamilyName: Leipzig Weight: Regular Copyright: Created by Etienne Darbellay, Jean-Francois Marti and Laurent Pugin. \nThis font is licensed under the SIL Open Font License \\(http://scripts.sil.org/OFL\\).\nVersion 5.2.1 -UComments: "2014-03-21: Created.+AAoA-Version 5.2.0 - adding glyphs (dynamics, ornaments, mensural note heads, etc)+AAoA-Version 5.2.1 - adding repeats+AAoA-Version 5.2.2 - fixing size of some glpyhs+AAoA" +UComments: "2014-03-21: Created.+AAoA-Version 5.2.0 - adding glyphs (dynamics, ornaments, mensural note heads, etc)+AAoA-Version 5.2.1 - adding repeats+AAoA-Version 5.2.2 - fixing size of some glpyhs+AAoA-Version 5.2.3 - adding mensural clefs" Version: 5.2.1 ItalicAngle: 0 UnderlinePosition: -50 @@ -20,7 +20,7 @@ OS2Version: 0 OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 1 CreationTime: 1395388130 -ModificationTime: 1440762871 +ModificationTime: 1442493779 PfmFamily: 17 TTFWeight: 500 TTFWidth: 5 @@ -49,11 +49,11 @@ NameList: Adobe Glyph List DisplaySize: -72 AntiAlias: 1 FitToEm: 1 -WinInfo: 57510 18 9 +WinInfo: 59580 18 9 BeginPrivate: 0 EndPrivate TeXData: 1 0 0 346030 173015 115343 0 1048576 115343 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144 -BeginChars: 1114115 114 +BeginChars: 1114115 117 StartChar: uniE0A3 Encoding: 57507 57507 0 @@ -4302,7 +4302,7 @@ StartChar: uniE500 Encoding: 58624 58624 79 Width: 508 VWidth: 2048 -Flags: HWO +Flags: HW LayerCount: 2 Fore SplineSet @@ -5504,7 +5504,7 @@ StartChar: uniE101 Encoding: 57601 57601 111 Width: 508 VWidth: 2048 -Flags: HWO +Flags: HW LayerCount: 2 Fore SplineSet @@ -5603,5 +5603,232 @@ SplineSet 1092.67 -146 1087.67 -135 1087 -121 c 0 EndSplineSet EndChar + +StartChar: uniE901 +Encoding: 59649 59649 114 +Width: 596 +VWidth: 2048 +Flags: HW +LayerCount: 2 +Fore +SplineSet +183 747 m 4 + 196.334 754.333 210.667 758.333 226 759 c 132 + 241.334 759.667 255.667 757.667 269 753 c 132 + 282.333 748.333 293.333 740.333 302 729 c 132 + 310.667 717.661 316.333 705.328 319 692 c 4 + 321.667 676 317.333 656 306 632 c 132 + 294.667 608 281 590 265 578 c 4 + 256.333 571.333 250.333 565.333 247 560 c 132 + 243.667 554.667 241.667 548 241 540 c 4 + 241 534.667 242 530 244 526 c 132 + 246 522 248.333 519.333 251 518 c 132 + 253.667 516.663 258.667 511.996 266 504 c 132 + 273.335 496 280.668 487 288 477 c 4 + 301.333 460.332 309.333 447.666 312 439 c 132 + 314.667 430.333 317.333 414.333 320 391 c 5 + 322 360.333 321.333 338.666 318 326 c 132 + 314.667 313.333 305.333 298.666 290 282 c 4 + 281.332 272 275.665 263.667 273 257 c 132 + 270.333 250.333 269 243.667 269 237 c 5 + 270.333 224.333 277.333 215.333 290 210 c 132 + 302.667 204.667 324.667 202 356 202 c 4 + 378 202 393.333 203 402 205 c 4 + 410.667 206.333 419.667 210 429 216 c 6 + 449 230 l 5 + 437 213 l 6 + 429 201.667 426.333 190.333 429 179 c 6 + 432 162 l 5 + 296 162 l 6 + 263.333 162 238.333 161.667 221 161 c 132 + 203.667 160.333 187.333 159.667 172 159 c 132 + 156.667 158.333 144.667 156 136 152 c 132 + 127.332 148 119.666 144 113 140 c 132 + 106.332 136 98.666 129.333 90 120 c 5 + 68.667 100 54.667 74.333 48 43 c 132 + 41.333 11.667 42.333 -20 51 -52 c 4 + 55.667 -69.333 64.334 -85.333 77 -100 c 132 + 89.667 -114.667 104.333 -126.667 121 -136 c 132 + 137.667 -145.333 156 -153 176 -159 c 132 + 196 -165 216.333 -167 237 -165 c 132 + 257.667 -163 277.333 -158.333 296 -151 c 4 + 316.667 -142.334 331.333 -131.667 340 -119 c 132 + 348.667 -106.333 354.667 -87 358 -61 c 4 + 360 -43 360.333 -29.667 359 -21 c 132 + 357.667 -12.333 354 -1.33301 348 12 c 4 + 340 28 330.333 40.667 319 50 c 132 + 307.667 59.333 298 62.667 290 60 c 4 + 286 58 283.667 54.667 283 50 c 132 + 282.333 45.333 282.333 37.667 283 27 c 5 + 285.667 9.66699 283.333 -8.33301 276 -27 c 132 + 268.667 -45.667 258.667 -59.333 246 -68 c 132 + 233.333 -76.667 220 -81 206 -81 c 4 + 194 -81 178.667 -76 160 -66 c 132 + 141.333 -56 128.333 -44 121 -30 c 4 + 109 -6 108.333 17.667 119 41 c 132 + 129.667 64.333 149.333 82.667 178 96 c 4 + 194 104 210 108 226 108 c 132 + 242 108 264.667 104.667 294 98 c 4 + 320.667 92 341 83 355 71 c 132 + 369 59 381 39.333 391 12 c 4 + 396.333 -1.33301 399.333 -12 400 -20 c 132 + 400.658 -28 399.325 -41 396 -59 c 132 + 392.667 -77 389 -89.667 385 -97 c 132 + 381 -104.333 373.667 -112.667 363 -122 c 4 + 346.333 -136.667 326.333 -149.667 303 -161 c 4 + 287 -169 274 -173.667 264 -175 c 132 + 254 -176.331 236 -176.664 210 -176 c 5 + 158.667 -173.333 116.667 -163 84 -145 c 132 + 51.333 -127 25.333 -99 6 -61 c 4 + -5.33301 -38.333 -11.333 -17.333 -12 2 c 132 + -12.667 21.333 -8 44.333 2 71 c 4 + 15.333 106.333 31.333 133 50 151 c 132 + 68.667 169 96 183.667 132 195 c 4 + 148.667 200.333 166.333 208.333 185 219 c 132 + 203.667 229.667 217 240 225 250 c 5 + 235 260.667 247 278 261 302 c 4 + 271 318.667 277 331 279 339 c 132 + 281 347 281.333 362.333 280 385 c 4 + 278 415.667 271.667 439 261 455 c 4 + 251.667 469 239.333 481.333 224 492 c 132 + 208.667 502.667 195 508 183 508 c 132 + 171 508 157 498.667 141 480 c 132 + 125 461.333 114 442.333 108 423 c 4 + 104 408.333 102.667 395.333 104 384 c 4 + 105.333 368.667 110.333 350 119 328 c 4 + 119.667 325.333 119 321.333 117 316 c 132 + 115 310.667 112.333 305.667 109 301 c 4 + 100.332 291 92.332 287.667 85 291 c 132 + 77.666 294.333 68.333 306 57 326 c 4 + 40.333 354.667 37.667 383.667 49 413 c 4 + 53 423 65 437.667 85 457 c 132 + 105 476.333 122.333 490 137 498 c 4 + 143.667 502 148.333 506.333 151 511 c 132 + 153.667 515.667 155 522.333 155 531 c 4 + 155 545.671 153 554.338 149 557 c 4 + 143 560.333 136 572.667 128 594 c 132 + 120 615.333 115.667 632 115 644 c 5 + 115 666.667 120.333 686.334 131 703 c 132 + 141.667 719.67 159 734.336 183 747 c 4 +277 715 m 4 + 268.333 723.667 255.333 728.667 238 730 c 132 + 220.667 731.333 204.667 729.667 190 725 c 5 + 178.667 719.667 169.333 711.667 162 701 c 132 + 154.667 690.333 150.667 679 150 667 c 132 + 149.333 655 150 643 152 631 c 132 + 154 619 159.333 608.667 168 600 c 132 + 176.667 591.333 187 586 199 584 c 4 + 216.334 580.685 230.667 581.351 242 586 c 132 + 253.333 590.667 264.333 600.667 275 616 c 4 + 283.667 628 289 637.333 291 644 c 132 + 293 650.672 293.333 660.338 292 673 c 4 + 291.319 681.667 289.653 690 287 698 c 132 + 284.333 706 281 711.667 277 715 c 4 +233 59 m 4 + 225.667 64.333 214 67.333 198 68 c 132 + 182 68.667 170.667 67.333 164 64 c 5 + 157.333 59.333 152 51.333 148 40 c 132 + 144 28.667 142 16 142 2 c 4 + 142 -9.33301 143.333 -18 146 -24 c 4 + 146.667 -26.667 152 -33.667 162 -45 c 4 + 170.667 -55 182.667 -61.333 198 -64 c 4 + 210.667 -66 222 -63.667 232 -57 c 132 + 242 -50.333 248.667 -40.333 252 -27 c 4 + 255.333 -13 255 3.33301 251 22 c 132 + 247 40.667 241 53 233 59 c 4 +EndSplineSet +EndChar + +StartChar: uniE904 +Encoding: 59652 59652 115 +Width: 677 +VWidth: 2048 +Flags: HW +LayerCount: 2 +Fore +SplineSet +337 -808 m 1 + 312 -808 l 1 + 312 -115 l 1 + 25 -115 l 1 + 25 -208 l 1 + 0 -208 l 1 + 0 209 l 1 + 25 209 l 1 + 25 123 l 1 + 312 123 l 1 + 312 209 l 1 + 337 209 l 1 + 337 -808 l 1 +312 -50 m 1 + 312 58 l 1 + 25 58 l 1 + 25 -50 l 1 + 312 -50 l 1 +518 -290 m 1 + 548 -280 l 1 + 548 -883 l 1 + 518 -883 l 1 + 518 -290 l 1 +535 325 m 1 + 677 147 l 1 + 535 -31 l 1 + 391 147 l 1 + 535 325 l 1 +508 249 m 1 + 454 182 l 1 + 566 44 l 1 + 618 110 l 1 + 508 249 l 1 +535 37 m 1 + 677 -141 l 1 + 535 -319 l 1 + 391 -141 l 1 + 535 37 l 1 +508 -39 m 1 + 454 -106 l 1 + 566 -244 l 1 + 618 -178 l 1 + 508 -39 l 1 +EndSplineSet +EndChar + +StartChar: uniE909 +Encoding: 59657 59657 116 +Width: 309 +VWidth: 2048 +Flags: HW +LayerCount: 2 +Fore +SplineSet +0 595 m 1 + 28 595 l 1 + 28 353 l 1 + 280 353 l 1 + 280 595 l 1 + 309 595 l 1 + 309 64 l 1 + 28 64 l 1 + 28 -64 l 1 + 309 -64 l 1 + 309 -602 l 1 + 280 -602 l 1 + 280 -355 l 1 + 28 -355 l 1 + 28 -602 l 1 + 0 -602 l 1 + 0 595 l 1 +280 255 m 1 + 28 255 l 1 + 28 164 l 1 + 280 164 l 1 + 280 255 l 1 +280 -172 m 1 + 28 -172 l 1 + 28 -263 l 1 + 280 -263 l 1 + 280 -172 l 1 +EndSplineSet +EndChar EndChars EndSplineFont diff --git a/fonts/Leipzig.svg b/fonts/Leipzig.svg index 49f630b76ff..71ab0f2ac33 100644 --- a/fonts/Leipzig.svg +++ b/fonts/Leipzig.svg @@ -5,11 +5,11 @@ Version 5.2.0 - adding glyphs (dynamics, ornaments, mensural note heads, etc) Version 5.2.1 - adding repeats Version 5.2.2 - fixing size of some glpyhs - +Version 5.2.3 - adding mensural clefs --> -Created by FontForge 20120731 at Fri Aug 28 13:54:39 2015 +Created by FontForge 20120731 at Thu Sep 17 14:43:38 2015 By laurent Created by Etienne Darbellay, Jean-Francois Marti and Laurent Pugin. This font is licensed under the SIL Open Font License \(http://scripts.sil.org/OFL\). @@ -279,14 +279,14 @@ d="M0 -0c49 0 97.5 -2.26367 135.5 4.73633c206 95 258.5 264.264 263.5 271.264c0 1 +c-4 -3.33301 -8.33301 -5.33301 -13 -6s-10.333 -0.666992 -17 0c-6 1.33301 -10.333 5 -13 11s-4.66701 12.667 -6 20c0 12 2.33299 22.667 7 32s12 17.333 22 24l14 10c0 8.66699 -6 14 -18 16c-13.333 1.32999 -24.667 -1.33701 -34 -8 +c-9.33299 -6.66699 -19 -21 -29 -43c-4.66701 -12 -10.333 -29.667 -17 -53s-11.333 -40 -14 -50h77v-40h-85c-12 -68.667 -29 -137.333 -51 -206c-18 -55.333 -35.333 -99 -52 -131c-13.333 -26 -27 -47 -41 -63c-24.667 -28.667 -50 -43 -76 -43 +c-24.666 0 -43.333 9.66701 -56 29c-10 15.333 -15 33.333 -15 54c0 16.667 4 32.667 12 48c4.667 7.333 10.333 13 17 17s13.333 6 20 6c8.667 0 15.667 -4 21 -12s9 -15.333 11 -22s3 -12.333 3 -17c0 -9.33299 -2.333 -17.333 -7 -24 +c-4.6641 -6.66701 -9.3301 -13.667 -14 -21c-4.6641 -7.33299 -8.3301 -12 -11 -14z" /> +d="M508 242l-362 -484h-146l362 484h146zM52 118c0 13.333 4.333 24.667 13 34s19.333 14.333 32 15c14 0 25.667 -4 35 -12c9.33299 -8 14.333 -19 15 -33c0 -13.333 -4.33299 -24.667 -13 -34c-8.667 -9.333 -19.333 -14.333 -32 -15c-14 0 -25.667 4 -35 12 +s-14.333 19 -15 33zM361 -121c0 13.333 4.33301 24.667 13 34s19.334 14.333 32 15c14 0 25.667 -4 35 -12s14.333 -19 15 -33c0 -13.333 -4.33301 -24.667 -13 -34s-19.333 -14.333 -32 -15c-14 0 -25.667 4 -35 12s-14.333 19 -15 33z" /> +d="M481 220h-83c-8.66699 -55.333 -22.333 -114.333 -41 -177s-35.667 -109.667 -51 -141c-15.333 -31.333 -32 -58 -50 -80c-16 -21.333 -37 -35.666 -63 -43l-19 -2c-21.333 0 -37.333 8.66701 -48 26c-4 5.33299 -7 10.333 -9 15c-2 4.666 -4 10.333 -6 17 +c-2 6.666 -3 16.333 -3 29c0 18.667 4 32.667 12 42s18.667 17.667 32 25c5.33299 0 10 -1 14 -3s8.33299 -6 13 -12c7.33299 -9.333 11 -20.667 11 -34c0 -14.667 -10.667 -36.333 -32 -65c0 -4.66701 3 -7 9 -7c34 0 61.333 46.333 82 139l7 29l13 60l22 102l17 80h-161 +c-8 -53.333 -22.333 -113.333 -43 -180c-12 -39.333 -20.667 -66 -26 -80c-8 -21.333 -16.333 -40.667 -25 -58c-32.667 -72 -69.333 -113 -110 -123l-18 -2c-21.3311 0 -37.664 8.66701 -49 26c-5.33299 6 -10.333 15.333 -15 28c-0.667007 5.33299 -1.33299 10.333 -2 15 +s-1.33299 10.667 -2 18c1.33299 11.333 2.66701 20.333 4 27s4.33299 13 9 19c6.667 8.667 17.667 15.667 33 21c10.6621 0 19.3281 -5 26 -15c6.6572 -10 10.3242 -21.333 11 -34c0 -7.333 -0.667 -12.667 -2 -16c-1.333 -3.332 -2.333 -5.666 -3 -7l-14 -23l-15 -19 +c0 -4.66701 3.333 -7 10 -7c11.333 0 21.667 5 31 15c3.333 3.33299 7 8 11 14s8 13 12 21l14 36l15 53l19 86l22 105l17 80h-57v38h70c9.333 31.334 22 60.667 38 88s37.667 51 65 71c24.667 16.667 52.333 25 83 25c15.333 0 27.333 -6.33301 36 -19s13 -28.334 13 -47 +c0 -18.667 -4.33301 -35.334 -13 -50c-8.66599 -14.668 -21.333 -23.335 -38 -26c-16.667 0 -26 10.667 -28 32c0 11.335 3.33299 23.668 10 37c6.66701 11.335 15.667 19.668 27 25c3.33301 2.66699 5 4.66699 5 6c-3.33301 4.66699 -5.66699 7.66699 -7 9 +c-4.66699 3.33301 -10.667 5 -18 5c-22 0 -40 -15.667 -54 -47s-25 -67 -33 -107h164c13.333 49.333 36.667 92 70 128s72 54 116 54c8 0 15 -1.33301 21 -4s11 -8 15 -16c2.66699 -3.33301 5.33301 -9 8 -17s4.33301 -17.667 5 -29c0 -18.667 -4.33301 -35 -13 -49 +s-21 -23 -37 -27c-18 0 -28 10.667 -30 32c0 6 1 12 3 18s4.66699 12 8 18s7 11 11 15s9 7.66699 15 11c3.33301 2.66699 5 4.66699 5 6l-6 9c-4.66699 3.33301 -10.333 5 -17 5c-37.333 0 -66.667 -52 -88 -156h75v-38z" /> +d="M597 -69c21.386 0 35 -30.9219 35 -51c0 -20.113 -12.602 -31.813 -21 -45c-4.664 -7.33299 -8.33002 -12 -11 -14c-5.521 -7.362 -1.33801 -9.966 9 -11c35.075 0 54.221 54.5 67 89c6.66699 18 11.667 35.333 15 52c20.706 88.2939 38.664 179.336 58 269h-143 +c-7 -44 -15 -84 -26 -121c-18 -75 -39 -141 -66 -197c-15 -28 -31 -55 -50 -79c-16 -21 -36 -36 -61 -44l-18 -2c-35 0 -53 23 -62 54c-4 10 -6 21 -6 33c4 37 15 57 46 67c23 0 35 -23 36 -47c0 -8 -4 -23 -9 -31l-10 -15c-7 -10 -8 -12 -13 -21c0 -5 3 -7 10 -7 +c19 0 35 14 48 42c13 32 23 60 33 97c14 62 27 123 41 185l18 86h-140c-14 -89 -60 -256 -93 -318c-15 -31 -30 -57 -47 -79s-38 -37 -65 -44l-18 -2c-44 0 -67 40 -67 87c0 39 18 53 45 67c6 0 11 -1 14 -4c14.846 -5.9385 23 -25.0508 23 -45c0 -15 -11 -36 -32 -65 +c0 -5 3 -7 9 -7c34 0 61 46 82 139c21.424 88.7559 39.772 180.774 59 271h-141c-13 -85 -62 -255 -93 -318c-33 -72 -70 -113 -110 -123l-19 -2c-35 0 -51 24 -63 54l-5 33c5 39 13 55 46 67c23 0 38 -26 38 -49c0 -8 -2 -16 -6 -23l-14 -23l-14 -19c0 -5 3 -7 10 -7 +c11 0 21 5 30 15c18 15 26 46 37 71l15 53c17 77 34 155 50 233c3 13 6 26 9 38h-57v38h69c9 33 23 62 40 89c17 28 38 51 63 70c25 17 53 25 83 25c33 0 49 -30 49 -66c0 -38 -19 -70 -50 -76c-17 0 -27 11 -29 32c0 27 17 53 37 62c3 0 5 2 5 6l-6 9c-5 3 -11 5 -18 5 +c-23 0 -41 -16 -55 -48s-25 -67 -32 -106h144c23 84 85 182 185 182c36 0 47 -31 49 -66c0 -18 -4 -35 -13 -51c-8 -12 -20 -20 -37 -25c-18 0 -28 11 -30 32c0 29 18 51 37 62c3 0 5 2 5 6c-4 10 -11 14 -23 14c-37 0 -67 -52 -88 -156h144c15 49 39 93 72 132 +c31 36 69 54 114 54c34 0 49 -36 49 -70c0 -37 -19 -68 -51 -74c-16 0 -25 11 -27 32c0 26 18 52 35 62c4 0 6 2 6 6c-5 9 -11 14 -24 14c-37 0 -67 -52 -88 -156h146c13.429 37.847 22.957 64.661 40 91c20.666 30 42.333 53 65 69s47.667 24 75 24 +c28.318 0 45.6 -13.674 51 -38l4 -16c0 -33.139 -1 -36.007 -13 -60c-3.138 -7.06 -17.383 -25.054 -31 -27c-4.66699 -0.666992 -10.333 -0.666992 -17 0c-12.606 2.80099 -16.566 17.612 -19 31c0 27.28 11.325 44.216 29 56l14 10c0 8.66699 -6 14 -18 16 +c-13.333 1.32999 -24.667 -1.33701 -34 -8c-9.33301 -6.66699 -19 -21 -29 -43c-6.914 -17.778 -25.9 -83.879 -31 -103h77v-40h-85c-19.014 -108.805 -60.061 -254.559 -103 -337c-23.657 -46.132 -64.302 -106 -117 -106c-44.617 0 -71 36.683 -71 83 +c0 31.822 15.31 71 49 71z" /> +d="M983 220l-44 -208l-14 -61c-3.33301 -16.667 -8.33301 -34 -15 -52s-13.333 -34 -20 -48c-12.667 -27.333 -28.333 -41 -47 -41c-6.66699 0.667007 -10.333 2 -11 4s0 4.33299 2 7c2.66998 2 6.336 6.66701 11 14c4.66998 7.33299 9.336 14.333 14 21 +c4.66699 6.66701 7 14.667 7 24c0 4.667 -1 10.333 -3 17s-5.66699 14 -11 22s-12.333 12 -21 12c-6.66699 0 -13.333 -2 -20 -6s-12.333 -9.667 -17 -17c-8 -15.333 -12 -31.333 -12 -48c0 -20.667 5 -38.667 15 -54c12.667 -19.333 31.334 -29 56 -29 +c26 0 51.333 14.333 76 43c14 16 27.667 37 41 63c16.67 32 34 75.667 52 131c22 68.667 39 137.333 51 206h85v40h-77c2.67004 10 7.32996 26.667 14 50s12.33 41 17 53c10 22 19.67 36.333 29 43c9.32996 6.66299 20.67 9.32999 34 8c12 -2 18 -7.33301 18 -16l-14 -10 +c-10 -6.66699 -17.33 -14.667 -22 -24s-7 -20 -7 -32c1.32996 -7.33301 3.32996 -14 6 -20s7 -9.66699 13 -11c6.67004 -0.666992 12.33 -0.666992 17 0s9 2.66699 13 6c9.32996 8 15.33 15 18 21c6 12 9.67004 21.333 11 28c1.32996 6.66599 2 17.333 2 32l-4 16 +c-1.32996 6 -4.32996 12.333 -9 19c-6.67004 8.66699 -13 14 -19 16s-13.67 3 -23 3c-27.33 0 -52.33 -8 -75 -24s-44.33 -39 -65 -69c-7.32996 -11.333 -14.67 -26 -22 -44c-4.66998 -10.667 -10.67 -26.333 -18 -47h-148c5.09998 19.121 24.086 87.222 31 105 +c10 22 19.667 36.333 29 43c9.33301 6.66299 20.667 9.32999 34 8c12 -2 18 -7.33301 18 -16l-14 -10c-17.675 -11.784 -29 -28.72 -29 -56c2.43402 -13.388 6.39398 -28.199 19 -31c6.66699 -0.666992 12.333 -0.666992 17 0c13.617 1.94601 27.862 19.94 31 27 +c12 23.993 13 26.861 13 60l-4 16c-5.40002 24.326 -22.682 38 -51 38c-27.333 0 -52.333 -8 -75 -24s-44.334 -39 -65 -69c-17.043 -26.339 -26.571 -53.153 -40 -91h-146c21 104 51 156 88 156c13 0 19 -5 24 -14c0 -4 -2 -6 -6 -6c-17 -10 -35 -36 -35 -62 +c2 -21 11 -32 27 -32c32 6 51 37 51 74c0 34 -15 70 -49 70c-45 0 -83 -18 -114 -54c-33 -39 -57 -83 -72 -132h-144c21 104 51 156 88 156c12 0 19 -4 23 -14c0 -4 -2 -6 -5 -6c-19 -11 -37 -33 -37 -62c2 -21 12 -32 30 -32c17 5 29 13 37 25c9 16 13 33 13 51 +c-2 35 -13 66 -49 66c-100 0 -162 -98 -185 -182h-144c7 39 18 74 32 106s32 48 55 48c7 0 13 -2 18 -5l6 -9c0 -4 -2 -6 -5 -6c-20 -9 -37 -35 -37 -62c2 -21 12 -32 29 -32c31 6 50 38 50 76c0 36 -16 66 -49 66c-30 0 -58 -8 -83 -25c-25 -19 -46 -42 -63 -70 +c-17 -27 -31 -56 -40 -89h-69v-38h57c-3 -12 -6 -25 -9 -38c-16 -78 -33 -156 -50 -233l-15 -53c-11 -25 -19 -56 -37 -71c-9 -10 -19 -15 -30 -15c-7 0 -10 2 -10 7l14 19l14 23c4 7 6 15 6 23c0 23 -15 49 -38 49c-33 -12 -41 -28 -46 -67l5 -33c12 -30 28 -54 63 -54 +l19 2c40 10 77 51 110 123c31 63 80 233 93 318h141c-19.228 -90.226 -37.576 -182.244 -59 -271c-21 -93 -48 -139 -82 -139c-6 0 -9 2 -9 7c21 29 32 50 32 65c0 19.9492 -8.15401 39.0615 -23 45c-3 3 -8 4 -14 4c-27 -14 -45 -28 -45 -67c0 -47 23 -87 67 -87l18 2 +c27 7 48 22 65 44s32 48 47 79c33 62 79 229 93 318h140l-18 -86c-14 -62 -27 -123 -41 -185c-10 -37 -20 -65 -33 -97c-13 -28 -29 -42 -48 -42c-7 0 -10 2 -10 7c5 9 6 11 13 21l10 15c5 8 9 23 9 31c-1 24 -13 47 -36 47c-31 -10 -42 -30 -46 -67c0 -12 2 -23 6 -33 +c9 -31 27 -54 62 -54l18 2c25 8 45 23 61 44c19 24 35 51 50 79c27 56 48 122 66 197c11 37 19 77 26 121h143c-19.336 -89.664 -37.294 -180.706 -58 -269c-3.33301 -16.667 -8.33301 -34 -15 -52c-12.779 -34.5 -31.925 -89 -67 -89c-10.338 1.034 -14.521 3.638 -9 11 +c2.66998 2 6.336 6.66701 11 14c8.39801 13.187 21 24.887 21 45c0 20.0781 -13.614 51 -35 51c-33.69 0 -49 -39.178 -49 -71c0 -46.317 26.383 -83 71 -83c52.698 0 93.343 59.868 117 106c42.939 82.4414 83.986 228.195 103 337h144z" /> +d="M153 214h-37c-10 -4 -18.667 -14 -26 -30c-3.333 -7.33299 -8 -12 -14 -14c-4 1.33299 -10.667 10 -20 26c-4.667 8.66701 -11.333 14.667 -20 18h-36l76 -214z" /> +d="M153 -214h-37c-10 4 -18.667 14 -26 30c-3.333 7.33299 -8 12 -14 14c-4 -1.33299 -10.667 -10 -20 -26c-4.667 -8.66701 -11.333 -14.667 -20 -18h-36l76 214z" /> +d="M468 126c0 69.355 -37.514 116.042 -106 118c-22.667 0 -43.667 -5 -63 -15c-20.602 -12.677 -44.791 -32.051 -64 -49c-22.561 -23.772 -45.814 -46.853 -69 -70c-16 -14 -31 -25 -45 -33s-26.333 -12.333 -37 -13c-19.7583 0 -27.7186 13.5628 -37 28l-12 26 +c-3.333 9.333 -5 15.667 -5 19v8c0 28.667 13.333 43 40 43l9 -2l11 -9l7 -7c6.447 -4.03 14.151 -8 24 -8c17.333 0 28.333 9.33299 33 28c0 34.187 -26.771 52.58 -58 54c-22.8296 0 -25.7106 0.339996 -41 -8c-32.9816 -13.582 -55 -53.578 -55 -97 +c0 -50.4509 20.6276 -86.763 49 -114c18 -14.667 36.333 -23 55 -25c26 0 51 7 75 21c8.66701 5.333 14.667 9 18 11l18 15c8.638 7.1975 25.24 22.1328 33 31l65 67l10 9l22 16c13.333 7.33299 25.667 11 37 11c37.101 0 55 -35.871 55 -70c0 -27.9599 -11.97 -55 -39 -55 +c-6.353 2.1187 -10.691 4.7935 -17 9l-18 13c-3.33301 2.667 -9.33301 4 -18 4c-19.451 0 -29.676 -17.2405 -32 -37c0 -28.051 28.285 -41.7132 58 -44c43.494 0 69.733 31.4674 85 62c8.66699 17.333 12.667 38.333 12 63z" /> +d="M468 118c0 -69.3555 -37.514 -116.042 -106 -118c-22.667 0 -43.667 5 -63 15c-20.603 12.6768 -44.791 32.0508 -64 49c-22.562 23.7725 -45.813 46.854 -69 70c-16 14 -31 25 -45 33s-26.333 12.333 -37 13c-19.7578 0 -27.7188 -13.562 -37 -28l-12 -26 +c-3.333 -9.333 -5 -15.667 -5 -19v-8c0 -28.667 13.333 -43 40 -43l9 2l11 9l7 7c6.447 4.0293 14.151 8 24 8c17.333 0 28.333 -9.333 33 -28c0 -34.1875 -26.771 -52.5801 -58 -54c-22.8301 0 -25.7109 -0.339844 -41 8c-32.9814 13.582 -55 53.5781 -55 97 +c0 50.451 20.6279 86.763 49 114c18 14.667 36.333 23 55 25c26 0 51 -7 75 -21c8.66701 -5.33299 14.667 -9 18 -11l18 -15c8.638 -7.19701 25.24 -22.133 33 -31l65 -67l10 -9l22 -16c13.333 -7.333 25.667 -11 37 -11c37.102 0 55 35.8711 55 70 +c0 27.96 -11.971 55 -39 55c-6.354 -2.119 -10.691 -4.79401 -17 -9l-18 -13c-3.33301 -2.66701 -9.33301 -4 -18 -4c-19.451 0 -29.676 17.24 -32 37c0 28.051 28.285 41.713 58 44c43.493 0 69.732 -31.468 85 -62c8.66699 -17.333 12.667 -38.333 12 -63z" /> +d="M710 134l-109 -127c-2.66699 -3.33333 -5 -5.33333 -7 -6l-6 -2c-5.35101 2 -8.68402 3.66667 -10 5l-89 78c-4.67001 4.6667 -10.337 7.3333 -17 8c-4 -1.3333 -6.66699 -2.6667 -8 -4l-66 -79c-3.33301 -5.33333 -7.66699 -8 -13 -8l-11 5l-89 78 +c-6 4.6667 -11.333 7.3333 -16 8c-4 -1.3333 -6.66699 -2.6667 -8 -4l-67 -79c-5.33299 -5.33333 -10 -8 -14 -8c-2 0 -5.33299 1.66667 -10 5l-88 78c-5.3333 4.6667 -11 7.3333 -17 8c-4.6667 -1.3333 -7.3333 -2.6667 -8 -4l-57 -68v49l108 127l10 4 +c0.667 0 2 -0.332993 4 -1s6 -3 12 -7l88 -78l10 -5c4 0 8.66701 2.667 14 8l67 79c3.33301 2.66701 6 4 8 4c4.66699 0 10 -2.66701 16 -8l89 -78l11 -5l6 1l7 7l67 79c3.33301 2.66701 5.66699 4 7 4c4 -1.334 6.66699 -2.66701 8 -4l7 -6l89 -77 +c3.33301 -3.333 7 -5 11 -5s8.33301 2.667 13 8l58 67v-47z" /> +d="M126 468c69.355 0 116.042 -37.514 118 -106c0 -22.667 -5 -43.667 -15 -63c-12.677 -20.603 -32.051 -44.791 -49 -64c-23.772 -22.562 -46.854 -45.813 -70 -69c-14 -16 -25 -31 -33 -45s-12.333 -26.333 -13 -37c0 -19.7578 13.5625 -27.7188 28 -37l26 -12 +c9.333 -3.333 15.667 -5 19 -5h8c28.667 0 43 13.333 43 40l-2 9l-9 11l-7 7c-4.02901 6.447 -8 14.151 -8 24c0 17.333 9.33299 28.333 28 33c34.188 0 52.58 -26.771 54 -58c0 -22.8301 0.339996 -25.7109 -8 -41c-13.582 -32.9814 -53.578 -55 -97 -55 +c-50.4512 0 -86.7627 20.6279 -114 49c-14.667 18 -23 36.333 -25 55c0 26 7 51 21 75c5.333 8.66701 9 14.667 11 18l15 18c7.1973 8.638 22.1328 25.24 31 33l67 65l9 10l16 22c7.33299 13.333 11 25.667 11 37c0 37.102 -35.871 55 -70 55c-27.96 0 -55 -11.971 -55 -39 +c2.1191 -6.354 4.7939 -10.691 9 -17l13 -18c2.667 -3.33301 4 -9.33301 4 -18c0 -19.451 -17.2402 -29.676 -37 -32c-28.0508 0 -41.7129 28.285 -44 58c0 43.493 31.4678 69.732 62 85c17.333 8.66699 38.333 12.667 63 12z" /> +d="M118 468c-69.3555 0 -116.042 -37.514 -118 -106c0 -22.667 5 -43.667 15 -63c12.6768 -20.603 32.0508 -44.791 49 -64c23.7725 -22.562 46.854 -45.813 70 -69c14 -16 25 -31 33 -45s12.333 -26.333 13 -37c0 -19.7578 -13.562 -27.7188 -28 -37l-26 -12 +c-9.333 -3.333 -15.667 -5 -19 -5h-8c-28.667 0 -43 13.333 -43 40l2 9l9 11l7 7c4.0293 6.447 8 14.151 8 24c0 17.333 -9.333 28.333 -28 33c-34.1875 0 -52.5801 -26.771 -54 -58c0 -22.8301 -0.339844 -25.7109 8 -41c13.582 -32.9814 53.5781 -55 97 -55 +c50.451 0 86.763 20.6279 114 49c14.667 18 23 36.333 25 55c0 26 -7 51 -21 75c-5.33299 8.66701 -9 14.667 -11 18l-15 18c-7.19701 8.638 -22.133 25.24 -31 33l-67 65l-9 10l-16 22c-7.333 13.333 -11 25.667 -11 37c0 37.102 35.8711 55 70 55 +c27.96 0 55 -11.971 55 -39c-2.119 -6.354 -4.79401 -10.691 -9 -17l-13 -18c-2.66701 -3.33301 -4 -9.33301 -4 -18c0 -19.451 17.24 -29.676 37 -32c28.051 0 41.713 28.285 44 58c0 43.493 -31.468 69.732 -62 85c-17.333 8.66699 -38.333 12.667 -63 12z" /> +d="M750 242l-362 -484h-146l362 484h146zM508 242l-362 -484h-146l362 484h146zM52 118c0 13.333 4.333 24.667 13 34s19.333 14.333 32 15c14 0 25.667 -4 35 -12c9.33299 -8 14.333 -19 15 -33c0 -13.333 -4.33299 -24.667 -13 -34c-8.667 -9.333 -19.333 -14.333 -32 -15 +c-14 0 -25.667 4 -35 12s-14.333 19 -15 33zM603 -121c0 13.333 4.33301 24.667 13 34s19.334 14.333 32 15c14 0 25.667 -4 35 -12s14.333 -19 15 -33c0 -13.333 -4.33301 -24.667 -13 -34s-19.333 -14.333 -32 -15c-14 0 -25.667 4 -35 12s-14.333 19 -15 33z" /> +d="M1234 242l-362 -484h-146l362 484h146zM992 242l-362 -484h-146l362 484h146zM750 242l-362 -484h-146l362 484h146zM508 242l-362 -484h-146l362 484h146zM52 118c0 13.333 4.333 24.667 13 34s19.333 14.333 32 15c14 0 25.667 -4 35 -12c9.33299 -8 14.333 -19 15 -33 +c0 -13.333 -4.33299 -24.667 -13 -34c-8.667 -9.333 -19.333 -14.333 -32 -15c-14 0 -25.667 4 -35 12s-14.333 19 -15 33zM1087 -121c0 13.333 4.32996 24.667 13 34s19.33 14.333 32 15c14 0 25.67 -4 35 -12s14.33 -19 15 -33c0 -13.333 -4.32996 -24.667 -13 -34 +s-19.33 -14.333 -32 -15c-14 0 -25.67 4 -35 12s-14.33 19 -15 33z" /> + + + diff --git a/fonts/supported.xsl b/fonts/supported.xsl index 38373b1a7ae..6a07aa094ab 100644 --- a/fonts/supported.xsl +++ b/fonts/supported.xsl @@ -2124,15 +2124,15 @@ Medieval and Renaissance clefs - + - + - + U+E90F diff --git a/include/vrv/smufl.h b/include/vrv/smufl.h index 8cdc759e804..7a0f6b8e1f1 100644 --- a/include/vrv/smufl.h +++ b/include/vrv/smufl.h @@ -125,6 +125,9 @@ enum { SMUFL_E888_tuplet8 = 0xE888, SMUFL_E889_tuplet9 = 0xE889, SMUFL_E88A_tupletColon = 0xE88A, + SMUFL_E901_mensuralGclefPetrucci = 0xE901, + SMUFL_E904_mensuralFclefPetrucci = 0xE904, + SMUFL_E909_mensuralCclefPetrucciPosMiddle = 0xE909, SMUFL_E938_mensuralNoteheadSemibrevisBlack = 0xE938, SMUFL_E939_mensuralNoteheadSemibrevisVoid = 0xE939, SMUFL_E93C_mensuralNoteheadMinimaWhite = 0xE93C, @@ -132,7 +135,7 @@ enum { }; /** The number of glyphs for verification **/ -#define SMUFL_COUNT 107 +#define SMUFL_COUNT 110 } // vrv namespace From 6d7362e55b14c4d8279a9431133ebf40a00dc5ee Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 17 Sep 2015 14:45:56 +0200 Subject: [PATCH 25/85] Finalizing --- include/vrv/style.h | 2 +- src/view_floating.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vrv/style.h b/include/vrv/style.h index f6bc0a177c9..47904b85b2c 100644 --- a/include/vrv/style.h +++ b/include/vrv/style.h @@ -141,7 +141,7 @@ namespace vrv { // the maximum angle of a slur #define TEMP_STYLE_SLUR_MAX_SLOPE (45 * M_PI / 180) -#define TEMP_STYLE_SLUR_CURVE_FACTOR 10 // a factor for allow more (0) or less (100) curved slurs +#define TEMP_STYLE_SLUR_CURVE_FACTOR 5 // a factor for allow more (0) or less (100) curved slurs #define TEMP_STYLE_SLUR_HEIGHT_FACTOR 8 // high value means flatter slurs #define TEMP_STYLE_SLUR_CONTROL_POINT_FACTOR 5 // higher value means more curved at the end diff --git a/src/view_floating.cpp b/src/view_floating.cpp index ad0547143d2..d44b8107be4 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -475,7 +475,7 @@ float View::AdjustSlur(Slur *slur, Staff *staff, int layerN, bool up, Point poi if (!spanningContentPoints.empty()) { AdjustSlurCurve(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, slurAngle ); // Use the adjusted control points for ajusting the position (p1, p2 and angle will be updated) - AdjustSlurPosition(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, &slurAngle, false ); + AdjustSlurPosition(slur, &spanningContentPoints, p1, &rotatedP2, &adjustedRotatedC1, &adjustedRotatedC2, up, &slurAngle, true ); // Now readjust the curvature with the new p1 and p2 with the original control points GetControlPoints(p1, &rotatedP2, &rotatedC1, &rotatedC2, up, height, staff->m_drawingStaffSize); From 44941c9138200bc336b7ff979b509caf08896c1f Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 17 Sep 2015 22:43:53 +0200 Subject: [PATCH 26/85] Fixing keySig and meterSig element alignment and grace notes within beams --- src/layerelement.cpp | 10 ++++++++-- src/note.cpp | 8 ++++++-- src/view_element.cpp | 8 +++----- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/layerelement.cpp b/src/layerelement.cpp index fc460b3819f..d10691e0471 100644 --- a/src/layerelement.cpp +++ b/src/layerelement.cpp @@ -256,7 +256,10 @@ int LayerElement::AlignHorizontally( ArrayPtrVoid *params ) type = ALIGNMENT_KEYSIG_ATTR; } else { - type = ALIGNMENT_KEYSIG; + //type = ALIGNMENT_KEYSIG; + // We force this because they should appear only at the beginning of a measure and should be non justifiable + // We also need it because the PAE importer creates keySig (and not staffDef @key.sig) + type = ALIGNMENT_KEYSIG_ATTR; } } else if (this->Is() == MENSUR) { @@ -278,7 +281,10 @@ int LayerElement::AlignHorizontally( ArrayPtrVoid *params ) // replace the current meter signature (*currentMeterSig) = dynamic_cast(this); assert( *currentMeterSig ); - type = ALIGNMENT_METERSIG; + //type = ALIGNMENT_METERSIG + // We force this because they should appear only at the beginning of a measure and should be non justifiable + // We also need it because the PAE importer creates meterSig (and not staffDef @meter) + type = ALIGNMENT_METERSIG_ATTR; } } else if ( (this->Is() == MULTIREST) || (this->Is() == MREST) || (this->Is() == MRPT) ) { diff --git a/src/note.cpp b/src/note.cpp index 319e765293c..2dfc2a31d3c 100644 --- a/src/note.cpp +++ b/src/note.cpp @@ -168,10 +168,14 @@ bool Note::IsClusterExtreme() bool Note::HasDrawingStemDir() { // In chord, the value is set in Chord::SetDrawingStemDir - // In beam, the value is tet in View::DrawBeam Chord* chordParent = dynamic_cast(this->GetFirstParent( CHORD, MAX_CHORD_DEPTH)); + if(chordParent) { + return true; + } + // In beam, the value is tet in View::DrawBeam - however, we need to check that the note is part of the beam + // It is not necessary the case with grace notes Beam* beamParent = dynamic_cast(this->GetFirstParent( BEAM, MAX_BEAM_DEPTH)); - if(chordParent || beamParent) { + if (beamParent && (beamParent->GetListIndex(this) > -1)) { return true; } else if (this->HasStemDir()) { diff --git a/src/view_element.cpp b/src/view_element.cpp index dda50d30c53..33b53072386 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -226,8 +226,8 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St // to see if beamed or not Beam *beam_parent = dynamic_cast(note->GetFirstParent( BEAM )); - // This note is beamed and cue sized if (beam_parent != NULL) { + // This note is beamed and cue sized if (drawingCueSize == true) { // Get the Parent of the parent // we want to see if we are in a group of @@ -235,7 +235,6 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St if (beam_parent->GetListIndex(note) > -1) { inBeam = true; } - } else { // the note is just in a beam @@ -667,8 +666,7 @@ void View::DrawMultiRest(DeviceContext *dc, LayerElement *element, Layer *layer, int width = measure->GetRightBarlineX() - measure->GetNonJustifiableLeftMargin(); int xCentered = measure->GetDrawingX() + measure->GetNonJustifiableLeftMargin() + (width / 2); - - + // We do not support more than three chars int num = std::min( multiRest->GetNum(), 999); @@ -1931,7 +1929,7 @@ void View::DrawAcciaccaturaSlash(DeviceContext *dc, LayerElement *element) ToDeviceContextX(startPoint.x - positionShiftX1 ), ToDeviceContextY(startPoint.y + positionShiftY1), ToDeviceContextX(startPoint.x + positionShiftX2), - ToDeviceContextY(note->GetDrawingStemStart().y + positionShiftY2)); + ToDeviceContextY(startPoint.y + positionShiftY2)); } else { dc->DrawLine(ToDeviceContextX(startPoint.x - positionShiftX1), ToDeviceContextY(startPoint.y - positionShiftY1), From 0a8b1fdd4dbfb8fa876032564d4db6cc2dcf881a Mon Sep 17 00:00:00 2001 From: Don Byrd Date: Thu, 17 Sep 2015 17:06:23 -0400 Subject: [PATCH 27/85] In mensural notation, always use mensural noteheads instead of CMN noteheads for durations shorter than semibrevis. --- src/view_mensural.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/view_mensural.cpp b/src/view_mensural.cpp index 4be08c3b532..406e16b2099 100644 --- a/src/view_mensural.cpp +++ b/src/view_mensural.cpp @@ -73,7 +73,7 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l drawingDur = note->GetDrawingDur(); - int radius = m_doc->GetGlyphWidth(SMUFL_E0A3_noteheadHalf, pseudoStaffSize, false) / 2; + int radius = m_doc->GetGlyphWidth(SMUFL_E93C_mensuralNoteheadMinimaWhite, pseudoStaffSize, false) / 2; if (drawingDur > DUR_1 || (drawingDur == DUR_1 && staff->notAnc)) { // annuler provisoirement la modif. des lignes addit. ledge = m_doc->GetDrawingLedgerLineLength(pseudoStaffSize, false); @@ -116,15 +116,15 @@ void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *l DrawSmuflCode( dc, xNote, noteY, charCode, pseudoStaffSize, false ); } - // Shorter values ??WE WANT MENSURAL NOTEHEADS, NOT CMN!!!!!!!! + // Shorter values else { if (note->GetColored()) { - if (drawingDur == DUR_2) charCode = SMUFL_E0A3_noteheadHalf; - else charCode = SMUFL_E0A4_noteheadBlack; + if (drawingDur == DUR_2) charCode = SMUFL_E93D_mensuralNoteheadSemiminimaWhite; + else charCode = SMUFL_E93C_mensuralNoteheadMinimaWhite; } else { - if (drawingDur > DUR_2) charCode = SMUFL_E93C_mensuralNoteheadMinimaWhite; - else charCode = SMUFL_E0A3_noteheadHalf; + if (drawingDur == DUR_2) charCode = SMUFL_E93C_mensuralNoteheadMinimaWhite; + else charCode = SMUFL_E93D_mensuralNoteheadSemiminimaWhite; } DrawSmuflCode( dc, xNote, noteY, charCode, pseudoStaffSize, false ); From ec667eeadb4565fd4960d543e50e93d0ba39fc28 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 18 Sep 2015 09:15:19 +0200 Subject: [PATCH 28/85] Adding functor for retrieving longest (or shortest) duration in the tree --- include/vrv/att_comparison.h | 54 ++++++++++++++++++++++++++++++++++++ include/vrv/object.h | 15 ++++++++++ src/object.cpp | 27 +++++++++++++++++- src/page.cpp | 11 ++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) diff --git a/include/vrv/att_comparison.h b/include/vrv/att_comparison.h index 300324dd2c2..45b97edb4bb 100644 --- a/include/vrv/att_comparison.h +++ b/include/vrv/att_comparison.h @@ -9,13 +9,22 @@ #define __VRV_ATT_COMPARISON_H__ #include "atts_shared.h" +#include "durationinterface.h" namespace vrv { +enum DurExtreme { + LONGEST = 0, + SHORTEST +}; + //---------------------------------------------------------------------------- // AttCommonNComparison //---------------------------------------------------------------------------- +/** + * This class evaluates if the object is of a certain ClassId and has a @n of value n. + */ class AttCommonNComparison: public AttComparison { @@ -43,6 +52,51 @@ class AttCommonNComparison: public AttComparison }; +//---------------------------------------------------------------------------- +// AttDurExtreme +//---------------------------------------------------------------------------- + +/** + * This class evaluates if the object the extreme duration so far + * The object has to have a DurationInterface and to have a @dur. + * The class can look for LONGEST or SHORTEST duration (Constructor) + */ +class AttDurExtreme: public AttComparison +{ + +public: + AttDurExtreme(DurExtreme extremeType): + AttComparison(OBJECT) + { + m_extremeType = extremeType; + if (m_extremeType == LONGEST) m_extremeDur = -VRV_UNSET; + else m_extremeDur = VRV_UNSET; + }; + + virtual bool operator() (Object *object) + { + if (!object->HasInterface(INTERFACE_DURATION)) return false; + DurationInterface *interface = dynamic_cast(object); + assert( interface ); + if (interface->HasDur()) { + if ((m_extremeType == LONGEST) && (interface->GetActualDur() < m_extremeDur)) { + m_extremeDur = interface->GetActualDur(); + return true; + } + else if ((m_extremeType == SHORTEST) && (interface->GetActualDur() > m_extremeDur)) { + m_extremeDur = interface->GetActualDur(); + return true; + } + } + return false; + } + +private: + int m_extremeDur; + DurExtreme m_extremeType; + +}; + } // namespace vrv #endif diff --git a/include/vrv/object.h b/include/vrv/object.h index 94ab598d00d..5cc84db11a7 100644 --- a/include/vrv/object.h +++ b/include/vrv/object.h @@ -237,6 +237,13 @@ class Object Object *FindChildByAttComparison( AttComparison *attComparison, int deepness = UNLIMITED_DEPTH, bool direction = FORWARD ); + /** + * Return the element matching the extreme value with an AttComparison functor + * Deepness allow to limit the depth search (EditorialElements are not count) + */ + Object *FindChildExtremeByAttComparison( AttComparison *attComparison, + int deepness = UNLIMITED_DEPTH, bool direction = FORWARD ); + /** * Give up ownership of the child at the idx position (NULL if not found) * This is a method to used only in very particular case where the child @@ -364,6 +371,14 @@ class Object * param 1: the pointer to pointer to the Object retrieved (if found). */ virtual int FindByAttComparison( ArrayPtrVoid *params ); + + /** + * Find a Object with the extreme value with a AttComparison functor . + * param 0: the pointer to the AttComparsion we are evaluating. + * param 1: the pointer to pointer to the Object retrieved (if found). + */ + virtual int FindExtremeByAttComparison( ArrayPtrVoid *params ); + /** * Save the content of and object by calling the appropriate FileOutputStream method diff --git a/src/object.cpp b/src/object.cpp index eb336829dd1..28a5b9929fb 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -275,6 +275,17 @@ Object *Object::FindChildByAttComparison( AttComparison *attComparison, int deep return element; } +Object *Object::FindChildExtremeByAttComparison( AttComparison *attComparison, int deepness, bool direction ) +{ + Functor findExtremeByAttComparison( &Object::FindExtremeByAttComparison ); + Object *element = NULL; + ArrayPtrVoid params; + params.push_back( attComparison ); + params.push_back( &element ); + this->Process( &findExtremeByAttComparison, ¶ms, NULL, NULL, deepness, direction ); + return element; +} + Object* Object::GetChild( int idx ) { if ( (idx < 0) || (idx >= (int)m_children.size()) ) { @@ -918,7 +929,21 @@ int Object::FindByAttComparison( ArrayPtrVoid *params ) //LogDebug("Still looking for the object matching the AttComparison..."); return FUNCTOR_CONTINUE; } - + +int Object::FindExtremeByAttComparison( ArrayPtrVoid *params ) +{ + // param 0: the type we are looking for + // param 1: the pointer to pointer to the Object + AttComparison *test = static_cast((*params).at(0)); + Object **element = static_cast((*params).at(1)); + + // evaluate by applying the AttComparison operator() + if ((*test)(this)) { + (*element) = this; + } + // continue until the end + return FUNCTOR_CONTINUE; +} int Object::SetCurrentScoreDef( ArrayPtrVoid *params ) { diff --git a/src/page.cpp b/src/page.cpp index aebb1fd8e99..f62bc5d2dcc 100644 --- a/src/page.cpp +++ b/src/page.cpp @@ -14,10 +14,12 @@ //---------------------------------------------------------------------------- +#include "att_comparison.h" #include "bboxdevicecontext.h" #include "doc.h" #include "system.h" #include "view.h" +#include "vrv.h" namespace vrv { @@ -115,6 +117,15 @@ void Page::LayOutHorizontally( ) // Unless duration-based spacing is disabled, set the X position of each Alignment. // Does non-linear spacing based on the duration space between two Alignment objects. if (!doc->GetEvenSpacing()) { + // Get the longest duration in the piece + AttDurExtreme durExtremeComparison(LONGEST); + Object *longestDur = this->FindChildExtremeByAttComparison(&durExtremeComparison); + if (longestDur) { + DurationInterface *interface = dynamic_cast(longestDur); + assert(interface); + LogDebug("Longest duration is %d", interface->GetActualDur()); + } + params.clear(); double previousTime = 0.0; int previousXRel = 0; From 0e1f2ffc82baad3d5d80dac452a00c6fddf0fee2 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Fri, 18 Sep 2015 09:58:06 +0200 Subject: [PATCH 29/85] Starting 0.9.10-dev --- include/vrv/vrvdef.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vrv/vrvdef.h b/include/vrv/vrvdef.h index bd37ccb006b..97e5cc715cf 100644 --- a/include/vrv/vrvdef.h +++ b/include/vrv/vrvdef.h @@ -27,9 +27,9 @@ namespace vrv { #define VERSION_MAJOR 0 #define VERSION_MINOR 9 -#define VERSION_REVISION 9 +#define VERSION_REVISION 10 // Adds "-dev" in the version number - should be set to false for releases -#define VERSION_DEV false +#define VERSION_DEV true //---------------------------------------------------------------------------- // Typedefs From bf43e562c3a7d23b7bd04e268d6de04ef5d18932 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Sat, 19 Sep 2015 09:38:42 +0200 Subject: [PATCH 30/85] Bug fix for tie direction in chords --- src/view_floating.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/view_floating.cpp b/src/view_floating.cpp index ae0951cef72..a5c74a8f20e 100644 --- a/src/view_floating.cpp +++ b/src/view_floating.cpp @@ -764,7 +764,7 @@ void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, Note *note1 = NULL; Note *note2 = NULL; - Chord *parentChord = NULL; + Chord *parentChord1 = NULL; bool up = true; data_STEMDIRECTION noteStemDir = STEMDIRECTION_NONE; @@ -780,7 +780,7 @@ void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, return; } - Chord *chordParent1 = note1->IsChordTone(); + parentChord1 = note1->IsChordTone(); Layer* layer1 = dynamic_cast(note1->GetFirstParent( LAYER ) ); Layer* layer2 = dynamic_cast(note2->GetFirstParent( LAYER ) ); @@ -794,7 +794,7 @@ void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, bool isShortTie = false; // shortTie correction cannot be applied for chords - if (!chordParent1 && (x2 - x1 < 3 * m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize))) isShortTie = true; + if (!parentChord1 && (x2 - x1 < 3 * m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize))) isShortTie = true; // the normal case if ( spanningType == SPANNING_START_END ) { @@ -806,8 +806,8 @@ void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, if (note1->HasDots()) { x1 += m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * note1->GetDots(); } - else if (chordParent1 && chordParent1->HasDots()) { - x1 += m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * chordParent1->GetDots(); + else if (parentChord1 && parentChord1->HasDots()) { + x1 += m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * parentChord1->GetDots(); } } noteStemDir = note1->GetDrawingStemDir(); @@ -848,9 +848,9 @@ void View::DrawTie( DeviceContext *dc, Tie *tie, int x1, int x2, Staff *staff, up = layer1->GetDrawingStemDir() == STEMDIRECTION_up ? true : false; } // the look if in a chord - else if (parentChord) { - if (parentChord->PositionInChord(note1) < 0) up = false; - else if (parentChord->PositionInChord(note1) > 0) up = true; + else if (parentChord1) { + if (parentChord1->PositionInChord(note1) < 0) up = false; + else if (parentChord1->PositionInChord(note1) > 0) up = true; // away from the stem if odd number (center note) else up = (noteStemDir != STEMDIRECTION_up); } From c47058263fd9f73710363d9e2a4c87dd2a182eca Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Tue, 22 Sep 2015 07:43:55 +0200 Subject: [PATCH 31/85] Fixing fermatas --- include/vrv/view.h | 2 +- src/view_element.cpp | 82 +++++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/include/vrv/view.h b/include/vrv/view.h index 5bd0177e477..393b2a7ef17 100644 --- a/include/vrv/view.h +++ b/include/vrv/view.h @@ -238,7 +238,7 @@ class View void DrawAcciaccaturaSlash(DeviceContext *dc, LayerElement *element); void DrawBreveRest ( DeviceContext *dc, int x, int y, Staff *staff ); void DrawDots ( DeviceContext *dc, int x, int y, unsigned char dots, Staff *staff ); - void DrawFermata(DeviceContext *dc, LayerElement *element, Staff *staff); + void DrawFermata(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff); void DrawLedgerLines ( DeviceContext *dc, LayerElement *element, Staff *staff, bool aboveStaff, bool doubleLength, int skip, int n); void DrawLongRest ( DeviceContext *dc, int x, int y, Staff *staff); void DrawMeterSigFigures( DeviceContext *dc, int x, int y, int num, int numBase, Staff *staff); diff --git a/src/view_element.cpp b/src/view_element.cpp index 33b53072386..35351ffb514 100644 --- a/src/view_element.cpp +++ b/src/view_element.cpp @@ -434,7 +434,7 @@ void View::DrawNote ( DeviceContext *dc, LayerElement *element, Layer *layer, St if (!inChord) DrawLayerChildren(dc, note, layer, staff, measure); if (note->GetFermata() != PLACE_NONE) { - DrawFermata(dc, element, staff); + DrawFermata(dc, element, layer, staff); } if (note->m_embellishment == EMB_TRILL) { @@ -620,7 +620,7 @@ void View::DrawRest ( DeviceContext *dc, LayerElement *element, Layer *layer, St } if(rest->GetFermata() != PLACE_NONE) { - DrawFermata(dc, element, staff); + DrawFermata(dc, element, layer, staff); } } @@ -1941,12 +1941,7 @@ void View::DrawAcciaccaturaSlash(DeviceContext *dc, LayerElement *element) dc->ResetBrush(); } -/** Draws a fermata - rest - the fermata is always above the stavv - note - for breves and semibreves, only above the staff - - for flagged notes, the fermata is on the side of the notehead - */ -void View::DrawFermata(DeviceContext *dc, LayerElement *element, Staff *staff) +void View::DrawFermata(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff) { int x, y; int emb_offset = 0; // if there is and embellishment, offset the note up @@ -1954,50 +1949,57 @@ void View::DrawFermata(DeviceContext *dc, LayerElement *element, Staff *staff) // We move the fermata position of half of the fermata size x = element->GetDrawingX() - m_doc->GetGlyphWidth(SMUFL_E4C0_fermataAbove, staff->m_drawingStaffSize, false) / 2; + data_PLACE place = PLACE_above; + if (layer->GetDrawingStemDir() != STEMDIRECTION_NONE) { + place = (layer->GetDrawingStemDir() == STEMDIRECTION_up) ? PLACE_above : PLACE_above; + } + // First case, notes - if (element->Is() == NOTE) { - Note *note = dynamic_cast(element); - assert( note ); - - /* - // stem down or semibreve/longa, fermata up! - if (!element->m_drawingStemDir && (note->m_dur != DUR_1 || note->m_dur != DUR_BR)) { - */ - // only for up-fermatas, if there is a trill on the same note - if (note->m_embellishment) + if ((element->Is() == NOTE) || (element->Is() == CHORD)) { + // To be fix once m_embellishment is removed + if (element->Is() == NOTE) { + Note *note = dynamic_cast(element); + assert( note ); + if (note->m_embellishment) { emb_offset = m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize); - + } + } + + if (place == PLACE_above) { // check that the notehead is in the staff. - if ((element->GetDrawingY()) < staff->GetDrawingY()) + if (element->GetDrawingTop(m_doc, staff->m_drawingStaffSize) < staff->GetDrawingY()) { // in the staff, set the fermata 20 pixels above the last line (+ embellishment offset) y = staff->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) + emb_offset; - else + } + else { // out of the staff, place the trill above the notehead - y = (element->GetDrawingY()) + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) + emb_offset; - - // draw the up-fermata + y = element->GetDrawingTop(m_doc, staff->m_drawingStaffSize) + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) + emb_offset; + } + // draw the up-fermata - need cue size support DrawSmuflCode ( dc, x, y, SMUFL_E4C0_fermataAbove, staff->m_drawingStaffSize, false ); - /* - } else { // stem up fermata down - + } + else { // This works as above, only we check that the note head is not - // UNDER the staff - if ((element->GetDrawingY()) > (staff->GetDrawingY() - m_doc->m_drawingStaffSize.at(staff->m_drawingStaffSize))) + if (element->GetDrawingBottom(m_doc, staff->m_drawingStaffSize) > (staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize))) { // notehead in staff, set under - y = staff->GetDrawingY() - m_doc->m_drawingStaffSize.at(staff->m_drawingStaffSize) - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize); - else + y = staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize) - m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + } + else { // notehead under staff, set under notehead - y = (element->GetDrawingY()) - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize); - - DrawSmuflCode ( dc, x, y, LEIPZIG_FERMATA_DOWN, staff, false ); + y = element->GetDrawingBottom(m_doc, staff->m_drawingStaffSize) - m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + } + // draw the down-fermata - need cue size support + DrawSmuflCode ( dc, x, y, SMUFL_E4C1_fermataBelow, staff->m_drawingStaffSize, false ); } - */ } else if (element->Is() == REST) { - // this is a rest - // rests for the moment are always in the staff - // so just place the fermata above the staff - y = staff->GetDrawingY() + m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize); - DrawSmuflCode ( dc, x, y, SMUFL_E4C0_fermataAbove, staff->m_drawingStaffSize, false ); + if (place == PLACE_above) { + y = staff->GetDrawingY() + m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize); + DrawSmuflCode ( dc, x, y, SMUFL_E4C0_fermataAbove, staff->m_drawingStaffSize, false ); + } + else { + y = staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize) - m_doc->GetDrawingUnit(staff->m_drawingStaffSize); + DrawSmuflCode ( dc, x, y, SMUFL_E4C1_fermataBelow, staff->m_drawingStaffSize, false ); + } } } From dfc6e084c9880fdc59cc15953f46eb9c0aa704b2 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Wed, 23 Sep 2015 18:12:53 +0200 Subject: [PATCH 32/85] Adding namespace for local Plain and Easy classes (note and measure) --- include/vrv/iopae.h | 54 ++++++++++++++++++++++----------------------- src/iopae.cpp | 37 ++++++++++++++----------------- 2 files changed, 43 insertions(+), 48 deletions(-) diff --git a/include/vrv/iopae.h b/include/vrv/iopae.h index 2445cf88c83..6233601473f 100644 --- a/include/vrv/iopae.h +++ b/include/vrv/iopae.h @@ -31,11 +31,17 @@ class Tie; class Tuplet; class KeySig; class Barline; + +//---------------------------------------------------------------------------- +// namespace for local Plain and Easy classes +//---------------------------------------------------------------------------- + +namespace pae { +class Note { -class NoteObject { public: - NoteObject(const NoteObject &old) { // for STL vector + Note(const pae::Note &old) { // for STL vector //mnote = old.mnote; //mrest = old.mrest; tie = old.tie; @@ -59,7 +65,7 @@ class NoteObject { tuplet_notes = old.tuplet_notes; tuplet_note = old.tuplet_note; } - NoteObject(void) { clear(); }; + Note(void) { clear(); }; void clear(void) { appoggiatura = 0; acciaccatura = fermata = trill = false; @@ -81,7 +87,7 @@ class NoteObject { key = NULL; }; - NoteObject& operator=(const NoteObject& d){ // for STL vector + Note& operator=(const Note& d){ // for STL vector //mnote = d.mnote; //mrest = d.mrest; tie = d.tie; @@ -136,10 +142,11 @@ class NoteObject { }; -class MeasureObject { +class Measure { + public: - MeasureObject(const MeasureObject& d){ // for STL vector + Measure(const Measure& d){ // for STL vector clef = d.clef; meter = d.meter; notes = d.notes; @@ -153,9 +160,9 @@ class MeasureObject { abbreviation_offset = d.abbreviation_offset; wholerest = d.wholerest; } - MeasureObject(void) { clear(); }; + Measure(void) { clear(); }; - MeasureObject& operator=(const MeasureObject& d){ // for STL vector + Measure& operator=(const Measure& d){ // for STL vector clef = d.clef; meter = d.meter; notes = d.notes; @@ -191,7 +198,7 @@ class MeasureObject { MeterSig *meter; KeySig *key; - std::vector notes; + std::vector notes; std::vector durations; std::vector dots; // use the same offset as durations, they are used in parallel @@ -200,17 +207,8 @@ class MeasureObject { int abbreviation_offset; int wholerest; // number of whole rests to process }; - - -////////////////////////////////////////////////////////////////////////// - - - - - - - - + +} // namespace pae //---------------------------------------------------------------------------- // PaeInput @@ -241,22 +239,22 @@ class PaeInput: public FileInputStream int getBarline (const char *incipit, data_BARRENDITION *output, int index ); int getAccidental (const char* incipit, data_ACCIDENTAL_EXPLICIT *accident, int index = 0); int getOctave (const char* incipit, char *octave, int index = 0 ); - int getDurations (const char* incipit, MeasureObject *measure, int index = 0); + int getDurations (const char* incipit, pae::Measure *measure, int index = 0); int getDuration (const char* incipit, data_DURATION *duration, int *dot, int index ); - int getTupletFermata (const char* incipit, NoteObject *note, int index = 0); - int getTupletFermataEnd (const char* incipit, NoteObject *note, int index = 0); - int getGraceNote (const char* incipit, NoteObject *note, int index = 0); + int getTupletFermata (const char* incipit, pae::Note *note, int index = 0); + int getTupletFermataEnd (const char* incipit, pae::Note *note, int index = 0); + int getGraceNote (const char* incipit, pae::Note *note, int index = 0); int getWholeRest (const char* incipit, int *wholerest, int index ); - int getAbbreviation (const char* incipit, MeasureObject *measure, int index = 0 ); - int getNote (const char* incipit, NoteObject *note, MeasureObject *measure, int index = 0 ); + int getAbbreviation (const char* incipit, pae::Measure *measure, int index = 0 ); + int getNote (const char* incipit, pae::Note *note, pae::Measure *measure, int index = 0 ); data_PITCHNAME getPitch (char c_note ); // output functions void addLayerElement (LayerElement *element); - void parseNote (NoteObject note); + void parseNote (pae::Note note); void popContainer (); - void convertMeasure (MeasureObject *measure); + void convertMeasure (pae::Measure *measure); void pushContainer (LayerElement *container); diff --git a/src/iopae.cpp b/src/iopae.cpp index 3e76d7e6d4b..d5414198896 100644 --- a/src/iopae.cpp +++ b/src/iopae.cpp @@ -59,16 +59,13 @@ char data_line[10001] = {0}; char data_key[MAX_DATA_LEN]; char data_value[MAX_DATA_LEN]; //ditto as above - -////////////////////////////////////////////////////////////////////////// - //---------------------------------------------------------------------------- // PaeInput //---------------------------------------------------------------------------- PaeInput::PaeInput( Doc *doc, std::string filename ) : -// This is pretty bad. We open a bad fileoinputstream as we don't use it -FileInputStream( doc ) + // This is pretty bad. We open a bad fileoinputstream as we don't use it + FileInputStream( doc ) { m_filename = filename; m_staff = NULL; @@ -127,11 +124,11 @@ void PaeInput::parsePlainAndEasy(std::istream &infile) { int in_beam = 0; std::string s_key; - MeasureObject current_measure; - NoteObject current_note; + pae::Measure current_measure; + pae::Note current_note; Clef *staffDefClef = NULL; - std::vector staff; + std::vector staff; // read values while (!infile.eof()) { @@ -265,7 +262,7 @@ void PaeInput::parsePlainAndEasy(std::istream &infile) { // measure repetition else if ((incipit[i] == 'i') && staff.size() > 0) { - MeasureObject last_measure = staff[staff.size() - 1]; + pae::Measure last_measure = staff[staff.size() - 1]; current_measure.notes = last_measure.notes; current_measure.wholerest = last_measure.wholerest; @@ -361,7 +358,7 @@ void PaeInput::parsePlainAndEasy(std::istream &infile) { int measure_count = 1; - std::vector::iterator it; + std::vector::iterator it; for ( it = staff.begin() ; it < staff.end(); it++ ) { m_staff = new Staff( 1 ); @@ -373,7 +370,7 @@ void PaeInput::parsePlainAndEasy(std::istream &infile) { m_measure->AddStaff( m_staff ); system->AddMeasure( m_measure ); - MeasureObject obj = *it; + pae::Measure obj = *it; convertMeasure( &obj ); measure_count++; } @@ -480,7 +477,7 @@ int PaeInput::getDuration(const char* incipit, data_DURATION *duration, int *dot // getDurations -- // -int PaeInput::getDurations(const char* incipit, MeasureObject* measure, int index ) { +int PaeInput::getDurations(const char* incipit, pae::Measure* measure, int index ) { int i = index; size_t length = strlen(incipit); @@ -545,7 +542,7 @@ int PaeInput::getAccidental(const char* incipit, data_ACCIDENTAL_EXPLICIT *accid // getTupletOrFermata -- // -int PaeInput::getTupletFermata(const char* incipit, NoteObject* note, int index ) { +int PaeInput::getTupletFermata(const char* incipit, pae::Note* note, int index ) { int i = index; size_t length = strlen(incipit); @@ -633,7 +630,7 @@ int PaeInput::getTupletFermata(const char* incipit, NoteObject* note, int index // getTupletFermataEnd -- // // this can be deleted in the future? -int PaeInput::getTupletFermataEnd(const char* incipit, NoteObject *note, int index ) { +int PaeInput::getTupletFermataEnd(const char* incipit, pae::Note *note, int index ) { int i = index; //int length = strlen(incipit); @@ -651,7 +648,7 @@ int PaeInput::getTupletFermataEnd(const char* incipit, NoteObject *note, int ind // getGraceNote -- // -int PaeInput::getGraceNote(const char* incipit, NoteObject *note, int index ) { +int PaeInput::getGraceNote(const char* incipit, pae::Note *note, int index ) { int i = index; size_t length = strlen(incipit); @@ -925,7 +922,7 @@ int PaeInput::getBarline( const char *incipit, data_BARRENDITION *output, int in // getAbbreviation -- read abbreviation // -int PaeInput::getAbbreviation(const char* incipit, MeasureObject *measure, int index ) { +int PaeInput::getAbbreviation(const char* incipit, pae::Measure *measure, int index ) { size_t length = strlen(incipit); int i = index; @@ -998,7 +995,7 @@ int PaeInput::getKeyInfo(const char *incipit, KeySig *key, int index ) { // getNote -- // -int PaeInput::getNote( const char* incipit, NoteObject *note, MeasureObject *measure, int index ) { +int PaeInput::getNote( const char* incipit, pae::Note *note, pae::Measure *measure, int index ) { regex_t re; int oct; @@ -1090,7 +1087,7 @@ int PaeInput::getNote( const char* incipit, NoteObject *note, MeasureObject *mea // convertMeasure -- // -void PaeInput::convertMeasure(MeasureObject *measure ) { +void PaeInput::convertMeasure(pae::Measure *measure ) { if ( measure->clef != NULL ) { m_layer->AddLayerElement(measure->clef); @@ -1113,7 +1110,7 @@ void PaeInput::convertMeasure(MeasureObject *measure ) { m_nested_objects.clear(); for (unsigned int i=0; inotes.size(); i++) { - NoteObject note = measure->notes[i]; + pae::Note note = measure->notes[i]; parseNote(note); } @@ -1124,7 +1121,7 @@ void PaeInput::convertMeasure(MeasureObject *measure ) { } -void PaeInput::parseNote(NoteObject note) { +void PaeInput::parseNote(pae::Note note) { LayerElement *element; From eb98a5be5eb150483ceb94b3d6b3f590a3cc246b Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 24 Sep 2015 07:49:09 +0200 Subject: [PATCH 33/85] Making parseNote in PAE take a reference --- include/vrv/iopae.h | 3 +- src/iopae.cpp | 74 ++++++++++++++++++++++----------------------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/include/vrv/iopae.h b/include/vrv/iopae.h index 6233601473f..1c5b914ede1 100644 --- a/include/vrv/iopae.h +++ b/include/vrv/iopae.h @@ -138,7 +138,6 @@ class Note { Clef *clef; MeterSig *meter; KeySig *key; - }; @@ -252,7 +251,7 @@ class PaeInput: public FileInputStream // output functions void addLayerElement (LayerElement *element); - void parseNote (pae::Note note); + void parseNote (pae::Note *note); void popContainer (); void convertMeasure (pae::Measure *measure); void pushContainer (LayerElement *container); diff --git a/src/iopae.cpp b/src/iopae.cpp index d5414198896..25e0d99593a 100644 --- a/src/iopae.cpp +++ b/src/iopae.cpp @@ -1110,7 +1110,7 @@ void PaeInput::convertMeasure(pae::Measure *measure ) { m_nested_objects.clear(); for (unsigned int i=0; inotes.size(); i++) { - pae::Note note = measure->notes[i]; + pae::Note *note = &measure->notes[i]; parseNote(note); } @@ -1121,17 +1121,17 @@ void PaeInput::convertMeasure(pae::Measure *measure ) { } -void PaeInput::parseNote(pae::Note note) { +void PaeInput::parseNote(pae::Note *note) { LayerElement *element; - if (note.rest) { + if (note->rest) { Rest *rest = new Rest(); - rest->SetDots( note.dots ); - rest->SetDur(note.duration); + rest->SetDots( note->dots ); + rest->SetDur(note->duration); - if (note.fermata) { + if (note->fermata) { rest->SetFermata(PLACE_above); // always above for now } @@ -1139,18 +1139,18 @@ void PaeInput::parseNote(pae::Note note) { } else { Note *mnote = new Note(); - mnote->SetPname(note.pitch); - mnote->SetOct(note.octave); - mnote->SetAccid(note.accidental); + mnote->SetPname(note->pitch); + mnote->SetOct(note->octave); + mnote->SetAccid(note->accidental); - mnote->SetDots( note.dots ); - mnote->SetDur(note.duration); + mnote->SetDots( note->dots ); + mnote->SetDur(note->duration); - if (note.fermata) { + if (note->fermata) { mnote->SetFermata(PLACE_above); // always above for now } - if (note.trill == true) + if (note->trill == true) mnote->m_embellishment = EMB_TRILL; if (m_last_tied_note != NULL) { @@ -1158,7 +1158,7 @@ void PaeInput::parseNote(pae::Note note) { m_last_tied_note = NULL; } - if (note.tie) { + if (note->tie) { if (mnote->GetTie()==TIE_t) mnote->SetTie(TIE_m); else mnote->SetTie(TIE_i); m_last_tied_note = mnote; @@ -1168,46 +1168,46 @@ void PaeInput::parseNote(pae::Note note) { } // Does this note have a clef change? push it before everyting else - if (note.clef) - addLayerElement(note.clef); + if (note->clef) + addLayerElement(note->clef); // Same thing for time changes // You can find this sometimes - if (note.meter) - addLayerElement(note.meter); + if (note->meter) + addLayerElement(note->meter); // Handle key change. Evil if done in a beam - if (note.key) - addLayerElement(note.key); + if (note->key) + addLayerElement(note->key); // Acciaccaturas are similar but do not get beamed (do they) // this case is simpler. NOTE a note can not be acciacctura AND appoggiatura // Acciaccatura rests do not exist - if (note.acciaccatura && (element->Is() == NOTE) ) { - Note *note = dynamic_cast(element); - assert( note ); - note->SetDur(DURATION_8); - note->SetGrace(GRACE_acc); - note->SetStemDir(STEMDIRECTION_up); + if (note->acciaccatura && (element->Is() == NOTE) ) { + Note *mnote = dynamic_cast(element); + assert( mnote ); + mnote->SetDur(DURATION_8); + mnote->SetGrace(GRACE_acc); + mnote->SetStemDir(STEMDIRECTION_up); } - if ( (note.appoggiatura > 0) && (element->Is() == NOTE) ) { - Note *note = dynamic_cast(element); - assert( note ); - note->SetGrace(GRACE_unacc); - note->SetStemDir(STEMDIRECTION_up); + if ( (note->appoggiatura > 0) && (element->Is() == NOTE) ) { + Note *mnote = dynamic_cast(element); + assert( mnote ); + mnote->SetGrace(GRACE_unacc); + mnote->SetStemDir(STEMDIRECTION_up); } - if (note.beam == BEAM_INITIAL) { + if (note->beam == BEAM_INITIAL) { pushContainer(new Beam()); } // we have a tuplet, the tuplet_note is > 0 // which means we are counting a tuplet - if (note.tuplet_note > 0 && note.tuplet_notes == note.tuplet_note) { // first elem in tuplet + if (note->tuplet_note > 0 && note->tuplet_notes == note->tuplet_note) { // first elem in tuplet Tuplet *newTuplet = new Tuplet(); - newTuplet->SetNum(note.tuplet_notes); - newTuplet->SetNumbase(note.tuplet_notes); + newTuplet->SetNum(note->tuplet_notes); + newTuplet->SetNumbase(note->tuplet_notes); pushContainer(newTuplet); } @@ -1218,10 +1218,10 @@ void PaeInput::parseNote(pae::Note note) { // the last note counts always '1' // insert the tuplet elem // and reset the tuplet counter - if (note.tuplet_note == 1) + if (note->tuplet_note == 1) popContainer(); - if (note.beam == BEAM_TERMINAL) + if (note->beam == BEAM_TERMINAL) popContainer(); } From 0605d104e1b4c7a4a9898a70e4e847df8e411095 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 24 Sep 2015 07:49:47 +0200 Subject: [PATCH 34/85] Fixing tie being removed bug in PAE measure repetition --- src/iopae.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/iopae.cpp b/src/iopae.cpp index 25e0d99593a..2d4131c216c 100644 --- a/src/iopae.cpp +++ b/src/iopae.cpp @@ -265,12 +265,6 @@ void PaeInput::parsePlainAndEasy(std::istream &infile) { pae::Measure last_measure = staff[staff.size() - 1]; current_measure.notes = last_measure.notes; current_measure.wholerest = last_measure.wholerest; - - // if old measure does not end with a tie - // force the first note of the newly copied measure to be without tie - // this is to prevent copying tie closes which are invalid - if (last_measure.notes.size() > 0 && last_measure.notes[last_measure.notes.capacity() - 1].tie == 0) - current_measure.notes[0].tie = 0; } //barLine From bc5babe49c834fbf0f51c7cbb0a8604506c9d154 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 24 Sep 2015 08:41:57 +0200 Subject: [PATCH 35/85] Adding PAE chord support (limited) --- include/vrv/iopae.h | 6 +- src/iopae.cpp | 167 +++++++++++++++++++++++++++++++------------- 2 files changed, 125 insertions(+), 48 deletions(-) diff --git a/include/vrv/iopae.h b/include/vrv/iopae.h index 1c5b914ede1..4a66a0afc10 100644 --- a/include/vrv/iopae.h +++ b/include/vrv/iopae.h @@ -49,6 +49,7 @@ class Note { appoggiatura = old.appoggiatura; fermata = old.fermata; trill = old.trill; + chord = old.chord; octave = old.octave; beam = old.beam; @@ -68,7 +69,7 @@ class Note { Note(void) { clear(); }; void clear(void) { appoggiatura = 0; - acciaccatura = fermata = trill = false; + acciaccatura = fermata = trill = chord = false; tie = 0; octave = 4; @@ -95,6 +96,7 @@ class Note { appoggiatura = d.appoggiatura; fermata = d.fermata; trill = d.trill; + chord = d.chord; octave = d.octave; beam = d.beam; @@ -126,6 +128,7 @@ class Note { int appoggiatura; bool fermata; bool trill; + bool chord; char octave; unsigned char beam; @@ -270,6 +273,7 @@ class PaeInput: public FileInputStream Measure *m_measure; Layer *m_layer; Note *m_last_tied_note; + bool m_is_in_chord; std::vector m_nested_objects; }; diff --git a/src/iopae.cpp b/src/iopae.cpp index 2d4131c216c..8c0dbaf4863 100644 --- a/src/iopae.cpp +++ b/src/iopae.cpp @@ -16,6 +16,7 @@ //---------------------------------------------------------------------------- #include "beam.h" +#include "chord.h" #include "doc.h" #include "keysig.h" #include "layer.h" @@ -72,6 +73,7 @@ PaeInput::PaeInput( Doc *doc, std::string filename ) : m_measure = NULL; m_layer = NULL; m_last_tied_note = NULL; + m_is_in_chord = false; } PaeInput::~PaeInput() @@ -140,17 +142,23 @@ void PaeInput::parsePlainAndEasy(std::istream &infile) { getAtRecordKeyValue(data_key, data_value, data_line); if (strcmp(data_key,"end")==0) { break; - } else if (strcmp(data_key,"clef")==0) { + } + else if (strcmp(data_key,"clef")==0) { strcpy( c_clef, data_value ); - } else if (strcmp(data_key,"key")==0) { + } + else if (strcmp(data_key,"key")==0) { strcpy( c_key, data_value ); - } else if (strcmp(data_key,"keysig")==0) { + } + else if (strcmp(data_key,"keysig")==0) { strcpy( c_keysig, data_value ); - } else if (strcmp(data_key,"timesig")==0) { + } + else if (strcmp(data_key,"timesig")==0) { strcpy( c_timesig, data_value ); - } else if (strcmp(data_key,"alttimesig")==0) { + } + else if (strcmp(data_key,"alttimesig")==0) { strcpy( c_alttimesig, data_value ); - } else if (strcmp(data_key,"data")==0) { + } + else if (strcmp(data_key,"data")==0) { strcpy( incipit, data_value ); } } @@ -513,13 +521,15 @@ int PaeInput::getAccidental(const char* incipit, data_ACCIDENTAL_EXPLICIT *accid if (incipit[i] == 'n') { *accident = ACCIDENTAL_EXPLICIT_n; - } else if (incipit[i] == 'x') { + } + else if (incipit[i] == 'x') { *accident = ACCIDENTAL_EXPLICIT_s; if ((i+1 < length) && (incipit[i+1] == 'x')) { *accident = ACCIDENTAL_EXPLICIT_ss; i++; } - } else if (incipit[i] == 'b') { + } + else if (incipit[i] == 'b') { *accident = ACCIDENTAL_EXPLICIT_f; if ((i+1 < length) && (incipit[i+1] == 'b')) { *accident = ACCIDENTAL_EXPLICIT_ff; @@ -596,7 +606,8 @@ int PaeInput::getTupletFermata(const char* incipit, pae::Note* note, int index ) tuplet_val = atoi(buf); free(buf); // dispose of the buffer - } else { // it is a triplet + } + else { // it is a triplet // don't care to parse all the stuff tuplet_val = 3; } @@ -606,7 +617,8 @@ int PaeInput::getTupletFermata(const char* incipit, pae::Note* note, int index ) // but also the note counter note->tuplet_note = tuplet_val; - } else { + } + else { if ( note->tuplet_notes > 0 ) { LogWarning("Fermata within a tuplet. Won't be handled correctly"); } @@ -719,8 +731,9 @@ int PaeInput::getTimeInfo( const char* incipit, MeterSig *meter, int index) { int i = index; size_t length = strlen(incipit); - if (!isdigit(incipit[i]) && (incipit[i] != 'c') && (incipit[i] != 'o')) + if (!isdigit(incipit[i]) && (incipit[i] != 'c') && (incipit[i] != 'o')) { return 0; + } // find the end of time signature end i++; // the time signature length is a least 1 @@ -755,25 +768,31 @@ int PaeInput::getTimeInfo( const char* incipit, MeterSig *meter, int index) { int note_value = atoi(strtok(NULL, "/")); meter->SetCount(beats); meter->SetUnit(note_value); - } else if ( is_one_number == 0) { + } + else if ( is_one_number == 0) { int beats = atoi(timesig_str); meter->SetCount(beats); - } else if (strcmp(timesig_str, "c") == 0) { + } + else if (strcmp(timesig_str, "c") == 0) { // C meter->SetSym(METERSIGN_common); - } else if (strcmp(timesig_str, "c/") == 0) { + } + else if (strcmp(timesig_str, "c/") == 0) { // C| meter->SetSym(METERSIGN_cut); - } else if (strcmp(timesig_str, "c3") == 0) { + } + else if (strcmp(timesig_str, "c3") == 0) { // C3 meter->SetSym(METERSIGN_common); meter->SetCount(3); - } else if (strcmp(timesig_str, "c3/2") == 0) { + } + else if (strcmp(timesig_str, "c3/2") == 0) { // C3/2 meter->SetSym(METERSIGN_common); // ?? meter->SetCount(3); meter->SetUnit(2); - } else { + } + else { LogWarning("Unknown time signature: %s", timesig_str); } @@ -811,18 +830,22 @@ int PaeInput::getClefInfo( const char *incipit, Clef *mclef, int index ) { if (clef == 'C' || clef == 'c') { mclef->SetShape(CLEFSHAPE_C); mclef->SetLine(line - 48); - } else if (clef == 'G') { + } + else if (clef == 'G') { mclef->SetShape(CLEFSHAPE_G); mclef->SetLine(line - 48); - } else if (clef == 'g') { + } + else if (clef == 'g') { mclef->SetShape(CLEFSHAPE_G); mclef->SetLine(line - 48); mclef->SetDis(OCTAVE_DIS_8); mclef->SetDisPlace(PLACE_below); - } else if (clef == 'F' || clef == 'f') { + } + else if (clef == 'F' || clef == 'f') { mclef->SetShape(CLEFSHAPE_F); mclef->SetLine(line - 48); - } else { + } + else { // what the... LogDebug("Clef %c is Undefined", clef); } @@ -893,16 +916,20 @@ int PaeInput::getBarline( const char *incipit, data_BARRENDITION *output, int in if (is_barline_rptboth == 0) { *output = BARRENDITION_rptboth; i = 3; - } else if (is_barline_rptstart == 0) { + } + else if (is_barline_rptstart == 0) { *output = BARRENDITION_rptstart; i = 2; - } else if (is_barline_rptend == 0) { + } + else if (is_barline_rptend == 0) { *output = BARRENDITION_rptend; i = 2; - } else if (is_barline_dbl == 0) { + } + else if (is_barline_dbl == 0) { *output = BARRENDITION_dbl; i = 1; - } else { + } + else { *output = BARRENDITION_single; i = 0; } @@ -924,7 +951,8 @@ int PaeInput::getAbbreviation(const char* incipit, pae::Measure *measure, int in if (measure->abbreviation_offset == -1) { // start measure->abbreviation_offset = (int)measure->notes.size(); - } else { // + } + else { // int abbreviation_stop = (int)measure->notes.size(); while ((i+1 < length) && (incipit[i+1]=='f')) { i++; @@ -1002,12 +1030,14 @@ int PaeInput::getNote( const char* incipit, pae::Note *note, pae::Measure *measu // acciaccaturas are always eights regardless // and have no dots note->duration = DURATION_8; - } else { + } + else { if (measure->durations.size() == 0) { note->duration = DURATION_4; note->dots = 0; LogWarning("Got a note before a duration was specified"); - } else { + } + else { note->duration = measure->durations[measure->durations_offset]; note->dots = measure->dots[measure->durations_offset]; } @@ -1016,8 +1046,9 @@ int PaeInput::getNote( const char* incipit, pae::Note *note, pae::Measure *measu // lookout, hack. If it is a rest (PITCHNAME_NONE val) then create the rest object. // it will be added instead of the note - if (note->pitch == PITCHNAME_NONE) + if (note->pitch == PITCHNAME_NONE) { note->rest = true; + } // trills regcomp(&re, "^[^ABCDEFG]*t", REG_EXTENDED); @@ -1036,6 +1067,14 @@ int PaeInput::getNote( const char* incipit, pae::Note *note, pae::Measure *measu note->tie = 1; // reset 1 for the first note, >1 for next ones is incremented under } + // chord + regcomp(&re, "^[^ABCDEFG]*\\^", REG_EXTENDED); + int is_chord = regexec(&re, incipit + i + 1, 0, NULL, 0); + regfree(&re); + if ( is_chord == 0) { + note->chord = true; + } + oct = note->octave; measure->notes.push_back( *note ); @@ -1047,14 +1086,14 @@ int PaeInput::getNote( const char* incipit, pae::Note *note, pae::Measure *measu note->clear(); // write back the values we need to save - note->octave = oct; // save octave // tuplets. Decrease the current number is we are in a tuplet // i.e. tuplet_num > 0 // al the other values just need to be in the first note - if (tuplet_num > 0) + if (tuplet_num > 0) { note->tuplet_note = --tuplet_num; + } // grace notes note->acciaccatura = false; @@ -1130,7 +1169,8 @@ void PaeInput::parseNote(pae::Note *note) { } element = rest; - } else { + } + else { Note *mnote = new Note(); mnote->SetPname(note->pitch); @@ -1144,8 +1184,9 @@ void PaeInput::parseNote(pae::Note *note) { mnote->SetFermata(PLACE_above); // always above for now } - if (note->trill == true) + if (note->trill == true) { mnote->m_embellishment = EMB_TRILL; + } if (m_last_tied_note != NULL) { mnote->SetTie(TIE_t); @@ -1162,17 +1203,20 @@ void PaeInput::parseNote(pae::Note *note) { } // Does this note have a clef change? push it before everyting else - if (note->clef) + if (note->clef) { addLayerElement(note->clef); + } // Same thing for time changes // You can find this sometimes - if (note->meter) + if (note->meter) { addLayerElement(note->meter); + } // Handle key change. Evil if done in a beam - if (note->key) + if (note->key) { addLayerElement(note->key); + } // Acciaccaturas are similar but do not get beamed (do they) // this case is simpler. NOTE a note can not be acciacctura AND appoggiatura @@ -1205,18 +1249,38 @@ void PaeInput::parseNote(pae::Note *note) { pushContainer(newTuplet); } - + // note in a chord + if ( (note->chord) ) { + Note *mnote = dynamic_cast(element); + assert( mnote ); + // first note? + if (!m_is_in_chord) { + Chord *chord = new Chord(); + chord->SetDur(mnote->GetDur()); + pushContainer(chord); + m_is_in_chord = true; + } + } + // Add the note to the current container addLayerElement(element); // the last note counts always '1' // insert the tuplet elem // and reset the tuplet counter - if (note->tuplet_note == 1) + if (note->tuplet_note == 1) { popContainer(); + } - if (note->beam == BEAM_TERMINAL) + if (note->beam == BEAM_TERMINAL) { popContainer(); + } + + // last note of a chord + if (!note->chord && m_is_in_chord) { + popContainer(); + m_is_in_chord = false; + } } void PaeInput::pushContainer(LayerElement *container) { @@ -1226,10 +1290,13 @@ void PaeInput::pushContainer(LayerElement *container) { void PaeInput::popContainer() { //assert(m_nested_objects.size() > 0); - if (m_nested_objects.size() == 0) + if (m_nested_objects.size() == 0) { LogError("PaeInput::popContainer: tried to pop an object from empty stack. Cross-measure objects (tuplets, beams) are not supported."); - else + + } + else { m_nested_objects.pop_back(); + } } void PaeInput::addLayerElement(LayerElement *element) { @@ -1247,8 +1314,14 @@ void PaeInput::addLayerElement(LayerElement *element) { assert( tuplet ); tuplet->AddLayerElement( element ); } + else if ( bottom->Is() == CHORD ) { + Chord *chord = dynamic_cast( bottom ); + assert( chord ); + chord->AddLayerElement( element ); + } - } else { + } + else { m_layer->AddLayerElement(element); } } @@ -1282,8 +1355,9 @@ void PaeInput::getAtRecordKeyValue(char *key, char* value, memset(value, EMPTY, MAX_DATA_LEN); - if (length == 0) + if (length == 0) { return; + } char ch; int index = 0; @@ -1305,8 +1379,7 @@ void PaeInput::getAtRecordKeyValue(char *key, char* value, ch = input[index]; // Should never happen - if (count >= MAX_DATA_LEN) - return; + if (count >= MAX_DATA_LEN) return; key[count] = ch; count++; @@ -1321,8 +1394,8 @@ void PaeInput::getAtRecordKeyValue(char *key, char* value, SKIPSPACE // Also should never happen - if (strlen(&input[index]) > MAX_DATA_LEN) - return; + if (strlen(&input[index]) > MAX_DATA_LEN) return; + strcpy(value, &input[index]); // Thruncate string to first space From 8376d315ef83e7319d94558abbd0bb68ac6da4a8 Mon Sep 17 00:00:00 2001 From: Laurent Pugin Date: Thu, 24 Sep 2015 20:27:30 +0200 Subject: [PATCH 36/85] Basics for reading musicxml --- include/vrv/iomusxml.h | 56 +--- include/vrv/toolkit.h | 3 +- src/iomusxml.cpp | 641 ++--------------------------------------- src/toolkit.cpp | 8 +- tools/main.cpp | 4 +- 5 files changed, 54 insertions(+), 658 deletions(-) diff --git a/include/vrv/iomusxml.h b/include/vrv/iomusxml.h index b55cd84afa5..8acb9c738ef 100644 --- a/include/vrv/iomusxml.h +++ b/include/vrv/iomusxml.h @@ -9,6 +9,11 @@ #ifndef __VRV_IOMUSXML_H__ #define __VRV_IOMUSXML_H__ +#include +#include + +//---------------------------------------------------------------------------- + #include "io.h" #include "pugixml.hpp" @@ -35,58 +40,23 @@ class Tuplet; // This class is not up-to-date //---------------------------------------------------------------------------- -class XMLOutput: public FileOutputStream +class XmlInput: public FileInputStream { public: // constructors and destructors - XMLOutput( Doc *doc, std::string filename ); - virtual ~XMLOutput(); + XmlInput(Doc *doc, std::string filename); + virtual ~XmlInput(); - virtual bool ExportFile( ); + virtual bool ImportFile( ); + virtual bool ImportString(std::string musicxml); private: - - virtual bool WriteDoc( Doc *doc ); - // logical - bool WriteStaff( Staff *staff ); - bool WriteLayer( Layer *layer ); - bool WriteLayerElement( LayerElement *element ); - // layout - bool WriteLayout( Doc *layout ); - bool WritePage( Page *page ); - bool WriteSystem( System *system ); - bool WriteLaidOutStaff( Staff *laidOutStaff ); - bool WriteLaidOutLayer( Layer *laidOutLayer ); - bool WriteLaidOutLayerElement( LayerElement *laidOutLayerElement ); - - void WriteClef(LayerElement *element); - void WriteKey(LayerElement *element); - void WriteTime(LayerElement *element); - void WriteNoteOrRest(LayerElement *element); - void WriteMultiMeasureRest(Rest *r); - void CreateAttributes(); - void SetTie(pugi::xml_node xml_note, bool last); - void CreateRestsForMultiMeasure(); + bool ReadXml(pugi::xml_node root); private: std::string m_filename; - - pugi::xml_node m_xml_score; - pugi::xml_node m_xml_part; - pugi::xml_node m_xml_measure; - pugi::xml_node m_xml_attributes; - pugi::xml_node m_xml_measure_style; - pugi::xml_node m_xml_last_note; - pugi::xml_document m_xml_doc; - pugi::xml_node m_xml_current_clef; - - MeterSig *m_current_time; - Beam *m_current_beam; - bool m_in_beam; - bool m_tied; - int m_multimeasure_rests; - - int m_measure_count; + /** The parts are read as a vector of systems */ + std::vector m_parts; }; } // namespace vrv { diff --git a/include/vrv/toolkit.h b/include/vrv/toolkit.h index debac7e3094..d558977ddd3 100644 --- a/include/vrv/toolkit.h +++ b/include/vrv/toolkit.h @@ -27,7 +27,8 @@ namespace vrv { typedef enum _file_formats { mei_file = 0, pae_file, - darms_file + darms_file, + xml_file } ConvertFileFormat; diff --git a/src/iomusxml.cpp b/src/iomusxml.cpp index 436ac0096f0..a0ac1a3cdfd 100644 --- a/src/iomusxml.cpp +++ b/src/iomusxml.cpp @@ -28,639 +28,58 @@ namespace vrv { //---------------------------------------------------------------------------- -// XMLOutput +// XmlInput //---------------------------------------------------------------------------- -XMLOutput::XMLOutput( Doc *doc, std::string filename ) : +XmlInput::XmlInput(Doc *doc, std::string filename) : // This is pretty bad. We open a bad fileoutputstream as we don't use it -FileOutputStream( doc ) + FileInputStream(doc) { m_filename = filename; - m_measure_count = 0; -/* m_xml_attributes = NULL; - m_xml_current_clef = NULL; - m_xml_measure_style = NULL; - m_xml_last_note = NULL; -*/ - m_current_time = NULL; - m_current_beam = NULL; - m_in_beam = false; - m_tied = false; - m_multimeasure_rests = 0; - -} - -XMLOutput::~XMLOutput() -{ -} - -bool XMLOutput::ExportFile( ) -{ - /* - // do this or finale will barf, versione 3.0 for now - TiXmlUnknown *unk = new TiXmlUnknown; - //unk->SetValue("!DOCTYPE score-partwise PUBLIC \"-//Recordare//DTD MusicXML 3.0 Partwise//EN\" \"http://www.musicxml.org/dtds/partwise.dtd\""); - unk->SetValue("!DOCTYPE score-timewise PUBLIC \"-//Recordare//DTD MusicXML 2.0 Timewise//EN\" \"http://www.musicxml.org/dtds/timewise.dtd\""); - m_xml_doc->LinkEndChild(unk); - */ - - // this starts the call of all the functors - m_doc->Save( this ); - - m_xml_doc.save_file( m_filename.c_str() ); - - return true; -} - -bool XMLOutput::WriteDoc( Doc *doc ) -{ - LogDebug("Doc"); - - // Write the partwise declaration - // the MusicXML "score-partwise" does not map to our MusScore - - m_xml_score = m_xml_doc.append_child("score-timewise"); - - // hardcode a voice for noew - pugi::xml_node plist = m_xml_score.append_child("part-list"); - pugi::xml_node spart = plist.append_child("score-part"); - spart.append_attribute("id") = "P1"; - - pugi::xml_node pname = spart.append_child("part-name"); - pname.append_child(pugi::node_pcdata).set_value("Example Music"); - - /* - spart->LinkEndChild(pname); - plist->LinkEndChild(spart); - - m_xml_score->LinkEndChild(plist); - m_xml_doc->LinkEndChild(m_xml_score); - */ - - return true; -} - - -/* -bool XMLOutput::WriteMeasure( Measure *measure ) -//bool XMLOutput::WriteMeiMeasure( Measure *meiMeasure, Measure *measure ) -{ - std::string num; - - // Create multimeasure rests - if (m_multimeasure_rests > 0 ) - CreateRestsForMultiMeasure(); - - m_measure_count++; - num << m_measure_count; - LogDebug("Measure %i", m_measure_count); - - // go on and create this measure - m_xml_measure = new TiXmlElement("measure"); - m_xml_measure->SetAttribute("number", num); - m_xml_score->LinkEndChild(m_xml_measure); - - - // reset clef - m_xml_current_clef = NULL; - - //m_xml_part->LinkEndChild(m_xml_measure); - - return true; -} -*/ // ax2.3 - -bool XMLOutput::WriteStaff( Staff *staff ) -//bool XMLOutput::WriteMeiStaff( Staff *meiStaff, Staff *staff ) -{ - LogDebug("Staff"); - - m_xml_part = m_xml_measure.append_child("part"); - m_xml_part.append_attribute("id") = "P1"; - - // in first measure set the divisions value in - if (m_measure_count == 1) { - m_xml_attributes = m_xml_part.append_child("attributes"); - pugi::xml_node divisions = m_xml_attributes.append_child("divisions"); - //TiXmlText *divval = new TiXmlText("4"); // no more than sixteenths for now - divisions.append_child(pugi::node_pcdata).set_value("4"); - /* - divisions->LinkEndChild(divval); - m_xml_attributes->LinkEndChild(divisions); - m_xml_part->LinkEndChild(m_xml_attributes); - */ - } - - return true; } -bool XMLOutput::WriteLayer( Layer *layer ) -//bool XMLOutput::WriteMeiLayer( Layer *meiLayer, Layer *layer ) +XmlInput::~XmlInput() { - LogDebug("Layer"); - return true; } - -bool XMLOutput::WriteLayerElement( LayerElement *element ) -{ - LogDebug("Layer Elem"); - - if (dynamic_cast(element)) { - WriteClef(element); - } else if (dynamic_cast(element)) { - WriteKey(element); - } else if (dynamic_cast(element)) { - WriteTime(element); - } else if (dynamic_cast(element) || dynamic_cast(element)) { - WriteNoteOrRest(element); - } else if (dynamic_cast(element)) { - m_current_beam = dynamic_cast(element); - } else if (dynamic_cast(element)) { - // add tie to last note - // continuation of ties is made with a and - // in the same note - SetTie(m_xml_last_note, false); - } - // LogDebug("---- %s", element->GetClassName().c_str()); - - return true; - } - - - - -bool XMLOutput::WriteLayout( Doc *layout ) -{ - LogDebug("Layout"); - return true; -} - -bool XMLOutput::WritePage( Page *page ) -{ - LogDebug("Page"); - return true; -} - -bool XMLOutput::WriteSystem( System *system ) -{ - LogDebug("System"); - return true; -} - -bool XMLOutput::WriteLaidOutStaff( Staff *laidOutStaff ) -{ - LogDebug("Laid staff"); - return true; -} - -bool XMLOutput::WriteLaidOutLayer( Layer *laidOutLayer ) -{ LogDebug("Laid layer"); - return true; - -} - -bool XMLOutput::WriteLaidOutLayerElement( LayerElement *laidOutLayerElement ) +bool XmlInput::ImportFile() { - LogDebug("Laid Layer Elem"); - return true; -} - - -void XMLOutput::WriteClef(LayerElement *element) { - std::string sign, line; - - // Create the attributes elem - // or use existing one, all the attribute changes - // go in the same - CreateAttributes(); - - //Clef *clef = dynamic_cast(element); - - /* - switch (clef->m_clefId) { - case SOL1: sign = "G"; line = "1"; break; - case SOL2: sign = "G"; line = "2"; break; - case UT1: sign = "C"; line = "1"; break; - case UT2: sign = "C"; line = "2"; break; - case UT3: sign = "C"; line = "3"; break; - case UT4: sign = "C"; line = "4"; break; - case UT5: sign = "C"; line = "5"; break; - case FA3: sign = "F"; line = "3"; break; - case FA4: sign = "F"; line = "4"; break; - case FA5: sign = "F"; line = "5"; break; - default: break; - } - */ - - //Create the element - pugi::xml_node xclef = m_xml_attributes.append_child("clef"); - - // Create the element and link to it it's text - pugi::xml_node xsign = xclef.append_child("sign"); - xsign.append_child(pugi::node_pcdata).set_value(sign.c_str()); - //TiXmlText *xsignt = new TiXmlText(sign.c_str()); - //xsign->LinkEndChild(xsignt); - // Insert it into the - //xclef->LinkEndChild(xsign); - - // Create the element and link to it it's text - pugi::xml_node xline = xclef.append_child("line"); - xline.append_child(pugi::node_pcdata).set_value(line.c_str()); - //TiXmlText *xlinet = new TiXmlText(line.c_str()); - //xline->LinkEndChild(xlinet); - // Insert it into the - //xclef->LinkEndChild(xline); - - // place clef into - //m_xml_attributes->LinkEndChild(xclef); - m_xml_current_clef = xclef; - -} - -void XMLOutput::WriteKey(LayerElement *element) { - KeySig* key = dynamic_cast(element); - - // Check for attrib element as above - // or use existing one, all the attribute changes - // go in the same - CreateAttributes(); - - // create tompost elem - pugi::xml_node xkey = m_xml_attributes.append_child("key"); - - // Convert the number of alterations to string - std::stringstream n_alter; - if (key->GetAlterationType() == ACCIDENTAL_EXPLICIT_f) - // flats are negative numbers - n_alter << -key->GetAlterationNumber(); - else - n_alter << key->GetAlterationNumber(); - - //create node with the number of alterations - pugi::xml_node xfifths = xkey.append_child("fifths"); - xfifths.append_child(pugi::node_pcdata).set_value(n_alter.str().c_str()); - //TiXmlText *xftxt = new TiXmlText(n_alter.str().c_str()); - //xfifths->LinkEndChild(xftxt); - // add it to the key elem - //xkey->LinkEndChild(xfifths); - - //I dont know what musicxml does with the tag - //bmaybe it is just to annoy programmers using tinyxml - //finale sets this always to major - pugi::xml_node mode = xkey.append_child("mode"); - mode.append_child(pugi::node_pcdata).set_value("major"); - //TiXmlText *major = new TiXmlText("major"); - //mode->LinkEndChild(major); - // add it to the key elem - //xkey->LinkEndChild(mode); - - // Obviously the order in which and