示例#1
0
data_STEMDIRECTION LayerElement::GetDrawingStemDir()
{
    if (this->Is() == NOTE) {
        Note *note = dynamic_cast<Note*>(this);
        assert( note );
        return note->GetDrawingStemDir();
    }
    if (this->Is() == CHORD) {
        Chord *chord = dynamic_cast<Chord*>(this);
        assert( chord );
        return chord->GetDrawingStemDir();
    }
    return STEMDIRECTION_NONE;
}
示例#2
0
data_STEMDIRECTION View::GetTupletCoordinates(Tuplet *tuplet, Layer *layer, Point *start, Point *end, Point *center)
{
    assert(tuplet);
    assert(layer);
    assert(start);
    assert(end);
    assert(center);

    Point first, last;
    int x, y;
    data_STEMDIRECTION direction = STEMDIRECTION_up;

    ListOfObjects *tupletChildren = tuplet->GetList(tuplet);
    LayerElement *firstElement = dynamic_cast<LayerElement *>(tupletChildren->front());
    LayerElement *lastElement = dynamic_cast<LayerElement *>(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
        x = firstElement->GetDrawingX()
            + (lastElement->GetDrawingX() - firstElement->GetDrawingX() + lastElement->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
        Note *firstNote = dynamic_cast<Note *>(tuplet->FindChildByType(NOTE));
        Note *lastNote = dynamic_cast<Note *>(tuplet->FindChildByType(NOTE, UNLIMITED_DEPTH, BACKWARD));

        y = firstElement->GetDrawingY();
        if (firstNote && lastNote) {
            if (firstNote->GetDrawingStemDir() == STEMDIRECTION_up)
                y = lastNote->GetDrawingStemEnd().y
                    + (firstNote->GetDrawingStemEnd().y - lastNote->GetDrawingStemEnd().y) / 2 + TUPLET_OFFSET;
            else
                y = lastNote->GetDrawingStemEnd().y
                    + (firstNote->GetDrawingStemEnd().y - lastNote->GetDrawingStemEnd().y) / 2 - TUPLET_OFFSET;
        }

        // Copy the generated coordinates
        center->x = x;
        center->y = y;
        direction = firstNote->GetDrawingStemDir(); // stem direction is the same for all notes
    }
    else {
        // There are unbeamed notes of two different beams
        // treat all the notes as unbeamed
        int ups = 0, downs = 0; // quantity of up- and down-stems

        // In this case use the center of the notehead to calculate the exact center
        // as it looks better
        x = firstElement->GetDrawingX()
            + (lastElement->GetDrawingX() - firstElement->GetDrawingX() + lastElement->m_selfBB_x2) / 2;

        // Return the start and end position for the brackes
        // starting from the first edge and last of the BBoxes
        start->x = firstElement->m_selfBB_x1 + firstElement->GetDrawingX();
        end->x = lastElement->m_selfBB_x2 + lastElement->GetDrawingX();

        // The first step is to calculate all the stem directions
        // cycle into the elements and count the up and down dirs
        ListOfObjects::iterator iter = tupletChildren->begin();
        while (iter != tupletChildren->end()) {
            if ((*iter)->Is() == NOTE) {
                Note *currentNote = dynamic_cast<Note *>(*iter);
                assert(currentNote);
                if (currentNote->GetDrawingStemDir() == STEMDIRECTION_up)
                    ups++;
                else
                    downs++;
            }
            ++iter;
        }
        // true means up
        direction = ups > downs ? STEMDIRECTION_up : STEMDIRECTION_down;

        // if ups or downs are 0, it means all the stems go in the same direction
        if (ups == 0 || downs == 0) {

            Note *firstNote = dynamic_cast<Note *>(tuplet->FindChildByType(NOTE));
            Note *lastNote = dynamic_cast<Note *>(tuplet->FindChildByType(NOTE, UNLIMITED_DEPTH, BACKWARD));

            // Calculate the average between the first and last stem
            // set center, start and end too.
            y = firstElement->GetDrawingY();
            if (firstNote && lastNote) {
                if (direction == STEMDIRECTION_up) { // up
                    y = lastNote->GetDrawingStemEnd().y
                        + (firstNote->GetDrawingStemEnd().y - lastNote->GetDrawingStemEnd().y) / 2 + TUPLET_OFFSET;
                    start->y = firstNote->GetDrawingStemEnd().y + TUPLET_OFFSET;
                    end->y = lastNote->GetDrawingStemEnd().y + TUPLET_OFFSET;
                }
                else {
                    y = lastNote->GetDrawingStemEnd().y
                        + (firstNote->GetDrawingStemEnd().y - lastNote->GetDrawingStemEnd().y) / 2 - TUPLET_OFFSET;
                    start->y = firstNote->GetDrawingStemEnd().y - TUPLET_OFFSET;
                    end->y = lastNote->GetDrawingStemEnd().y - TUPLET_OFFSET;
                }
            }

            // Now we cycle again in all the intermediate notes (i.e. we start from the second note
            // and stop at last -1)
            // We will see if the position of the note is more (or less for down stems) of the calculated
            // average. In this case we offset down or up all the points
            iter = tupletChildren->begin();
            while (iter != tupletChildren->end()) {
                if ((*iter)->Is() == NOTE) {
                    Note *currentNote = dynamic_cast<Note *>(*iter);
                    assert(currentNote);

                    if (direction == STEMDIRECTION_up) {
                        // The note is more than the avg, adjust to y the difference
                        // from this note to the avg
                        if (currentNote->GetDrawingStemEnd().y + TUPLET_OFFSET > y) {
                            int offset = y - (currentNote->GetDrawingStemEnd().y + TUPLET_OFFSET);
                            y -= offset;
                            end->y -= offset;
                            start->y -= offset;
                        }
                    }
                    else {
                        if (currentNote->GetDrawingStemEnd().y - TUPLET_OFFSET < y) {
                            int offset = y - (currentNote->GetDrawingStemEnd().y - TUPLET_OFFSET);
                            y -= offset;
                            end->y -= offset;
                            start->y -= offset;
                        }
                    }
                }
                ++iter;
            }
        }
        else {
            // two-directional beams
            // this case is similar to the above, but the bracket is only horizontal
            // y is 0 because the final y pos is above the tallest stem
            y = 0;

            // Find the tallest stem and set y to it (with the offset distance)
            iter = tupletChildren->begin();
            while (iter != tupletChildren->end()) {
                if ((*iter)->Is() == NOTE) {
                    Note *currentNote = dynamic_cast<Note *>(*iter);
                    assert(currentNote);

                    if (currentNote->GetDrawingStemDir() == direction) {
                        if (direction == STEMDIRECTION_up) {
                            if (y == 0 || currentNote->GetDrawingStemEnd().y + TUPLET_OFFSET >= y)
                                y = currentNote->GetDrawingStemEnd().y + TUPLET_OFFSET;
                        }
                        else {
                            if (y == 0 || currentNote->GetDrawingStemEnd().y - TUPLET_OFFSET <= y)
                                y = currentNote->GetDrawingStemEnd().y - TUPLET_OFFSET;
                        }
                    }
                    else {
                        // do none for now
                        // but if a notehead with a reversed stem is taller that the last
                        // calculated y, we need to offset
                    }
                }
                ++iter;
            }

            // end and start are on the same line (and so il center when set later)
            end->y = start->y = y;
        }
    }

    center->x = x;
    center->y = y;
    return direction;
}
示例#3
0
void View::DrawLigatureNote(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff)
{
    assert(dc);
    assert(element);
    assert(layer);
    assert(staff);

    LogDebug("DrawLigatureNote");
    Note *note = dynamic_cast<Note *>(element);
    assert(note);

    int xn, x1, x2, y, y1, y2, y3, y4;
    // int yy2, y5; // unused
    int verticalCenter, up, epaisseur;

    epaisseur = std::max(2, m_doc->GetDrawingBeamWidth(staff->m_drawingStaffSize, false) / 2);
    xn = element->GetDrawingX();
    y = 99;
    //    LogDebug("DrawLigatureNote: _ligObliqua=%d drawingX=%d y=%d", note->m_ligObliqua, xn, y);
    LogDebug("DrawLigatureNote: drawingX=%d y=%d", xn, y);

    /*
     if ((note->m_lig==LIG_MEDIAL) || (note->m_lig==LIG_TERMINAL))
     {
     CalculateLigaturePosX(element, layer, staff);
     }
     else
     */ {
        xn = element->GetDrawingX();
    }

    // Compute the dimensions of the rectangle
    x1 = xn - m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize);
    x2 = xn + m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize);
    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); // part of the frame that overflows
    y4 = (int)(y2 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) / 2);

    // if (!note->m_ligObliqua && (!View::s_drawingLigObliqua))	// rectangular notes, incl. ligature
    {
        if (note->GetColored() != BOOLEAN_true) { //	double the bases of rectangles
            DrawObliquePolygon(dc, x1, y1, x2, y1, -epaisseur);
            DrawObliquePolygon(dc, x1, y2, x2, y2, epaisseur);
        }
        else
            DrawFilledRectangle(dc, x1, y1, x2, y2); //
        // ENZ correction of x2

        DrawVerticalLine(dc, y3, y4, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize)); // lateral brace
        DrawVerticalLine(dc, y3, y4, x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));
    }
    /*
     else			// handle obliques
     {
     if (!View::s_drawingLigObliqua)	// 1st pass: Initial flagStemHeight
     {
     DrawVerticalLine (dc,y3,y4,x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));
     View::s_drawingLigObliqua = true;
     //oblique = false;
     //			if (val == DUR_1)	// left tail up if DUR_1
     //				queue_lig = true;
     }
     else	// 2nd pass: oblique lines and final flagStemHeighte
     {
     x1 -=  m_doc->m_drawingBrevisWidth[staff->m_drawingStaffSize] * 2;	// auto advance

     y1 = *View::s_drawingLigY - m_doc->GetDrawingUnit(staff->m_drawingStaffSize);	// ligat_y contains original y
     yy2 = y2;
     y5 = y1+ m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize); y2 +=
     m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize);            // go up a
     INTERL

     if (note->GetColored()==BOOLEAN_true)
     DrawObliquePolygon (dc,  x1,  y1,  x2,  yy2, m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize));
     else
     {	DrawObliquePolygon (dc,  x1,  y1,  x2,  yy2, 5);
     DrawObliquePolygon (dc,  x1,  y5,  x2,  y2, -5);
     }
     DrawVerticalLine (dc,y3,y4,x2,m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));	// enclosure
     flagStemHeighte

     View::s_drawingLigObliqua = false;
     //			queue_lig = false;	// ??defuses alg.queue DUR_BR??

     }
     }

     if (note->m_lig)	// remember positions from one note to another; connect notes by bars
     {
     *(View::s_drawingLigX+1) = x2; *(View::s_drawingLigY+1) = y;	// connect ligature beamed notes by bar
     flagStemHeightes
     //if (in(x1,(*View::s_drawingLigX)-2,(*View::s_drawingLigX)+2) || (this->fligat && this->lat && !Note1::marq_obl))
     // the latest conditions to allow previous ligature flagStemHeighte
     //	DrawVerticalLine (dc, *ligat_y, y1, (this->fligat && this->lat) ? x2: x1, m_doc->m_parameters.m_stemWidth); //
     ax2 - drawing flagStemHeight
     lines missing
     *View::s_drawingLigX = *(View::s_drawingLigX + 1);
     *View::s_drawingLigY = *(View::s_drawingLigY + 1);
     }


     y3 = y2 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*6;

     if (note->m_lig)
     {
     if (note->m_dur == DUR_BR) //  && this->queue_lig)	// tail left bottom: initial downward DUR_BR // ax2 - no
     support for queue_lig (see WG
     corrigeLigature)
     {
     DrawVerticalLine (dc, y2, y3, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));
     }
     else if (note->m_dur == DUR_LG) // && !this->queue_lig) // DUR_LG ligature, tail right down // ax2 - no support
     for queue_lig
     {
     DrawVerticalLine (dc, y2, y3, x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));
     }
     else if (note->m_dur == DUR_1) // && this->queue_lig)	// queue gauche haut // ax2 - no support for queue_lig
     {
     y2 = y1 + m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*6;
     DrawVerticalLine (dc, y1, y2, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));
     }
     }
     else if (note->m_dur == DUR_LG)		// isolated DUR_LG: tail like normal notes
     */
    if (note->GetActualDur() == DUR_LG) {
        verticalCenter = staff->GetDrawingY() - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * 2;
        // ENZ
        up = (y < verticalCenter) ? true : false;
        // ENZ
        if (note->GetDrawingStemDir() != STEMDIRECTION_NONE) {
            if (note->GetDrawingStemDir() == STEMDIRECTION_up) {
                up = true;
            }
            else {
                up = false;
            }
        }

        if (!up) {
            y3 = y1 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 8;
            y2 = y1;
        }
        else {
            y3 = y1 + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 6;
            y2 = y1;
        }
        DrawVerticalLine(dc, y2, y3, x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));
    }

    return;
}
示例#4
0
文件: artic.cpp 项目: DDMAL/verovio
int Artic::CalcArtic(FunctorParams *functorParams)
{
    FunctorDocParams *params = dynamic_cast<FunctorDocParams *>(functorParams);
    assert(params);

    /************** Get the parent and the stem direction **************/

    LayerElement *parent = NULL;
    Note *parentNote = NULL;
    Chord *parentChord = dynamic_cast<Chord *>(this->GetFirstParent(CHORD, 2));
    data_STEMDIRECTION stemDir = STEMDIRECTION_NONE;
    data_STAFFREL place = STAFFREL_NONE;

    if (!parentChord) {
        parentNote = dynamic_cast<Note *>(this->GetFirstParent(NOTE));
        parent = parentNote;
    }
    else {
        parent = parentChord;
    }

    if (!parentChord && !parentNote) {
        // no parent chord or note, nothing we can do...
        return FUNCTOR_CONTINUE;
    }

    Staff *staff = dynamic_cast<Staff *>(this->GetFirstParent(STAFF));
    assert(staff);
    Layer *layer = dynamic_cast<Layer *>(this->GetFirstParent(LAYER));
    assert(layer);

    stemDir = parentNote ? parentNote->GetDrawingStemDir() : parentChord->GetDrawingStemDir();

    /************** placement **************/

    bool allowAbove = true;

    // for now we ignore within @place
    if (this->HasPlace() && (this->GetPlace() != STAFFREL_within)) {
        place = this->GetPlace();
        // If we have a place indication do not allow to be changed to above
        allowAbove = false;
    }
    else if (layer->GetDrawingStemDir() != STEMDIRECTION_NONE) {
        place = (layer->GetDrawingStemDir() == STEMDIRECTION_up) ? STAFFREL_above : STAFFREL_below;
        // If we have more than one layer do not allow to be changed to above
        allowAbove = false;
    }
    else if (stemDir == STEMDIRECTION_up)
        place = STAFFREL_below;
    else
        place = STAFFREL_above;

    /************** set it to both the inside and outside part **************/

    ArticPart *insidePart = this->GetInsidePart();
    ArticPart *outsidePart = this->GetOutsidePart();

    if (insidePart) {
        insidePart->SetPlace(place);
    }

    if (outsidePart) {
        // If allowAbove is true it will place the above if the content requires so (even if place below if given)
        if (place == STAFFREL_below && allowAbove && outsidePart->AlwaysAbove()) place = STAFFREL_above;
        outsidePart->SetPlace(place);
    }

    /************** calculate the y position **************/

    Staff *staffAbove = NULL;
    Staff *staffBelow = NULL;

    // Cross-staff handling of articulation will need to be re-thought. We can look at assiging a cross-staff to the
    // appropriate ArticPart
    // (see below) - For chords, we need to distinguish cross-staff chords and cross-staff chord notes
    if (parent->m_crossStaff && parent->m_crossLayer) {
        staff = parent->m_crossStaff;
        staffAbove = staff;
        staffBelow = staff;
    }
    else if (parentChord) {
        parentChord->GetCrossStaffExtremes(staffAbove, staffBelow);
    }

    int staffYBottom = -params->m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize);
    // Avoid in artic to be in legder lines
    int yInAbove = std::max(
        parent->GetDrawingTop(params->m_doc, staff->m_drawingStaffSize, false) - staff->GetDrawingY(), staffYBottom);
    int yInBelow
        = std::min(parent->GetDrawingBottom(params->m_doc, staff->m_drawingStaffSize, false) - staff->GetDrawingY(), 0);
    int yOutAbove = std::max(yInAbove, 0);
    int yOutBelow = std::min(yInBelow, staffYBottom);

    // Does not work properly with chords, needs rethinking - It might be better to make artic or articPart relative to
    // notes
    // The problem is that in MEI artic are children of chord element and not of the notes
    if (insidePart) {
        if (insidePart->GetPlace() == STAFFREL_above) {
            insidePart->SetDrawingYRel(yInAbove);
            insidePart->m_crossStaff = staffAbove;
        }
        else {
            insidePart->SetDrawingYRel(yInBelow);
            insidePart->m_crossStaff = staffBelow;
        }
    }

    if (outsidePart) {
        if (outsidePart->GetPlace() == STAFFREL_above) {
            outsidePart->SetDrawingYRel(yOutAbove);
            outsidePart->m_crossStaff = staffAbove;
        }
        else {
            outsidePart->SetDrawingYRel(yOutBelow);
            outsidePart->m_crossStaff = staffBelow;
        }
    }

    // If we have both an inside and outside part we need to move the outside part away when they are both on the same
    // side
    if (insidePart && outsidePart) {

        int margin = params->m_doc->GetTopMargin(insidePart->GetClassId())
            * params->m_doc->GetDrawingUnit(staff->m_drawingStaffSize) / PARAM_DENOMINATOR;

        if (insidePart->GetPlace() == outsidePart->GetPlace()) {
            if (insidePart->GetPlace() == STAFFREL_above) {
                int inTop = insidePart->GetContentTop();
                int outBottom = outsidePart->GetContentBottom();
                if (inTop > outBottom)
                    outsidePart->SetDrawingYRel(outsidePart->GetDrawingYRel() + inTop - outBottom + margin);
            }
            else {
                int inBottom = insidePart->GetContentBottom();
                int outTop = outsidePart->GetContentTop();
                if (inBottom < outTop)
                    outsidePart->SetDrawingYRel(outsidePart->GetDrawingYRel() + outTop - inBottom + margin);
            }
        }
    }

    return FUNCTOR_SIBLINGS;
}
示例#5
0
void View::DrawMaximaToBrevis(DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff)
{
    assert(dc);
    assert(element);
    assert(layer);
    assert(staff);

    Note *note = dynamic_cast<Note *>(element);
    assert(note);

    int xn, xLeft, xRight, yTop, yBottom, y3, y4;
    // int yy2, y5; // unused
    int verticalCenter, up, height;
    bool mensural_black = (staff->m_drawingNotationType == NOTATIONTYPE_mensural_black);
    bool fillNotehead = (mensural_black || note->GetColored()) && !(mensural_black && note->GetColored());
    height = m_doc->GetDrawingBeamWidth(staff->m_drawingStaffSize, false) / 2;
    xn = element->GetDrawingX();

    // Calculate size of the rectangle
    xLeft = xn - m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize);
    xRight = xn + m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize);
    if (note->GetActualDur() == DUR_MX) {
        // Maxima is twice the width of brevis
        xLeft -= m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize);
        xRight += m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize);
    }
    yTop = y + m_doc->GetDrawingUnit(staff->m_drawingStaffSize);
    yBottom = y - m_doc->GetDrawingUnit(staff->m_drawingStaffSize);

    y3 = yTop;
    y4 = yBottom;
    if (!mensural_black) {
        y3 += (int)m_doc->GetDrawingUnit(staff->m_drawingStaffSize) / 2; // partie d'encadrement qui depasse
        y4 -= (int)m_doc->GetDrawingUnit(staff->m_drawingStaffSize) / 2;
    }

    if (!fillNotehead) {
        //	double the bases of rectangles
        DrawObliquePolygon(dc, xLeft, yTop, xRight, yTop, -height);
        DrawObliquePolygon(dc, xLeft, yBottom, xRight, yBottom, height);
    }
    else {
        DrawFilledRectangle(dc, xLeft, yTop, xRight, yBottom);
    }

    DrawVerticalLine(dc, y3, y4, xLeft, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize)); // corset lateral
    DrawVerticalLine(dc, y3, y4, xRight, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));

    // stem
    if (note->GetActualDur() < DUR_BR) {
        verticalCenter = staff->GetDrawingY() - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * 2;
        up = (y < verticalCenter) ? true : false;
        if (note->GetDrawingStemDir() != STEMDIRECTION_NONE) {
            if (note->GetDrawingStemDir() == STEMDIRECTION_up) {
                up = true;
            }
            else {
                up = false;
            }
        }

        if (!up) {
            y3 = yTop - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 8;
            yBottom = yTop;
        }
        else {
            y3 = yTop + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 6;
            yBottom = yTop;
        }
        DrawVerticalLine(dc, yBottom, y3, xRight, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));
    }

    return;
}
示例#6
0
void View::DrawSlurInitial(FloatingCurvePositioner *curve, Slur *slur, int x1, int x2, Staff *staff, char spanningType)
{
    Beam *parentBeam = NULL;
    Chord *startParentChord = NULL;
    Chord *endParentChord = NULL;
    Note *startNote = NULL;
    Note *endNote = NULL;
    Chord *startChord = NULL;
    Chord *endChord = NULL;

    curvature_CURVEDIR drawingCurveDir = curvature_CURVEDIR_above;
    data_STEMDIRECTION startStemDir = STEMDIRECTION_NONE;
    data_STEMDIRECTION endStemDir = STEMDIRECTION_NONE;
    data_STEMDIRECTION stemDir = STEMDIRECTION_NONE;
    bool isGraceToNoteSlur = false;
    int y1 = staff->GetDrawingY();
    int y2 = staff->GetDrawingY();

    /************** parent layers **************/

    LayerElement *start = dynamic_cast<LayerElement *>(slur->GetStart());
    LayerElement *end = dynamic_cast<LayerElement *>(slur->GetEnd());

    if (!start || !end) {
        // no start and end, obviously nothing to do...
        return;
    }

    if (start->Is(TIMESTAMP_ATTR) && end->Is(TIMESTAMP_ATTR)) {
        // for now ignore slur using 2 tstamps
        return;
    }

    if (start->Is(NOTE)) {
        startNote = dynamic_cast<Note *>(start);
        assert(startNote);
        startParentChord = startNote->IsChordTone();
        startStemDir = startNote->GetDrawingStemDir();
    }
    else if (start->Is(CHORD)) {
        startChord = dynamic_cast<Chord *>(start);
        assert(startChord);
        startStemDir = startChord->GetDrawingStemDir();
    }
    if (end->Is(NOTE)) {
        endNote = dynamic_cast<Note *>(end);
        assert(endNote);
        endParentChord = endNote->IsChordTone();
        endStemDir = endNote->GetDrawingStemDir();
    }
    else if (end->Is(CHORD)) {
        endChord = dynamic_cast<Chord *>(end);
        assert(endChord);
        endStemDir = endChord->GetDrawingStemDir();
    }

    if (startNote && endNote && startNote->IsGraceNote() && !endNote->IsGraceNote()) {
        isGraceToNoteSlur = true;
    }

    Layer *layer = NULL;
    LayerElement *layerElement = NULL;
    // For now, with timestamps, get the first layer. We should eventually look at the @layerident (not implemented)
    if (!start->Is(TIMESTAMP_ATTR)) {
        layer = dynamic_cast<Layer *>(start->GetFirstParent(LAYER));
        layerElement = start;
    }
    else {
        layer = dynamic_cast<Layer *>(end->GetFirstParent(LAYER));
        layerElement = end;
    }
    assert(layer);

    if (!start->Is(TIMESTAMP_ATTR) && !end->Is(TIMESTAMP_ATTR) && (spanningType == SPANNING_START_END)) {
        System *system = dynamic_cast<System *>(staff->GetFirstParent(SYSTEM));
        assert(system);
        // If we have a start to end situation, then store the curvedir in the slur for mixed drawing stem dir
        // situations
        if (system->HasMixedDrawingStemDir(start, end)) {
            slur->SetDrawingCurvedir(curvature_CURVEDIR_above);
        }
    }

    /************** calculate the radius for adjusting the x position **************/

    int startRadius = 0;
    if (!start->Is(TIMESTAMP_ATTR)) {
        startRadius = start->GetDrawingRadius(m_doc);
    }

    int endRadius = 0;
    if (!end->Is(TIMESTAMP_ATTR)) {
        endRadius = end->GetDrawingRadius(m_doc);
    }

    /************** note stem dir **************/

    if (spanningType == SPANNING_START_END) {
        stemDir = startStemDir;
    }
    // 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) {
        stemDir = startStemDir;
    }
    // Now this is the case when the tie is split but we are drawing the end of it
    else if (spanningType == SPANNING_END) {
        stemDir = endStemDir;
    }
    // Finally, slur accross an entire system; use the staff position and up (see below)
    else {
        stemDir = STEMDIRECTION_down;
    }

    /************** direction **************/

    data_STEMDIRECTION layerStemDir;

    // first should be the tie @curvedir
    if (slur->HasCurvedir()) {
        drawingCurveDir
            = (slur->GetCurvedir() == curvature_CURVEDIR_above) ? curvature_CURVEDIR_above : curvature_CURVEDIR_below;
    }
    // grace notes - always below unless we have a drawing stem direction on the layer
    else if (isGraceToNoteSlur && (layer->GetDrawingStemDir(layerElement) == STEMDIRECTION_NONE)) {
        drawingCurveDir = curvature_CURVEDIR_below;
    }
    // the normal case
    else if (slur->HasDrawingCurvedir()) {
        drawingCurveDir = slur->GetDrawingCurvedir();
    }
    // then layer direction trumps note direction
    else if (layer && ((layerStemDir = layer->GetDrawingStemDir(layerElement)) != STEMDIRECTION_NONE)) {
        drawingCurveDir = (layerStemDir == STEMDIRECTION_up) ? curvature_CURVEDIR_above : curvature_CURVEDIR_below;
    }
    // look if in a chord
    else if (startParentChord) {
        if (startParentChord->PositionInChord(startNote) < 0) {
            drawingCurveDir = curvature_CURVEDIR_below;
        }
        else if (startParentChord->PositionInChord(startNote) > 0) {
            drawingCurveDir = curvature_CURVEDIR_above;
        }
        // away from the stem if odd number (center note)
        else {
            drawingCurveDir = (stemDir != STEMDIRECTION_up) ? curvature_CURVEDIR_above : curvature_CURVEDIR_below;
        }
    }
    else if (stemDir == STEMDIRECTION_up) {
        drawingCurveDir = curvature_CURVEDIR_below;
    }
    else if (stemDir == 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;
        drawingCurveDir = (start->GetDrawingY() > center) ? curvature_CURVEDIR_above : curvature_CURVEDIR_below;
    }

    /************** adjusting y position **************/

    bool isShortSlur = false;
    if (x2 - x1 < 1 * 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)
        if (startParentChord) {
            startParentChord->GetYExtremes(yChordMax, yChordMin);
        }
        else if (startChord) {
            startChord->GetYExtremes(yChordMax, yChordMin);
        }
        // slur is up
        if (drawingCurveDir == curvature_CURVEDIR_above) {
            // P(^)
            if (startStemDir == STEMDIRECTION_down) y1 = start->GetDrawingTop(m_doc, staff->m_drawingStaffSize);
            //  d(^)d
            else if (isShortSlur) {
                y1 = start->GetDrawingTop(m_doc, staff->m_drawingStaffSize);
            }
            // same but in beam - adjust the x too
            else if ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start)) {
                y1 = start->GetDrawingTop(m_doc, staff->m_drawingStaffSize);
                x1 += startRadius - m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize);
            }
            // d(^)
            else {
                // put it on the side, move it left, but not if we have a @stamp
                if (!start->Is(TIMESTAMP_ATTR)) x1 += m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 4 / 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 (startStemDir == STEMDIRECTION_up) y1 = start->GetDrawingBottom(m_doc, staff->m_drawingStaffSize);
            // P(_)P
            else if (isShortSlur) {
                y1 = start->GetDrawingBottom(m_doc, staff->m_drawingStaffSize);
            }
            // same but in beam
            else if ((parentBeam = start->IsInBeam()) && !parentBeam->IsLastInBeam(start)) {
                y1 = start->GetDrawingBottom(m_doc, staff->m_drawingStaffSize);
                x1 -= startRadius - m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize);
            }
            // P(_)
            else {
                // put it on the side, but no need to move it left
                if (startChord || startParentChord)
                    y1 = yChordMin - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3;
                else
                    y1 = start->GetDrawingY() - m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3;
            }
        }
    }
    if ((spanningType == SPANNING_START_END) || (spanningType == SPANNING_END)) {
        // get the min max of the chord if any
        if (endParentChord) {
            endParentChord->GetYExtremes(yChordMax, yChordMin);
        }
        else if (endChord) {
            endChord->GetYExtremes(yChordMax, yChordMin);
        }
        // get the stem direction of the end
        // slur is up
        if (drawingCurveDir == curvature_CURVEDIR_above) {
            // (^)P
            if (endStemDir == STEMDIRECTION_down) y2 = end->GetDrawingTop(m_doc, staff->m_drawingStaffSize);
            // d(^)d
            else if (isShortSlur) {
                y2 = end->GetDrawingTop(m_doc, staff->m_drawingStaffSize);
            }
            // same but in beam - adjust the x too
            else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end)) {
                y2 = end->GetDrawingTop(m_doc, staff->m_drawingStaffSize);
                x2 += endRadius - m_doc->GetDrawingStemWidth(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) * 3;
                else
                    y2 = end->GetDrawingY() + m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 3;
            }
        }
        else {
            if (isGraceToNoteSlur) {
                if (endNote) {
                    y2 = endNote->GetDrawingY();
                    x2 -= m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * 2;
                    isShortSlur = true;
                }
                else {
                    y2 = y1;
                }
            }
            // (_)d
            else if (endStemDir == STEMDIRECTION_up)
                y2 = end->GetDrawingBottom(m_doc, staff->m_drawingStaffSize);
            // P(_)P
            else if (isShortSlur) {
                y2 = end->GetDrawingBottom(m_doc, staff->m_drawingStaffSize);
            }
            // same but in beam
            else if ((parentBeam = end->IsInBeam()) && !parentBeam->IsFirstInBeam(end)) {
                y2 = end->GetDrawingBottom(m_doc, staff->m_drawingStaffSize);
                //
                x2 -= endRadius - m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize);
            }
            // (_)P
            else {
                // put it on the side, move it right, but not if we have a @stamp2
                if (!end->Is(TIMESTAMP_ATTR)) x2 -= 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;
            }
        }
    }

    // Positions not attached to a note
    if (spanningType == SPANNING_START) {
        if (drawingCurveDir == curvature_CURVEDIR_above)
            y2 = std::max(staff->GetDrawingY(), y1);
        else
            y2 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y1);
    }
    if (end->Is(TIMESTAMP_ATTR)) {
        if (drawingCurveDir == curvature_CURVEDIR_above)
            y2 = std::max(staff->GetDrawingY(), y1);
        else
            y2 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y1);
    }
    if (spanningType == SPANNING_END) {
        if (drawingCurveDir == curvature_CURVEDIR_above)
            y1 = std::max(staff->GetDrawingY(), y2);
        else
            y1 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y2);
    }
    if (start->Is(TIMESTAMP_ATTR)) {
        if (drawingCurveDir == curvature_CURVEDIR_above)
            y1 = std::max(staff->GetDrawingY(), y2);
        else
            y1 = std::min(staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize), y2);
    }
    // slur accross an entire system; use the staff position
    else if (spanningType == SPANNING_MIDDLE) {
        // To be adjusted
        if (drawingCurveDir == curvature_CURVEDIR_above)
            y1 = staff->GetDrawingY();
        else
            y1 = staff->GetDrawingY() - m_doc->GetDrawingStaffSize(staff->m_drawingStaffSize);
        y2 = y1;
    }

    /************** y position **************/

    if (drawingCurveDir == curvature_CURVEDIR_above) {
        y1 += 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize);
        y2 += 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize);
    }
    else {
        y1 -= 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize);
        y2 -= 1 * m_doc->GetDrawingUnit(staff->m_drawingStaffSize);
    }

    Point points[4];
    points[0] = Point(x1, y1);
    points[3] = Point(x2, y2);

    float angle = CalcInitialSlur(curve, slur, staff, layer->GetN(), drawingCurveDir, points);
    int thickness = m_doc->GetDrawingUnit(staff->m_drawingStaffSize) * m_options->m_slurThickness.GetValue();

    curve->UpdateCurveParams(points, angle, thickness, drawingCurveDir);

    /************** articulation **************/

    // First get all artic children
    ClassIdComparison matchType(ARTIC);
    ArrayOfObjects artics;
    ArrayOfObjects::iterator articIter;

    // the normal case or start
    if ((spanningType == SPANNING_START_END) || (spanningType == SPANNING_START)) {
        start->FindAllChildByComparison(&artics, &matchType);
        // Then the @n of each first staffDef
        for (articIter = artics.begin(); articIter != artics.end(); ++articIter) {
            Artic *artic = dynamic_cast<Artic *>(*articIter);
            assert(artic);
            ArticPart *outsidePart = artic->GetOutsidePart();
            if (outsidePart) {
                if ((outsidePart->GetPlace().GetBasic() == STAFFREL_basic_above)
                    && (drawingCurveDir == curvature_CURVEDIR_above)) {
                    outsidePart->AddSlurPositioner(curve, true);
                }
                else if ((outsidePart->GetPlace().GetBasic() == STAFFREL_basic_below)
                    && (drawingCurveDir == curvature_CURVEDIR_below)) {
                    outsidePart->AddSlurPositioner(curve, true);
                }
            }
        }
    }
    // normal case or end
    if ((spanningType == SPANNING_START_END) || (spanningType == SPANNING_END)) {
        end->FindAllChildByComparison(&artics, &matchType);
        // Then the @n of each first staffDef
        for (articIter = artics.begin(); articIter != artics.end(); ++articIter) {
            Artic *artic = dynamic_cast<Artic *>(*articIter);
            assert(artic);
            ArticPart *outsidePart = artic->GetOutsidePart();
            if (outsidePart) {
                if ((outsidePart->GetPlace().GetBasic() == STAFFREL_basic_above)
                    && (drawingCurveDir == curvature_CURVEDIR_above)) {
                    outsidePart->AddSlurPositioner(curve, false);
                }
                else if ((outsidePart->GetPlace().GetBasic() == STAFFREL_basic_below)
                    && (drawingCurveDir == curvature_CURVEDIR_below)) {
                    outsidePart->AddSlurPositioner(curve, false);
                }
            }
        }
    }

    return;
}
示例#7
0
void View::DrawLigature ( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff )
{
    assert( dc );
    assert( element );
    assert( layer );
    assert( staff );

    Note *note = dynamic_cast<Note*>(element);
    assert( note );
    
    int xn, x1, x2, y1, y2, y3, y4;
    // int yy2, y5; // unused
    int verticalCenter, up, epaisseur;
    
    epaisseur = std::max (2, m_doc->GetDrawingBeamWidth(staff->m_drawingStaffSize, false) / 2);
    xn = element->GetDrawingX();
    
    /*
     if ((note->m_lig==LIG_MEDIAL) || (note->m_lig==LIG_TERMINAL))
     {
     CalculateLigaturePosX ( element, layer, staff );
     }
     else
     */{
         xn = element->GetDrawingX();
     }
    
    // calcul des dimensions du rectangle
    x1 = xn - m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize); x2 = xn +  m_doc->GetDrawingBrevisWidth(staff->m_drawingStaffSize);
    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);
    
    
    //if (!note->m_ligObliqua && (!View::s_drawingLigObliqua))	// notes rectangulaires, y c. en ligature
    {
        if (note->GetColored()!=BOOLEAN_true)
        {				//	double base des carrees
            DrawObliquePolygon ( dc, x1,  y1,  x2,  y1, -epaisseur );
            DrawObliquePolygon ( dc, x1,  y2,  x2,  y2, epaisseur );
        }
        else
            DrawFullRectangle( dc,x1,y1,x2,y2);	// dessine val carree pleine // ENZ correction de x2
        
        DrawVerticalLine ( dc, y3, y4, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );	// corset lateral
        DrawVerticalLine ( dc, y3, y4, x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );
    }
    /*
     else			// traitement des obliques
     {
     if (!View::s_drawingLigObliqua)	// 1e passage: ligne flagStemHeighte initiale
     {
     DrawVerticalLine (dc,y3,y4,x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );
     View::s_drawingLigObliqua = true;
     //oblique = OFF;
     //			if (val == DUR_1)	// queue gauche haut si DUR_1
     //				queue_lig = ON;
     }
     else	// 2e passage: lignes obl. et flagStemHeighte finale
     {
     x1 -=  m_doc->m_drawingBrevisWidth[staff->m_drawingStaffSize]*2;	// avance auto
     
     y1 = *View::s_drawingLigY - m_doc->GetDrawingUnit(staff->m_drawingStaffSize);	// ligat_y contient y original
     yy2 = y2;
     y5 = y1+ m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize); y2 += m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize);	// on monte d'un INTERL
     
     if (note->GetColored()==BOOLEAN_true)
     DrawObliquePolygon ( dc,  x1,  y1,  x2,  yy2, m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize));
     else
     {	DrawObliquePolygon ( dc,  x1,  y1,  x2,  yy2, 5);
     DrawObliquePolygon ( dc,  x1,  y5,  x2,  y2, -5);
     }
     DrawVerticalLine ( dc,y3,y4,x2,m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize));	//cloture flagStemHeighte
     
     View::s_drawingLigObliqua = false;
     //			queue_lig = OFF;	//desamorce alg.queue DUR_BR
     
     }
     }
     
     if (note->m_lig)	// memoriser positions d'une note a l'autre; relier notes par barres
     {
     *(View::s_drawingLigX+1) = x2; *(View::s_drawingLigY+1) = y;	// relie notes ligaturees par barres flagStemHeightes
     //if (in(x1,(*View::s_drawingLigX)-2,(*View::s_drawingLigX)+2) || (this->fligat && this->lat && !Note1::marq_obl))
     // les dernieres conditions pour permettre ligature flagStemHeighte ancienne
     //	DrawVerticalLine (dc, *ligat_y, y1, (this->fligat && this->lat) ? x2: x1, m_doc->m_parameters.m_stemWidth); // ax2 - drawing flagStemHeight lines missing
     *View::s_drawingLigX = *(View::s_drawingLigX + 1);
     *View::s_drawingLigY = *(View::s_drawingLigY + 1);
     }
     
     
     y3 = y2 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*6;
     
     if (note->m_lig)
     {
     if (note->m_dur == DUR_BR) //  && this->queue_lig)	// queue gauche bas: DUR_BR initiale descendante // ax2 - no support of queue_lig (see WG corrigeLigature)
     {
     DrawVerticalLine ( dc, y2, y3, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );
     }
     else if (note->m_dur == DUR_LG) // && !this->queue_lig) // DUR_LG en ligature, queue droite bas // ax2 - no support of queue_lig
     {
     DrawVerticalLine (dc, y2, y3, x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );
     }
     else if (note->m_dur == DUR_1) // && this->queue_lig )	// queue gauche haut // ax2 - no support of queue_lig
     {
     y2 = y1 + m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*6;
     DrawVerticalLine ( dc, y1, y2, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );
     }
     }
     else if (note->m_dur == DUR_LG)		// DUR_LG isolee: queue comme notes normales
     */
    if (note->GetActualDur() == DUR_LG)
    {
        verticalCenter = staff->GetDrawingY() - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize)*2;
        // ENZ
        up = (y < verticalCenter) ? ON : OFF;
        // ENZ
        if ( note->GetDrawingStemDir() != STEMDIRECTION_NONE ) {
            if ( note->GetDrawingStemDir() == STEMDIRECTION_up) {
                up = ON;
            }
            else {
                up = OFF;
            }
        }
        
        if (!up)
        {
            y3 = y1 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*8;
            y2 = y1;
        }
        else {
            y3 = y1 + m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*6;
            y2 = y1;
        }
        DrawVerticalLine ( dc, y2,y3,x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );
    }
    
    return;
}
示例#8
0
void View::DrawMaximaToBrevis( DeviceContext *dc, int y, LayerElement *element, Layer *layer, Staff *staff )
{
    assert( dc );
    assert( element );
    assert( layer );
    assert( staff );
    
    Note *note = dynamic_cast<Note*>(element);
    assert( note );
    
    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 ;
    xn = element->GetDrawingX();
    
    // calcul des dimensions du rectangle
    x1 = xn - m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize );
    x2 = xn +  m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize );
    if (note->GetActualDur() == DUR_MX) {
        x1 -= m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize );
        x2 += m_doc->GetDrawingBrevisWidth( staff->m_drawingStaffSize );
    }
    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);
    
    if (note->GetColored()!=BOOLEAN_true) {
        //	double base des carrees
        DrawObliquePolygon ( dc, x1,  y1,  x2,  y1, -height );
        DrawObliquePolygon ( dc, x1,  y2,  x2,  y2, height );
    }
    else {
        DrawFullRectangle( dc,x1,y1,x2,y2);
    }
    
    DrawVerticalLine ( dc, y3, y4, x1, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );	// corset lateral
    DrawVerticalLine ( dc, y3, y4, x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );

    // stem
    if (note->GetActualDur() < DUR_BR)
    {
        verticalCenter = staff->GetDrawingY() - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize)*2;
        up = (y < verticalCenter) ? true : false;
        if ( note->GetDrawingStemDir() != STEMDIRECTION_NONE ) {
            if ( note->GetDrawingStemDir() == STEMDIRECTION_up) {
                up = true;
            }
            else {
                up = false;
            }
        }
        
        if (!up) {
            y3 = y1 - m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*8;
            y2 = y1;
        }
        else {
            y3 = y1 + m_doc->GetDrawingUnit(staff->m_drawingStaffSize)*6;
            y2 = y1;
        }
        DrawVerticalLine ( dc, y2,y3,x2, m_doc->GetDrawingStemWidth(staff->m_drawingStaffSize) );
    }
    
    return;
}
示例#9
0
void View::DrawMensuralNote ( DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure )
{
    assert( dc );
    assert( element );
    assert( layer );
    assert( staff );
    assert( measure );
    
    Note *note = dynamic_cast<Note*>(element);
    assert( note );
    
    int staffSize = staff->m_drawingStaffSize;
    int noteY = element->GetDrawingY();
    int xLedger, xNote, xStem;
    int drawingDur;
    bool drawingCueSize;
    int staffY = staff->GetDrawingY();
    wchar_t fontNo;
    int ledge;
    int verticalCenter = 0;

    xStem = element->GetDrawingX();
    xLedger = xStem;
    
    drawingDur = note->GetDrawingDur();
    drawingCueSize = note->HasGrace();
    
    int radius = m_doc->GetGlyphWidth(SMUFL_E0A3_noteheadHalf, staffSize, drawingCueSize);
    
    if (drawingDur > DUR_1 || (drawingDur == DUR_1 && staff->notAnc)) {	// annuler provisoirement la modif. des lignes addit.
        ledge = m_doc->GetDrawingLedgerLineLength(staffSize, drawingCueSize);
    }
    else {
        ledge = m_doc->GetDrawingLedgerLineLength(staffSize, drawingCueSize);
        radius += radius/3;
    }
    
    /************** Stem/notehead direction: **************/
    
    verticalCenter = staffY - m_doc->GetDrawingDoubleUnit(staffSize)*2;
    data_STEMDIRECTION noteStemDir = note->CalcDrawingStemDir();
    if ( noteStemDir != STEMDIRECTION_NONE ) {
        note->SetDrawingStemDir( noteStemDir );
    }
    else if ( layer->GetDrawingStemDir() != STEMDIRECTION_NONE) {
        note->SetDrawingStemDir( layer->GetDrawingStemDir() );
    }
    else {
        note->SetDrawingStemDir((noteY >= verticalCenter) ? STEMDIRECTION_down : STEMDIRECTION_up);
    }
    
    xNote = xStem - radius;
    
    /************** Noteheads: **************/
    
    // Long, breve and ligatures
    if ((note->GetLig()!=LIGATURE_NONE) && (drawingDur <= DUR_1)) {
        DrawLigature ( dc, noteY, element, layer, staff);
    }
    else if (drawingDur < DUR_1) {
        DrawMaximaToBrevis( dc, noteY, element, layer, staff);
    }
    else if (drawingDur == DUR_1) {
        if (note->GetColored())
            fontNo = SMUFL_E938_mensuralNoteheadSemibrevisBlack;
        else
            fontNo = SMUFL_E939_mensuralNoteheadSemibrevisVoid;
        
        DrawSmuflCode( dc, xNote, noteY, fontNo, staff->m_drawingStaffSize, drawingCueSize );
    }
    // Other values ??WE WANT MENSURAL NOTEHEADS, NOT CMN!!!!!!!!
   else {
        if (note->GetColored()) {
            if (drawingDur == DUR_2) fontNo = SMUFL_E0A4_noteheadBlack;
            else fontNo = SMUFL_E0A3_noteheadHalf;
        }
        else {
            if (drawingDur > DUR_2) fontNo = SMUFL_E0A4_noteheadBlack;
            else fontNo = SMUFL_E0A3_noteheadHalf;
        }

        DrawSmuflCode( dc, xNote, noteY, fontNo,  staff->m_drawingStaffSize, drawingCueSize );
        
        DrawStem(dc, note, staff, note->GetDrawingStemDir(), radius, xStem, noteY);
    }
    
    /************** Ledger lines: **************/
    
    int staffTop = staffY + m_doc->GetDrawingUnit(staffSize);
    int staffBot = staffY - m_doc->GetDrawingStaffSize(staffSize) - m_doc->GetDrawingUnit(staffSize);
    
    //if the note is not in the staff
    if (!is_in(noteY,staffTop,staffBot))
    {
        int distance, highestNewLine, numLines;
        bool aboveStaff = (noteY > staffTop);
        
        distance = (aboveStaff ? (noteY - staffY) : staffY - m_doc->GetDrawingStaffSize(staffSize) - noteY);
        highestNewLine = ((distance % m_doc->GetDrawingDoubleUnit(staffSize) > 0) ? (distance - m_doc->GetDrawingUnit(staffSize)) : distance);
        numLines = highestNewLine / m_doc->GetDrawingDoubleUnit(staffSize);
        
        DrawLedgerLines(dc, note, staff, aboveStaff, false, 0, numLines);

    }
    
    /************** dots **************/
    
    if (note->GetDots()) {
        int xDot;
        if (note->GetDur() < DUR_2 || (note->GetDur() > DUR_8 && (note->GetDrawingStemDir() == STEMDIRECTION_up)))
            xDot = xStem + m_doc->GetDrawingUnit(staffSize)*7/2;
        else
            xDot = xStem + m_doc->GetDrawingUnit(staffSize)*5/2;
        
        DrawDots( dc, xDot, noteY, note->GetDots(), staff );
    }
}