Esempio n. 1
0
void GRBeam::RangeEnd(GRStaff * grstaff)
{
	assert(grstaff);

	GRPositionTag::RangeEnd(grstaff);

	if (error) return;
	if (!mAssociated) return;
	
	GRSystemStartEndStruct * sse = getSystemStartEndStruct(grstaff->getGRSystem());
	assert(sse);

	if (mAssociated && (mAssociated->GetCount() == 1) && isAutoBeam())
	{
		GREvent * ev = GREvent::cast(mAssociated->GetHead());
		if (ev)
		{
			ev->setFlagOnOff(true);
			ev->decBeamCount();
			if (sse->startElement)	// something did not work, if the starElement is a glue ... and not an event
				ev->removeAssociation(this);
			if (sse->endElement)
				ev->removeAssociation(this);
		}
		return;
	}

	GREvent * grn;
	GuidoPos syststpos = sse->startpos;
	if (syststpos)
	{
		// this is all done so that I really get a correct first staff to test my stuff ...
		while (syststpos && !(mAssociated->GetAt(syststpos)))
		{
			mAssociated->GetNext(syststpos);
		}
		int tststaffnum = mAssociated->GetNext(syststpos)->getStaffNumber(); 
		while (syststpos)
		{
			GRNotationElement * el = mAssociated->GetNext(syststpos);
			if (el)
			{
				if (el->getStaffNumber() != tststaffnum)
				{
					tagtype = GRTag::SYSTEMTAG;
					GRSystemTag * mysystag = new GRSystemTag(this);
					el->getGRSystemSlice()->addSystemTag(mysystag);
					break;
				}
			}		
		}
	}

	GuidoPos pos = sse->startpos;
	GRBeamSaveStruct * st = (GRBeamSaveStruct *) sse->p;
	bool first = true;

	GDirection mytmpdir = dirOFF;
	while (pos)
	{
		grn = GREvent::cast(mAssociated->GetNext(pos));
		if (grn)
		{
			if (!st->dirset)
			{
				if (first)
				{
					// get the stemdir of the first !? maybe it now has been set?
					mytmpdir = grn->getStemDirection();
				}
				if (mytmpdir != dirOFF)
					grn->setStemDirection(mytmpdir);
				else if (st->direction>=0)
					grn->setStemDirection(dirUP);
				else
					grn->setStemDirection(dirDOWN);
			}
			grn->setFlagOnOff(false);
			first = false;
		}
	}
}
Esempio n. 2
0
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);
}