📄 notationhlayout.cpp
字号:
for (BarDataMap::iterator i = m_barData.begin(); i != m_barData.end(); ++i) { BarDataList &list = i->second; BarDataList::iterator bdli = list.find(barNo); if (bdli != list.end()) { BarData::SizeData &bd(bdli->second.sizeData); double diff = maxWidth - bd.reconciledWidth; if (diff < -0.1 || diff > 0.1) { bdli->second.layoutData.needsLayout = true; } bd.reconciledWidth = maxWidth; } } pageWidthSoFar += maxWidth; } } m_barPositions[barNo] = m_totalWidth;}voidNotationHLayout::finishLayout(timeT startTime, timeT endTime){ Profiler profiler("NotationHLayout::finishLayout"); m_barPositions.clear(); bool isFullLayout = (startTime == endTime); if (m_pageMode && (m_pageWidth > 0.1)) reconcileBarsPage(); else reconcileBarsLinear(); int staffNo = 0; for (BarDataMap::iterator i(m_barData.begin()); i != m_barData.end(); ++i) { emit setProgress(100 * staffNo / m_barData.size()); ProgressDialog::processEvents(); throwIfCancelled(); timeT timeCovered = endTime - startTime; if (isFullLayout) { NotationElementList *notes = i->first->getViewElementList(); if (notes->begin() != notes->end()) { NotationElementList::iterator j(notes->end()); timeCovered = (*--j)->getViewAbsoluteTime() - (*notes->begin())->getViewAbsoluteTime(); } } m_timePerProgressIncrement = timeCovered / (100 / m_barData.size()); layout(i, startTime, endTime); ++staffNo; }}voidNotationHLayout::layout(BarDataMap::iterator i, timeT startTime, timeT endTime){ Profiler profiler("NotationHLayout::layout"); Staff &staff = *(i->first); NotationElementList *notes = staff.getViewElementList(); BarDataList &barList(getBarData(staff)); NotationStaff ¬ationStaff = dynamic_cast<NotationStaff &>(staff); bool isFullLayout = (startTime == endTime); // these two are for partial layouts: // bool haveSimpleOffset = false; // double simpleOffset = 0; NOTATION_DEBUG << "NotationHLayout::layout: full layout " << isFullLayout << ", times " << startTime << "->" << endTime << endl; double x = 0, barX = 0; TieMap tieMap; timeT lastIncrement = (isFullLayout && (notes->begin() != notes->end())) ? (*notes->begin())->getViewAbsoluteTime() : startTime; ::Rosegarden::Key key = notationStaff.getSegment().getKeyAtTime(lastIncrement); Clef clef = notationStaff.getSegment().getClefAtTime(lastIncrement); TimeSignature timeSignature; int startBar = getComposition()->getBarNumber(startTime); KConfig *config = kapp->config(); config->setGroup("Notation Options"); bool showInvisibles = config->readBoolEntry("showinvisibles", true); for (BarPositionList::iterator bpi = m_barPositions.begin(); bpi != m_barPositions.end(); ++bpi) { int barNo = bpi->first; if (!isFullLayout && barNo < startBar) continue; NOTATION_DEBUG << "NotationHLayout::looking for bar " << bpi->first << endl; BarDataList::iterator bdi = barList.find(barNo); if (bdi == barList.end()) continue; barX = bpi->second; NotationElementList::iterator from = bdi->second.basicData.start; NotationElementList::iterator to; NOTATION_DEBUG << "NotationHLayout::layout(): starting bar " << barNo << ", x = " << barX << ", width = " << bdi->second.sizeData.idealWidth << ", time = " << (from == notes->end() ? -1 : (*from)->getViewAbsoluteTime()) << endl; BarDataList::iterator nbdi(bdi); if (++nbdi == barList.end()) { to = notes->end(); } else { to = nbdi->second.basicData.start; } if (from == notes->end()) { NOTATION_DEBUG << "Start is end" << endl; } if (from == to) { NOTATION_DEBUG << "Start is to" << endl; } if (!bdi->second.layoutData.needsLayout) { double offset = barX - bdi->second.layoutData.x; NOTATION_DEBUG << "NotationHLayout::layout(): bar " << barNo << " has needsLayout false and offset of " << offset << endl; if (offset > -0.1 && offset < 0.1) { NOTATION_DEBUG << "NotationHLayout::layout(): no offset, ignoring" << endl; continue; } bdi->second.layoutData.x += offset; if (bdi->second.basicData.newTimeSig) bdi->second.layoutData.timeSigX += (int)offset; for (NotationElementList::iterator it = from; it != to && it != notes->end(); ++it) { NotationElement* nel = static_cast<NotationElement*>(*it); NOTATION_DEBUG << "NotationHLayout::layout(): shifting element's x to " << ((*it)->getLayoutX() + offset) << " (was " << (*it)->getLayoutX() << ")" << endl; nel->setLayoutX((*it)->getLayoutX() + offset); double airX, airWidth; nel->getLayoutAirspace(airX, airWidth); nel->setLayoutAirspace(airX + offset, airWidth); } continue; } bdi->second.layoutData.x = barX; // x = barX + getPostBarMargin(); bool timeSigToPlace = false; if (bdi->second.basicData.newTimeSig) { timeSignature = bdi->second.basicData.timeSignature; timeSigToPlace = !bdi->second.basicData.timeSignature.isHidden(); } if (timeSigToPlace) { NOTATION_DEBUG << "NotationHLayout::layout(): there's a time sig in this bar" << endl; } bool repeatClefAndKey = false; if (bdi->second.sizeData.clefKeyWidth > 0) { repeatClefAndKey = true; } if (repeatClefAndKey) { NOTATION_DEBUG << "NotationHLayout::layout(): need to repeat clef & key in this bar" << endl; } double barInset = notationStaff.getBarInset(barNo, repeatClefAndKey); NotationElement *lastDynamicText = 0; int fretboardCount = 0; int count = 0; double offset = 0.0; double reconciledWidth = bdi->second.sizeData.reconciledWidth; if (repeatClefAndKey) { offset = bdi->second.sizeData.clefKeyWidth; reconciledWidth -= offset; } if (bdi->second.basicData.newTimeSig || !bdi->second.basicData.timeSignature.hasHiddenBars()) { offset += getPostBarMargin(); } ChunkList &chunks = bdi->second.chunks; ChunkList::iterator chunkitr = chunks.begin(); double reconcileRatio = 1.0; if (bdi->second.sizeData.idealWidth > 0.0) { reconcileRatio = reconciledWidth / bdi->second.sizeData.idealWidth; } NOTATION_DEBUG << "have " << chunks.size() << " chunks, reconciledWidth " << bdi->second.sizeData.reconciledWidth << ", idealWidth " << bdi->second.sizeData.idealWidth << ", ratio " << reconcileRatio << endl; double delta = 0; for (NotationElementList::iterator it = from; it != to; ++it) { NotationElement *el = static_cast<NotationElement*>(*it); delta = 0; float fixed = 0; if (el->event()->isa(Note::EventType)) { long pitch = 0; el->event()->get<Int>(PITCH, pitch); NOTATION_DEBUG << "element is a " << el->event()->getType() << " (pitch " << pitch << ")" << endl; } else { NOTATION_DEBUG << "element is a " << el->event()->getType() << endl; } bool invisible = false; if (el->event()->get<Bool>(INVISIBLE, invisible) && invisible) { if (!showInvisibles) continue; } if (chunkitr != chunks.end()) { NOTATION_DEBUG << "new chunk: addr " << &(*chunkitr) << " duration=" << (*chunkitr).duration << " subordering=" << (*chunkitr).subordering << " fixed=" << (*chunkitr).fixed << " stretchy=" << (*chunkitr).stretchy << " x=" << (*chunkitr).x << endl; x = barX + offset + reconcileRatio * (*chunkitr).x; fixed = (*chunkitr) .fixed; NOTATION_DEBUG << "adjusted x is " << x << endl; ChunkList::iterator chunkscooter(chunkitr); if (++chunkscooter != chunks.end()) { delta = (*chunkscooter).x - (*chunkitr).x; } else { delta = reconciledWidth - bdi->second.sizeData.fixedWidth - (*chunkitr).x; } delta *= reconcileRatio; ++chunkitr; } else { x = barX + reconciledWidth - getPreBarMargin(); delta = 0; } if (timeSigToPlace && !el->event()->isa(Clef::EventType) && !el->event()->isa(::Rosegarden::Key::EventType)) { NOTATION_DEBUG << "Placing timesig at " << x << endl; bdi->second.layoutData.timeSigX = (int)(x - fixed ) ; double shift = getFixedItemSpacing() + m_npf->getTimeSigWidth(timeSignature); offset += shift; x += shift; NOTATION_DEBUG << "and moving next elt to " << x << endl; timeSigToPlace = false; } if (barInset >= 1.0) { if (el->event()->isa(Clef::EventType) || el->event()->isa(::Rosegarden::Key::EventType)) { NOTATION_DEBUG << "Pulling clef/key back by " << getPreBarMargin() << endl; x -= getPostBarMargin() * 2 / 3; } else { barInset = 0.0; } } NOTATION_DEBUG << "NotationHLayout::layout(): setting element's x to " << x << " (was " << el->getLayoutX() << ")" << endl; double displacedX = 0.0; long dxRaw = 0; el->event()->get<Int>(DISPLACED_X, dxRaw); displacedX = double(dxRaw * m_npf->getNoteBodyWidth()) / 1000.0; el->setLayoutX(x + displacedX); el->setLayoutAirspace(x, int(delta)); // #704958 (multiple tuplet spanners created when entering // triplet chord) -- only do this here for non-notes, // notes get it from positionChord if (!el->isNote()) { sampleGroupElement(staff, clef, key, it); } if (el->isNote()) { // This modifies "it" and "tieMap" positionChord(staff, it, clef, key, tieMap, to); } else if (el->isRest()) { // nothing to do } else if (el->event()->isa(Clef::EventType)) { clef = Clef(*el->event()); } else if (el->event()->isa(::Rosegarden::Key::EventType)) { key = ::Rosegarden::Key(*el->event()); } else if (el->event()->isa(Text::EventType)) { // if it's a dynamic, make a note of it in case a // hairpin immediately follows it if (el->event()->has(Text::TextTypePropertyName) && el->event()->get<String>(Text::TextTypePropertyName) == Text::Dynamic) { lastDynamicText = el; } } else if (el->event()->isa(Indication::EventType)) { std::string type; double ix = x; // Check for a dynamic text at the same time as the // indication and if found, move the indication to the // right to make room. We know the text should have // preceded the indication in the staff because it has // a smaller subordering if (el->event()->get<String> (Indication::IndicationTypePropertyName, type) && (type == Indication::Crescendo || type == Indication::Decrescendo) && lastDynamicText && lastDynamicText->getViewAbsoluteTime() == el->getViewAbsoluteTime()) { ix = x + m_npf->getTextWidth (Text(*lastDynamicText->event())) + m_npf->getNoteBodyWidth() / 4; } el->setLayoutX(ix + displacedX); el->setLayoutAirspace(ix, delta - (ix - x)); } else if (el->event()->isa(Guitar::Chord::EventType)) { int guitarChordWidth = m_npf->getLineSpacing() * 6; el->setLayoutX(x - (guitarChordWidth / 2) + fretboardCount * (guitarChordWidth + m_npf->getNoteBodyWidth()/2) + displacedX); ++fretboardCount; } else { // nothing else } if (m_timePerProgressIncrement > 0 && (++count == 100)) { count = 0; timeT sinceIncrement = el->getViewAbsoluteTime() - lastIncrement; if (sinceIncrement > m_timePerProgressIncrement) { emit incrementProgress (sinceIncrement / m_timePerProgressIncrement); lastIncrement += (sinceIncrement / m_timePerProgressIncrement) * m_timePerProgressIncrement; throwIfCancelled(); } } } if (timeSigToPlace) { // no other events in this bar, so we never managed to place it x = barX + offset; NOTATION_DEBUG << "Placing timesig reluctantly at " << x << endl; bdi->second.layoutData.timeSigX = (int)(x); timeSigToPlace = false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -