/** \brief Manual anchor points positionning, when dx and dy tags are specified. This calculates the reference points on which dx and dy offset will be applied. Following the guido specification of tie ans slur tags, those reference points are the center of the noteheads. */ void GRBowing::manualAnchorPoints( GRBowingContext * bowContext, ARBowing * arBow, GRSystemStartEndStruct * sse ) { // Careful, we have to deal with chords! what about getStemStartPosition()? NVPoint posLeft; NVPoint posRight; GRNotationElement * startElement = sse->startElement; GRNotationElement * endElement = sse->endElement; GRBowingSaveStruct * bowInfos = (GRBowingSaveStruct *)sse->p; GRStdNoteHead * head; const bool upward = bowContext->curveDir == 1; // - Find left position if (bowContext->bottomLeftHead && bowContext->topLeftHead) // && !noteleft // useless additional test ? don't exists for rightPos ! { if( upward ) head = bowContext->topLeftHead; else head = bowContext->bottomLeftHead; // down ... we take the lowest notehead posLeft = head->getNoteHeadPosition(); } else posLeft = startElement->getPosition(); // - Find right position if (bowContext->bottomRightHead && bowContext->topRightHead) { if( upward ) head = bowContext->topRightHead; else head = bowContext->bottomRightHead; // down ... we take the lowest notehead posRight = head->getNoteHeadPosition(); } else posRight = endElement->getPosition(); if (bowContext->openLeft) posLeft.y = posRight.y; if (bowContext->openRight) posRight.y = posLeft.y; bowInfos->position = posLeft; bowInfos->offsets[2] = posRight - posLeft; // control points are stored as offsets to the position. // if( manualSettings == false ) arBow->setCurve( bowContext->curveDir, posLeft, posRight ); // (JB) useless ? }
/** \brief Recalculates the bounding box of the page. */ void GRPage::updateBoundingBox() { // - Start from a null rectangle mBoundingBox.Set( 0, 0, 0, 0 ); GRNotationElement * el; // - Add systems boxes SystemPointerList::iterator ptr; TYPE_DURATION duration; for( ptr = mSystems.begin(); ptr != mSystems.end(); ++ ptr ) { el = *ptr; NVRect eltBox ( el->getBoundingBox()); eltBox += el->getPosition(); mBoundingBox.Merge( eltBox ); duration += el->getDuration(); //addToBoundingBox( el ); } setDuration (duration); // - Add page and system-tags boxes GuidoPos mypos = First(); if (mypos) { GRNotationElement * el = GetNext( mypos ); NVRect eltBox ( el->getBoundingBox()); eltBox += el->getPosition(); mBoundingBox.Merge( eltBox ); // todo: addToBoundingBox( el ); } mMapping = mBoundingBox; // - Add the page margins /* mBoundingBox.left -= getMarginLeft(); mBoundingBox.top -= getMarginTop(); mBoundingBox.right += getMarginRight(); mBoundingBox.bottom += getMarginBottom(); */ // This adds some space to the right and at the bottom. // The NoteServer can display a nicer picture using this .... // maybe this needs to be changed later!? //mBoundingBox.right += 5* LSPACE; //mBoundingBox.bottom += 5* LSPACE; }
void GRGlobalStem::tellPosition(GObject * obj, const NVPoint & pt) { if (error) return; if (dynamic_cast<GRNotationElement *>(obj) == mFirstEl) // useless cast ? { if (mIsSystemCall) { // this is the staff, to which the stem belongs .... const GRStaff * stemstaff = mFirstEl->getGRStaff(); // update the position of the stem and of the flag .... // determine the lowest and highest position ... GRNotationElement * el = mAssociated->GetTail(); NVPoint offset; if (el) { offset = el->getGRStaff()->getPosition(); mLowestY = el->getPosition().y + offset.y; mHighestY = mLowestY; } else { mLowestY = 0; mHighestY = 0; } GuidoPos pos = mAssociated->GetHeadPosition(); while (pos) { GRNotationElement * el = mAssociated->GetNext(pos); if (el && !dynamic_cast<GREmpty *>(el)) { offset = el->getGRStaff()->getPosition(); if (mLowestY > el->getPosition().y + offset.y) mLowestY = el->getPosition().y + offset.y; if (mHighestY < el->getPosition().y + offset.y) mHighestY = el->getPosition().y + offset.y; } } offset = stemstaff->getPosition(); mLowestY -= offset.y; mHighestY -= offset.y; GDirection stemdir = theStem->getStemDir(); // now we have the position of the lowest or highest note ... if (stemdir == dirUP) { theStem->setPosition(NVPoint(0, (GCoord)mHighestY)); } else if (stemdir == dirDOWN) { theStem->setPosition(NVPoint(0, (GCoord)mLowestY)); } // now we have to deal with the length ... if (stemstate && stemstate->getLength()->TagIsSet()) { // we have a length, that was definitly set .... theStem->setStemLength( stemstate->getLength()->getValue()); stemlengthset = true; } else { // length was not set .... const float theLength = (float)(mHighestY - mLowestY + stemstaff->getStaffLSPACE() * 3.5f); theStem->setStemLength(theLength); } // here we have to add the flags ... // theFlag = new GRFlag(this, // dispdur,stemdir,theStem->getStemLength()); if (stemdir == dirUP) { theFlag->setPosition(NVPoint(0, (GCoord)mHighestY)); } else if (stemdir == dirDOWN) { theFlag->setPosition(NVPoint(0, (GCoord)mLowestY)); } GRNotationElement * tmpel = mAssociated->GetHead(); if (tmpel) updateGlobalStem(tmpel->getGRStaff()); } setHPosition(pt.x); } }
void GRGlobalStem::RangeEnd( GRStaff * inStaff) { if (error || mFirstEl == 0) return; GRPTagARNotationElement::RangeEnd(inStaff); if (inStaff == 0) return; GRSystemStartEndStruct * sse = getSystemStartEndStruct(inStaff->getGRSystem()); // this checks, wether all associated elements are // on the same staff. If not, we build a new // GRSystemTag that gets added to the system // so that an update on all positions can be made .... // (this is taken from GRBeam) GuidoPos syststpos = sse->startpos; if (tagtype != GRTag::SYSTEMTAG && syststpos) { // this is all done so that I really get a correct first staff to // test my stuff ... while (syststpos && !/*ynamic_cast<GRNotationElement *>*/(mAssociated->GetAt(syststpos))) { mAssociated->GetNext(syststpos); } // const GRStaff *tststaff = mAssociated->GetNext(syststpos)->getGRStaff(); int tststaffnum = mAssociated->GetNext(syststpos)->getStaffNumber(); while (syststpos) { GRNotationElement * el = mAssociated->GetNext(syststpos); if (el) { if (el->getStaffNumber() != tststaffnum) // el->getGRStaff() != tststaff) { tagtype = GRTag::SYSTEMTAG; GRSystemTag * mysystag = new GRSystemTag(this); // sse->grsystem->addSystemTag(mysystag); el->getGRSystemSlice()->addSystemTag(mysystag); break; } } } } if (tagtype != GRTag::SYSTEMTAG) { // check, whether firstel is on the same staff? if (mFirstEl && mAssociated && mAssociated->GetHead()) { if (mFirstEl->getStaffNumber() != mAssociated->GetHead()->getStaffNumber() ) // getGRStaff() != mAssociated->GetHead()->getGRStaff()) { tagtype = GRTag::SYSTEMTAG; GRSystemTag * mysystag = new GRSystemTag(this); // sse->grsystem->addSystemTag(mysystag); mFirstEl->getGRSystemSlice()->addSystemTag(mysystag); } } } GRNotationElement * el = /*dynamic cast<GRNotationElement *>*/(this); const NEPointerList * associated = el ? el->getAssociations() : 0; if (associated == 0) return; // now I have the associations ... // I have to build the stem .... delete theStem; theStem = new GRStem(this); if (mColRef) theStem->setColRef( mColRef ); // the Vertical position of the Notes that share a stem // must be already set .... // mHighestY = mLowestY = -32767; int highestlowestset = 0; // only if the stemdir has not been set .... if (stemdir == dirOFF) { stemdir = dirUP; if (stemstate) { if (stemstate->getStemState() == ARTStem::UP) { // we have to determine the direction ourselves. stemdir = dirUP; } else if (stemstate->getStemState() == ARTStem::DOWN) { // we have to determine the direction ourselves. stemdir = dirDOWN; } else if (stemstate->getStemState() == ARTStem::OFF) { // we have to determine the direction ourselves. stemdir = dirOFF; } } if ( ( stemstate && stemstate->getStemState() == ARTStem::AUTO ) || !stemstate) { // we have to determine the direction ourselves. // this needs to be done with // the direction of notes ... GCoord middle = 0; int count = 0; // determine the lowest and highest position ... el = associated->GetTail(); if (el) { middle = el->getPosition().y; if (tagtype == GRTag::SYSTEMTAG && el->getGRStaff()) { middle += (GCoord)el->getGRStaff()->getPosition().y; } mHighestY = middle; mLowestY = middle; ++ count; } GuidoPos pos = associated->GetHeadPosition(); while (pos && pos != associated->GetTailPosition()) { GRNotationElement * el = associated->GetNext(pos); if (el && !dynamic_cast<GREmpty *>(el)) { GCoord ypos = el->getPosition().y; if (el->getGRStaff() && tagtype == GRTag::SYSTEMTAG) ypos += el->getGRStaff()->getPosition().y; middle += ypos; ++count ; if (mLowestY > ypos) mLowestY = ypos; if (mHighestY < ypos) mHighestY = ypos; } } highestlowestset = 1; if (count > 0) middle /= count; const float curLSPACE = (float)(inStaff->getStaffLSPACE()); const float mylowesty = 2 * curLSPACE - mLowestY; const float myhighesty = mHighestY - 2 * curLSPACE; if (mylowesty > myhighesty) { stemdir = dirDOWN; } else if (myhighesty > mylowesty) stemdir = dirUP; else { if (middle >= curLSPACE * 2) { stemdir = dirUP; } else if (middle < curLSPACE * 2) { stemdir = dirDOWN; } } } } if (dispdur >= DURATION_1) { stemdir = dirOFF; } theStem->setStemDir(stemdir); // otherwise it has been set because of auto-stem. if (!highestlowestset) { // determine the lowest and highest position ... el = associated->GetTail(); if (el) { mLowestY = el->getPosition().y; if (tagtype == GRTag::SYSTEMTAG && el->getGRStaff()) { mLowestY += el->getGRStaff()->getPosition().y; } mHighestY = mLowestY; } GuidoPos pos = associated->GetHeadPosition(); while (pos) { GRNotationElement * el = associated->GetNext(pos); if (el && !dynamic_cast<GREmpty *>(el)) { NVPoint elpos (el->getPosition()); if (tagtype == GRTag::SYSTEMTAG && el->getGRStaff()) { elpos += el->getGRStaff()->getPosition(); } if (mLowestY > elpos.y) mLowestY = elpos.y; if (mHighestY < elpos.y) mHighestY = elpos.y; } } } // now we have the position of the lowest or highest note ... if (stemdir == dirUP) { theStem->setPosition(NVPoint(0, (GCoord)mHighestY)); } else if (stemdir == dirDOWN) { theStem->setPosition(NVPoint(0, (GCoord)mLowestY)); } // now we have to deal with the length... const TagParameterFloat * taglength = 0; if (stemstate) taglength = stemstate->getLength(); if (stemstate && taglength && taglength->TagIsSet()) { // we have a length, that was definitly set... theStem->setStemLength((float)(stemstate->getLength()->getValue())); stemlengthset = true; } else { // length was not set .... float length = (float)(mHighestY - mLowestY + inStaff->getStaffLSPACE() * 3.5f * mTagSize); theStem->setStemLength( length ); } delete theFlag; // here we have to add the flags ... theFlag = new GRFlag(this, dispdur,stemdir,theStem->getStemLength()); if (mColRef) theFlag->setColRef(mColRef); if (!mFlagOnOff) theFlag->setFlagOnOff(mFlagOnOff); if (stemdir == dirUP) { theFlag->setPosition(NVPoint(0, (GCoord)mHighestY)); } else if (stemdir == dirDOWN) { theFlag->setPosition(NVPoint(0, (GCoord)mLowestY)); } if (tagtype != GRTag::SYSTEMTAG) updateGlobalStem(inStaff); }
// ---------------------------------------------------------------------------- void GRTuplet::manualPosition(GObject * caller, const NVPoint & inPos ) { GREvent * event = GREvent::cast( caller ); if( event == 0 ) return; GRStaff * staff = event->getGRStaff(); if( staff == 0 ) return; GRSystemStartEndStruct * sse = getSystemStartEndStruct(staff->getGRSystem()); if( sse == 0 ) return; GRNotationElement * startElement = sse->startElement; GRNotationElement * endElement = sse->endElement; // if ( openLeftRange && openRightRange ) return; GRTupletSaveStruct * st = (GRTupletSaveStruct *)sse->p; const ARTuplet * arTuplet = getARTuplet(); float dy1 = arTuplet->isDySet() ? arTuplet->getDy1() : 0; float dy2 = arTuplet->isDySet() ? arTuplet->getDy2() : 0; if(( dy1 > 0 ) || ( dy2 > 0 )) mDirection = dirUP; const float halfNoteWidth = LSPACE * float(0.65); // harcoded if (event == startElement) { st->p1 = startElement->getPosition(); st->p1.x -= halfNoteWidth; // to enclose all the element width st->p1.y -= dy1; } else if (event == endElement) { st->p2 = endElement->getPosition(); st->p2.x += halfNoteWidth; // to enclose all the element width st->p2.y -= dy2; } if(event == endElement || (endElement == 0 && event == startElement)) { if (startElement && endElement) { const float posx = (st->p2.x - st->p1.x) * 0.5f + st->p1.x; const float posy = st->p2.y > st->p1.y ? (st->p2.y - st->p1.y) * 0.5f + st->p1.y + 40 : (st->p1.y - st->p2.y) * 0.5f + st->p2.y + 40; st->textpos.x = posx; st->textpos.y = posy; } else st->textpos = inPos; } // if( arTuplet->isFormatSet()) // { mShowLeftBrace = arTuplet->getLeftBrace(); mShowRightBrace = arTuplet->getRightBrace(); // } }