示例#1
0
void View::DrawMensuralRest(DeviceContext *dc, LayerElement *element, Layer *layer, Staff *staff, Measure *measure)
{
    assert(dc);
    assert(element);
    assert(layer);
    assert(staff);
    assert(measure);

    wchar_t charCode;

    Rest *rest = dynamic_cast<Rest *>(element);
    assert(rest);

    bool drawingCueSize = rest->IsCueSize();
    int drawingDur = rest->GetActualDur();
    int x = element->GetDrawingX();
    int y = element->GetDrawingY();

    switch (drawingDur) {
        case DUR_MX: charCode = SMUFL_E9F0_mensuralRestMaxima; break;
        case DUR_LG: charCode = SMUFL_E9F2_mensuralRestLongaImperfecta; break;
        case DUR_BR: charCode = SMUFL_E9F3_mensuralRestBrevis; break;
        case DUR_1: charCode = SMUFL_E9F4_mensuralRestSemibrevis; break;
        case DUR_2: charCode = SMUFL_E9F5_mensuralRestMinima; break;
        case DUR_4: charCode = SMUFL_E9F6_mensuralRestSemiminima; break;
        case DUR_8: charCode = SMUFL_E9F7_mensuralRestFusa; break;
        case DUR_16: charCode = SMUFL_E9F8_mensuralRestSemifusa; break;
        default:
            charCode = 0; // This should never happen
    }
    DrawSmuflCode(dc, x, y, charCode, staff->m_drawingStaffSize, drawingCueSize);
}
示例#2
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 noteY = element->GetDrawingY();
    int xNote, xStem;
    int drawingDur;
    int staffY = staff->GetDrawingY();
    wchar_t charCode;
    int verticalCenter = 0;
    bool mensural_black = (staff->m_drawingNotationType == NOTATIONTYPE_mensural_black);

    xStem = element->GetDrawingX();

    drawingDur = note->GetDrawingDur();

    int radius = m_doc->GetGlyphWidth(SMUFL_E93C_mensuralNoteheadMinimaWhite, staff->m_drawingStaffSize, false) / 2;

    if (drawingDur > DUR_1) {
        if (mensural_black) radius *= TEMP_MINIMA_WIDTH_FACTOR;
    }
    else {
        radius += radius / 3;
    }

    /************** Stem/notehead direction: **************/

    data_STEMDIRECTION stemDir = STEMDIRECTION_NONE;

    verticalCenter = staffY - m_doc->GetDrawingDoubleUnit(staff->m_drawingStaffSize) * 2;
    if (note->HasStemDir()) {
        stemDir = note->GetStemDir();
    }
    else if (layer->GetDrawingStemDir() != STEMDIRECTION_NONE) {
        stemDir = layer->GetDrawingStemDir();
    }
    else {
        if (drawingDur < DUR_1)
            stemDir = STEMDIRECTION_down;
        else
            stemDir = (noteY > verticalCenter) ? STEMDIRECTION_down : STEMDIRECTION_up;
    }

    xNote = xStem - radius;

    /************** Noteheads: **************/

    // Ligature, maxima,longa, and brevis
    if ((note->GetLig() != noteLogMensural_LIG_NONE) && (drawingDur <= DUR_1)) {
        DrawLigatureNote(dc, element, layer, staff);
    }
    else if (drawingDur < DUR_1) {
        DrawMaximaToBrevis(dc, noteY, element, layer, staff);
    }
    // Semibrevis
    else if (drawingDur == DUR_1) {
        if (mensural_black) {
            int sbStaffSize = 0.8 * staff->m_drawingStaffSize;
            DrawDiamond(dc, xNote, noteY, 2 * sbStaffSize, (int)(1.2 * sbStaffSize), !note->GetColored(), 20);
        }
        else {
            // Maybe we can add this to Note::GetMensuralSmuflNoteHead?
            if (note->GetColored())
                charCode = SMUFL_E938_mensuralNoteheadSemibrevisBlack;
            else
                charCode = SMUFL_E939_mensuralNoteheadSemibrevisVoid;

            DrawSmuflCode(dc, xNote, noteY, charCode, staff->m_drawingStaffSize, false);
        }
    }
    // Shorter values
    else {
        if (mensural_black) {
            // SMuFL 1.20 doesn't have a codepoint for the "colored" semibrevis and minima head in black
            // mensural notation. But an unfilled (void) narrow diamond is fine, so we draw one.
            int sbStaffSize = 0.8 * staff->m_drawingStaffSize;
            DrawDiamond(dc, xNote, noteY, 2 * sbStaffSize, (int)(TEMP_MINIMA_WIDTH_FACTOR * 2 * sbStaffSize),
                !note->GetColored(), 20);
        }
        else {
            DrawSmuflCode(dc, xNote, noteY, note->GetMensuralSmuflNoteHead(), staff->m_drawingStaffSize, false);
        }

        DrawMensuralStem(dc, note, staff, stemDir, radius, xStem, noteY);
    }
    
    /************ Draw children (verse / syl) ************/
    
    DrawLayerChildren(dc, note, layer, staff, measure);
    
}
示例#3
0
void View::DrawMensuralStem(DeviceContext *dc, LayerElement *object, Staff *staff, data_STEMDIRECTION dir, int radius,
    int xn, int originY, int heightY)
{
    assert(object->GetDurationInterface());

    int staffSize = staff->m_drawingStaffSize;
    int staffY = staff->GetDrawingY();
    int baseStem, totalFlagStemHeight, flagStemHeight, nbFlags;
    int drawingDur = (object->GetDurationInterface())->GetActualDur();
    bool drawingCueSize = object->IsCueSize();
    int verticalCenter = staffY - m_doc->GetDrawingDoubleUnit(staffSize) * 2;
    bool mensural_black = (staff->m_drawingNotationType == NOTATIONTYPE_mensural_black);

    baseStem = m_doc->GetDrawingUnit(staffSize) * STANDARD_STEMLENGTH;
    flagStemHeight = m_doc->GetDrawingDoubleUnit(staffSize);
    if (drawingCueSize) {
        baseStem = m_doc->GetCueSize(baseStem);
        flagStemHeight = m_doc->GetCueSize(flagStemHeight);
    }

    nbFlags = (mensural_black ? drawingDur - DUR_2 : drawingDur - DUR_4);
    totalFlagStemHeight = flagStemHeight * (nbFlags * 2 - 1) / 2;

    /* SMuFL provides combining stem-and-flag characters with one and two flags, but
        at the moment, I'm using only the one flag ones, partly out of concern for
        possible three-flag notes. */

    /* In black notation, the semiminima gets one flag; in white notation, it gets none.
        In both cases, as in CWMN, each shorter duration gets one additional flag. */

    if (dir == STEMDIRECTION_down) {
        // flip all lengths. Exception: in mensural notation, the stem will never be at
        //   left, so leave radius as is.
        baseStem = -baseStem;
        totalFlagStemHeight = -totalFlagStemHeight;
        heightY = -heightY;
    }

    // If we have flags, add them to the height.
    int y1 = originY;
    int y2 = ((nbFlags > 0) ? (y1 + baseStem + totalFlagStemHeight) : (y1 + baseStem)) + heightY;
    int x2;
    if (drawingDur < DUR_BR)
        x2 = xn + radius;
    else
        x2 = xn;

    if ((dir == STEMDIRECTION_up) && (y2 < verticalCenter)) {
        y2 = verticalCenter;
    }
    else if ((dir == STEMDIRECTION_down) && (y2 > verticalCenter)) {
        y2 = verticalCenter;
    }

    // shorten the stem at its connection with the note head
    // this will not work if the pseudo size is changed
    int shortening = 0.9 * m_doc->GetDrawingUnit(staffSize);

    // LogDebug("DrawMensuralStem: drawingDur=%d mensural_black=%d nbFlags=%d", drawingDur, mensural_black, nbFlags);
    int stemY1 = (dir == STEMDIRECTION_up) ? y1 + shortening : y1 - shortening;
    int stemY2 = y2;
    if (nbFlags > 0) {
        // if we have flags, shorten the stem to make sure we have a nice overlap with the flag glyph
        int shortener
            = (drawingCueSize) ? m_doc->GetCueSize(m_doc->GetDrawingUnit(staffSize)) : m_doc->GetDrawingUnit(staffSize);
        stemY2 = (dir == STEMDIRECTION_up) ? y2 - shortener : y2 + shortener;
    }

    int halfStemWidth = m_doc->GetDrawingStemWidth(staffSize) / 2;
    // draw the stems and the flags
    if (dir == STEMDIRECTION_up) {

        if (nbFlags > 0) {
            for (int i = 0; i < nbFlags; i++)
                DrawSmuflCode(dc, x2 - halfStemWidth, stemY1 - i * flagStemHeight,
                    SMUFL_E949_mensuralCombStemUpFlagSemiminima, staff->m_drawingStaffSize, drawingCueSize);
        }
        else
            DrawFilledRectangle(dc, x2 - halfStemWidth, stemY1, x2 + halfStemWidth, stemY2);
    }
    else {
        if (nbFlags > 0) {
            for (int i = 0; i < nbFlags; i++)
                DrawSmuflCode(dc, x2 - halfStemWidth, stemY1 + i * flagStemHeight,
                    SMUFL_E94A_mensuralCombStemDownFlagSemiminima, staff->m_drawingStaffSize, drawingCueSize);
        }
        else
            DrawFilledRectangle(dc, x2 - halfStemWidth, stemY1, x2 + halfStemWidth, stemY2);
    }

    // Store the start and end values
    StemmedDrawingInterface *interface = object->GetStemmedDrawingInterface();
    assert(interface);
    interface->SetDrawingStemDir(dir);
}
示例#4
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 );
    }
}