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); }
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); }
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); }
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 ); } }