// -------------------------------------------------------------------------- void GRBar::DrawWithLines( VGDevice & hdc ) const { if ((getTagType() != GRTag::SYSTEMTAG) && isSystemSlice()) return; // don't draw staff bars on system slices const float staffSize = mGrStaff->getSizeRatio(); if (staffSize < kMinNoteSize) // Too small, don't draw return; // - Vertical adjustement according to staff's line number float offsety1 = (fmod(- 0.5f * fLineNumber - 2, 3) + 1.5f) * LSPACE; float offsety2 = 0; if (fLineNumber != 0 && fLineNumber != 1) offsety2 = ((fLineNumber - 5) % 6) * LSPACE; const float offsetX = 3 + (staffSize - 1) * 2; const float x = mPosition.x + offsetX; const float y1 = mPosition.y + mBoundingBox.top + offsety1 * staffSize; const float y2 = y1 + mBoundingBox.bottom + offsety2 * staffSize; hdc.PushPenWidth( mGrStaff ? mGrStaff->currentLineThikness() * staffSize : kLineThick * staffSize ); hdc.Line(x, y1, x, y2); hdc.PopPenWidth(); }
void GRClef::OnDraw(VGDevice & hdc) const { // DrawBoundingBox( hdc, GColor( 255, 200, 0, 150)); // DEBUG if (error) return; GRTagARNotationElement::OnDraw(hdc); if( mDoubleTreble ) { const float xOffset = ((mRightSpace + mLeftSpace) * float(0.5)) - LSPACE * float(0.2); OnDrawSymbol( hdc, mSymbol, xOffset, 0 ); } else if( mOctaveStr ) // Draws the octava { const int fontSize = (int)(float(1.5) * LSPACE); NVstring textFont ( FontManager::kDefaultTextFont ); const VGFont* fontRef = FontManager::FindOrCreateFont( fontSize, &textFont ); const float octX = mPosition.x + mOctaveOffset.x; const float octY = mPosition.y + mOctaveOffset.y; // hdc.SelectFont( fontRef ); hdc.SetTextFont( fontRef ); // hdc.SetMusicFont( fontRef ); hdc.SetFontAlign( VGDevice::kAlignBottom | VGDevice::kAlignCenter ); hdc.DrawString( octX, octY, mOctaveStr, (int)strlen(mOctaveStr) ); } }
void GRSimpleBeam::OnDraw( VGDevice & hdc ) const { const unsigned char * colref = getColRef(); if (colref) { VGColor color ( colref ); // custom or black hdc.PushFillColor( color ); hdc.PushPen( color, 1 ); } float ax [4] = { fPoints[0].x, fPoints[1].x, fPoints[3].x, fPoints[2].x }; float ay [4] = { fPoints[0].y, fPoints[1].y, fPoints[3].y, fPoints[2].y }; // DF added to check for incorrect coordinates // makes sure that the right point is not to the left of the left point :-) // actually this should be checked at coordinates computation time // todo: check the object that computes the beam coordinates if (ax[0] > ax[2]) { ax[2] = ax[0]; } if (ax[1] > ax[3]) { ax[3] = ax[1]; } // This does the drawing! hdc.Polygon( ax, ay, 4 ); // - Cleanup if (colref) { hdc.PopPen(); hdc.PopFillColor(); } }
/** \brief Draws a musical symbol glyph at given position into input graphic device context. It possible to scale the symbol, by specifying a font height and a x-scale. */ void GRNotationElement::OnDrawSymbol( VGDevice & hdc, unsigned int inSymbol, float inOffsetX, float inOffsetY, float inFontSize ) const //, float inScaleX ) const { // - Setup colors if(!mDraw) return; const unsigned char * colref = getColRef(); const VGColor prevFontColor = hdc.GetFontColor(); if (colref) hdc.SetFontColor( VGColor( colref )); // int nBackmode = hdc.GetBackgroundMode(); // hdc.SetBackgroundMode( VGDevice::kModeTransparent ); // - Setup text align hdc.SetFontAlign(getTextAlign()); // - Draw DrawSymbol( hdc, inSymbol, inOffsetX, inOffsetY, inFontSize ); // DrawBoundingBox( hdc, VGColor(0,0,200)); // debug // - Restore context if (colref) hdc.SetFontColor( prevFontColor ); //(TODO: in a parent method) }
// -------------------------------------------------------------------------- void GRDoubleBar::DrawWithLines( VGDevice & hdc ) const { if ((getTagType() != GRTag::SYSTEMTAG) && isSystemSlice()) return; // don't draw staff bars on system slices if (fSize < kMinNoteSize) // Too small, don't draw return; // - Vertical adjustement according to staff's line number float offsety1 = (fmod(- 0.5f * fLineNumber - 2, 3) + 1.5f) * LSPACE; float offsety2 = 0; if (fLineNumber != 0 && fLineNumber != 1) offsety2 = ((fLineNumber - 5) % 6) * LSPACE; // - Horizontal adjustement according to staff's lines size and staff's size const float offsetX = (fStaffThickness - 4) * 0.5f - 24; const float spacing = LSPACE * 0.7f * fSize; const float x1 = mPosition.x + offsetX; const float x2 = x1 + spacing; const float y1 = mPosition.y + mBoundingBox.top + offsety1 * fSize; const float y2 = y1 + mBoundingBox.bottom + offsety2 * fSize; float lineThickness = kLineThick * 1.5f * fSize; hdc.PushPenWidth(lineThickness); hdc.Line(x1, y1 + lineThickness / 2, x1, y2 - lineThickness / 2); hdc.Line(x2, y1 + lineThickness / 2, x2, y2 - lineThickness / 2); hdc.PopPenWidth(); }
/** \brief Low-level symbol drawing. */ void GRNotationElement::DrawSymbol( VGDevice & hdc, unsigned int inSymbol, float inOffsetX, float inOffsetY, float inFontSize ) const { if(!mDraw) return; // - Setup font const VGFont* myfont = FontManager::gFontScriab; const float theSize = (inFontSize != 0) ? inFontSize : getSize(); if (theSize < kMinNoteSize) return; // element is too small, don't draw it if (theSize != float(1.0)) { const int newFontSize = (int)(theSize * 4 * LSPACE + 0.5f ); // +0.5 to round from float to int. myfont = FontManager::FindOrCreateFont( newFontSize ); } // hdc.SelectFont( myfont ); hdc.SetMusicFont( myfont ); // - Setup position const NVPoint & offset = getOffset(); const NVPoint & refpos = getReferencePosition(); const float xPos = mPosition.x + offset.x + (refpos.x * theSize) + inOffsetX; const float yPos = mPosition.y + offset.y + (refpos.y * theSize) + inOffsetY; // - Draw hdc.DrawMusicSymbol( xPos, yPos, inSymbol ); #ifdef SHOWRODS // draw the rods .... const float leftspc = getLeftSpace(); const float rightspc = getRightSpace(); if (leftspc) { const float myposy = 350; hdc.PushPen(VGColor( 0, 0, 200 ), 5 ); // Always blue hdc.Line( mPosition.x-leftspc,myposy-30, mPosition.x-leftspc,myposy+30 ); hdc.Line( mPosition.x-leftspc, myposy, mPosition.x, myposy ); hdc.PopPen(); } if (rightspc) { const float myposy = 350; hdc.PushPen(VGColor( 0, 0, 200 ), 5 ); // Always blue hdc.Line( mPosition.x+rightspc, myposy-30, mPosition.x+rightspc, myposy+30 ); hdc.LineTo( mPosition.x+rightspc, myposy, mPosition.x, myposy ); hdc.PopPen(); } #endif // #ifdef SHOWRODS }
/** \brief Draws the score page. */ void GRPage::OnDraw( VGDevice & hdc ) const { // TODO: test if the element intersect with the clipping box GuidoPos pagepos = First(); while (pagepos) GetNext(pagepos)->OnDraw(hdc); // - Convert from centimeter to logical. const float tstx = mLeftMargin; // (JB) sign change const float tsty = mTopMargin; // (JB) sign change // this resets the window-origin, so that left and top margins are correct ... // dont forget to set the clipping-rectangle! gClipRect.left -= tstx; gClipRect.top -= tsty; gClipRect.right -= tstx; gClipRect.bottom -= tsty; // The following sets the WindowOrigin so that // 0,0 is at the top left (including margins) // // --------------- // | mt | // | x------- | // | | | mr| // |ml| | | // | -------- | // | mb | // |-------------| hdc.OffsetOrigin( tstx, tsty ); GRSystem * theSystem; SystemPointerList::const_iterator ptr; for( ptr = mSystems.begin(); ptr != mSystems.end(); ++ ptr ) { theSystem = *ptr; const NVPoint & pos = theSystem->getPosition(); NVRect br (theSystem->getBoundingBox()); br += pos; if( br.Collides( gClipRect ) == false ) continue; gCurSystem = theSystem; theSystem->OnDraw(hdc); } if (gBoundingBoxesMap & kPageBB) DrawBoundingBox( hdc, kPageBBColor); hdc.OffsetOrigin( -tstx, -tsty ); }
/** \brief Converts a Rectangle from device coordinades to logical (virtual) coordinates. */ bool GRPage::DPtoLPRect( VGDevice & hdc, float left, float top, float right, float bottom, NVRect * outRect ) const { hdc.DeviceToLogical( &left, &top ); hdc.DeviceToLogical( &right, &bottom ); outRect->left = left; outRect->top = top; outRect->right = right; outRect->bottom = bottom; return true; }
/** \brief Rudis Slur-routine (currently unused) */ void GRBowing::drawSlur( VGDevice & hdc, NVPoint pstart, NVPoint pmid, NVPoint pend) const { NVRect rectangle ; // rectangle in which the arc is to be drawn. rectangle.left = pstart.x; if (pstart.y<pmid.y) rectangle.top=pmid.y; else rectangle.top= (pstart.y-pmid.y)*2 + pmid.y; rectangle.right = (pmid.x-pstart.x)*2 + pstart.x; if(pstart.y<pmid.y) rectangle.bottom= pmid.y - (pmid.y-pstart.y)*2; else rectangle.bottom= pmid.y; hdc.Arc( rectangle.left, rectangle.top, rectangle.right, rectangle.bottom, pstart.x,pstart.y,pmid.x,pmid.y); //second arc /// pmid.y-=10; rectangle.left = pmid.x - (pend.x - pmid.x); if (pmid.y < pend.y) rectangle.top = (pend.y-pmid.y)*2 - pmid.y; else rectangle.top= pmid.y; rectangle.right=pend.x; if(pmid.y < pend.y) rectangle.bottom= pmid.y; else rectangle.bottom= pmid.y - (pmid.y-pend.y)*2; hdc.Arc( rectangle.left, rectangle.top, rectangle.right, rectangle.bottom, pmid.x,pmid.y,pend.x,pend.y); // - DEBUG -> /* hdc.PushPen( GColor( 0, 0, 200 ), 5 ); hdc.Line( pstart.x - 20, pstart.y - 20, pstart.x + 20, pstart.y + 20); hdc.Line( pstart.x - 10, pstart.y + 20, pstart.x + 20, pstart.y - 20); hdc.Line( pmid.x - 20, pmid.y - 20, pmid.x + 20, pmid.y + 20); hdc.Line( pmid.x - 10, pmid.y + 20, pmid.x + 20, pmid.y - 20); hdc.Line( pend.x - 20, pend.y - 20, pend.x + 20, pend.y + 20); hdc.Line( pend.x - 20, pend.y + 20, pend.x + 20, pend.y - 20); hdc.PopPen();*/ // <- }
//____________________________________________________________________________________ void GRSingleNote::OnDraw( VGDevice & hdc ) const { float incy = 1; float posy = 0; int sum = mNumHelpLines; if (mNumHelpLines > 0) { // ledger lines up incy = -mCurLSPACE; posy = -mCurLSPACE; hdc.SetFontAlign( VGDevice::kAlignLeft | VGDevice::kAlignBase ); } else if( mNumHelpLines < 0 ) { incy = mCurLSPACE; posy = mGrStaff->getNumlines() * mCurLSPACE; sum = - sum; hdc.SetFontAlign( VGDevice::kAlignLeft | VGDevice::kAlignBase ); } // draw ledger lines const float ledXPos = -60 * 0.85f * mSize; for (int i = 0; i < sum; ++i, posy += incy) GRNote::DrawSymbol( hdc, kLedgerLineSymbol, ledXPos, ( posy - mPosition.y )); const VGColor oldcolor = hdc.GetFontColor(); if (mColRef) hdc.SetFontColor( VGColor( mColRef )); // - Draw elements (stems, dots...) DrawSubElements( hdc ); // - draw articulations & ornament const GRNEList * articulations = getArticulations(); if( articulations ) { for( GRNEList::const_iterator ptr = articulations->begin(); ptr != articulations->end(); ++ptr ) { GRNotationElement * el = *ptr; el->OnDraw(hdc); } } if (mOrnament ) mOrnament->OnDraw(hdc); // - Restore if (mColRef) hdc.SetFontColor( oldcolor ); if (gBoundingBoxesMap & kEventsBB) DrawBoundingBox( hdc, kEventBBColor); }
/** \brief Sets the scaling of input graphic device context, according to input sizes. (was setMapping) */ void GRPage::setScaling( VGDevice & hdc, float vsizex, float vsizey ) const { float newScaleX = vsizex; float newScaleY = vsizey; getScaling (newScaleX, newScaleY); hdc.SetScale( newScaleX, newScaleY ); // ok // const float sizex = getPageWidth(); // Get the logical (virtual) size // const float sizey = getPageHeight(); // used internaly by Guido. // // if( sizex <= 0 ) return; // if( sizey <= 0 ) return; // // // - Calculate the new device context scaling factors. // float newScaleX = vsizex / sizex; // float newScaleY = vsizey / sizey; // // // - Force the page to be proportional. // // (This could be a setting for GuidoSetSetting(): proportionnal or non-proportionnal) // if( newScaleX > newScaleY ) newScaleX = newScaleY; // if( newScaleY > newScaleX ) newScaleY = newScaleX; // // // - Scale the device context to match desired size & zoom. // hdc.SetScale( newScaleX, newScaleY ); // ok }
/** \brief For debugging purpose only */ void GRNotationElement::DrawExtents( VGDevice & hdc, const VGColor & inColor ) const { if(!mDraw) return; #if (0) hdc.PushPen( inColor, LSPACE * 0.15f ); const float x1 = mPosition.x - getLeftSpace(); const float x2 = mPosition.x + getRightSpace(); const float y = mPosition.y; hdc.Line( x1, y, x2, y ); hdc.Line( x1, y - LSPACE, x1, y + LSPACE ); hdc.Line( x2, y - LSPACE, x2, y + LSPACE ); hdc.PopPen(); #endif }
//---------------------------------------------------------------------------------- void GRJump::OnDraw( VGDevice & hdc ) const { // DrawBoundingBox (hdc, VGColor(255,0,0)); if(!mDraw) return; const ARJump * ar = getARJump(); if (!ar) return; NVRect r = getBoundingBox(); NVPoint pos = getPosition(); pos.x += r.left; FormatStringParserResult::const_iterator assoc; for (assoc = ar->getMark().begin(); assoc != ar->getMark().end(); assoc++) { if (assoc->second == FormatStringParser::kSpecial) { unsigned int symbol = mSymbols[assoc->first]; if (symbol) { OnDrawSymbol( hdc, symbol, pos.x - getPosition().x, 0, getSymbolSize() ); pos.x += GetSymbolExtent( symbol ) * getSymbolSize(); } } else { const VGColor prevTextColor = hdc.GetFontColor(); if (mColRef) hdc.SetFontColor(VGColor(mColRef)); const VGFont* font = SelectTextFont (hdc); const char * text = assoc->first.c_str(); int size = int(assoc->first.size()); float w, h, texty = pos.y + r.bottom + getOffset().y; font->GetExtent ( 'a', &w, &h, &hdc ); texty += (r.bottom - r.top - h) / 2; hdc.DrawString( pos.x + getOffset().x, texty, text, size); font->GetExtent ( text, size, &w, &h, &hdc ); pos.x += w; if (mColRef) hdc.SetFontColor(prevTextColor); } } }
// ---------------------------------------------------------------------------- void GRTempo::DrawText( VGDevice & hdc, const char * cp, float xOffset, float yOffset, float * outWidth ) const { // hdc.SelectFont( mFont ); hdc.SetTextFont( mFont ); hdc.SetFontAlign (getTextAlign()); hdc.DrawString ( xOffset + mPosition.x, yOffset + mPosition.y, cp, (int)strlen(cp) ); if( outWidth ) { float fooHeight; // hdc.GetTextExtent(cp, (int)strlen(cp), outWidth, &fooHeight); const VGFont *font = hdc.GetTextFont(); if (!font) { font = FontManager::gFontText; } if (!font) { std::cerr << "Cannot find text font" << std::endl; *outWidth = 0; } else { font->GetExtent(cp, (int)strlen(cp), outWidth, &fooHeight, &hdc); } } }
void GRDiminuendo::OnDraw( VGDevice & hdc) const { if (!mDraw) return; if (fDimInfos->points[0].x == fDimInfos->points[1].x) return; assert(gCurSystem); GRSystemStartEndStruct * sse = getSystemStartEndStruct(gCurSystem); if (sse == 0) return; if (mColRef) { hdc.PushPenColor(VGColor(mColRef)); hdc.PushFillColor(VGColor(mColRef)); hdc.SetFontColor(VGColor(mColRef)); } hdc.PushPenWidth(fDimInfos->thickness); hdc.Line(fDimInfos->points[0].x , fDimInfos->points[0].y, fDimInfos->points[1].x , fDimInfos->points[1].y); hdc.Line(fDimInfos->points[2].x , fDimInfos->points[2].y, fDimInfos->points[1].x , fDimInfos->points[1].y); const float xMarkingOffset = fDimInfos->points[1].x + 30; const float yMarkingOffset = fDimInfos->points[1].y - 277 + (mTagSize - 1) * 25; OnDrawSymbol(hdc, fDimInfos->fMarkingSymbol, xMarkingOffset, yMarkingOffset, mTagSize); hdc.PopPenWidth(); if (mColRef) { hdc.PopPenColor(); hdc.PopFillColor(); hdc.SetFontColor(VGColor()); } }
// ---------------------------------------------------------------------------- void GRTempo::OnDraw( VGDevice & hdc ) const { if(!mDraw) return; ARTempo *ar = static_cast<ARTempo *>(mAbstractRepresentation); if (!ar) return; VGColor prevFontColor = hdc.GetFontColor(); if (mColRef) hdc.SetFontColor(VGColor(mColRef)); const float noteOffsetY = 0; // LSPACE * 1.85f; float currX = getOffset().x; float dy = 0; if (ar->getDY()) dy = - ar->getDY()->getValue(LSPACE); FormatStringParserResult::const_iterator assoc; for (assoc = ar->getTempoMark().begin(); assoc != ar->getTempoMark().end(); assoc++) { if ((*assoc).second == FormatStringParser::kSpecial) { TYPE_DURATION duration = getDuration((*assoc).first.c_str()); currX += DrawNote( hdc, duration, currX + LSPACE, noteOffsetY + dy ) + LSPACE; } else { float textwidth; DrawText( hdc, (*assoc).first.c_str(), currX, dy, &textwidth ); currX += textwidth; } } if (mColRef) hdc.SetFontColor(prevFontColor); }
void GRBeam::OnDraw( VGDevice & hdc) const { if (error) return; GRSystemStartEndStruct * sse = getSystemStartEndStruct( gCurSystem ); if (sse == 0) return; GRBeamSaveStruct * st = (GRBeamSaveStruct *)sse->p; assert(st); if (mColRef) { VGColor color ( mColRef ); // custom or black hdc.PushFillColor( color ); hdc.PushPen( color, 1); } float ax [4] = { st->p[0].x, st->p[1].x, st->p[3].x, st->p[2].x }; float ay [4] = { st->p[0].y, st->p[1].y, st->p[3].y, st->p[2].y }; // This does the drawing! hdc.Polygon( ax, ay, 4 ); if (st->simpleBeams) { GuidoPos smplpos = st->simpleBeams->GetHeadPosition(); while (smplpos) { GRSimpleBeam * smplbeam = st->simpleBeams->GetNext(smplpos); smplbeam->OnDraw(hdc); } } if (mColRef) { hdc.PopPen(); hdc.PopFillColor(); } }
/** \brief This tries to draw the spring. */ void GRSpring::OnDraw( VGDevice & hdc ) const { const VGColor springColor ( 0, 0, 255, 50 ); // semi-transparent blue const float springThickness = 5; hdc.PushPen( springColor, springThickness ); const float offsety = -100; float x = posx, y = offsety; const int numturns = (int)((x-60.0f) / 40.0f + 0.5f ); if (numturns < 1) { hdc.Line( x, y, (posx + x), offsety ); } else { const float offset = ((x - numturns * 40) * 0.5f); hdc.Line( x, y, posx + offset, offsety ); x = posx + offset; for( float i = 0; i < numturns; i++ ) { hdc.Line( x, y, posx + offset + 40 * i + 10, -20 + offsety ); x = posx + offset + 40 * i + 10; y = -20 + offsety; hdc.Line( x, y, posx + offset + 40 * i + 30, 20 + offsety ); x = posx + offset + 40 * i + 30; y = 20 + offsety; hdc.Line( x, y, posx + offset + 40 * i + 40, offsety ); x = posx + offset + 40 * i + 40; y = offsety; } hdc.Line( x, y, (posx + x), 0 + offsety ); } hdc.PopPen(); }
// ------------------------------------------------------------------------- void GRNotationElement::OnDrawText( VGDevice & hdc, const char * cp, int inCharCount ) const { // first we have to get a font .... if(!mDraw) return; const VGFont* hmyfont = FontManager::gFontText; const int size = getFontSize(); const NVstring * font = getFont(); const unsigned char * colref = getColRef(); if (font && font->length() > 0) { // handle font-attributes ... hmyfont = FontManager::FindOrCreateFont( size, font, getFontAttrib()); } hdc.SetTextFont( hmyfont ); const VGColor prevTextColor = hdc.GetFontColor(); if (colref) hdc.SetFontColor( VGColor( colref )); // const unsigned int ta = hdc.GetTextAlign(); // GColor backColor = hdc.GetTextBackgroundColor(); // hdc.SetTextBackgroundColor( 255, 255, 255, 255 ); const NVPoint & refpos = getReferencePosition(); const NVPoint & offset = getOffset(); hdc.SetFontAlign(getTextAlign()); hdc.DrawString( (float)(mPosition.x + offset.x + (refpos.x * size)), (float)(mPosition.y + offset.y + (refpos.y * size)), cp, inCharCount ); // hdc.SetTextAlign( ta ); // hdc.SetTextBackgroundColor( backColor ); if (colref) hdc.SetFontColor( prevTextColor ); }
/** Draws the note corresponding to a given symbolic musical duration. */ float GRTempo::DrawNote( VGDevice & hdc, const TYPE_DURATION & noteDur, float xOffset, float yOffset ) const { float offsetX = 0; // - Choose notehead unsigned int theSymbol = kNoneSymbol; if (noteDur>=DURATION_1) { theSymbol = kWholeNoteHeadSymbol; } else if (noteDur == DURATION_2 || noteDur == DURATION_3_4 || noteDur == DURATION_7_8) { theSymbol = kHalfNoteHeadSymbol; } else { theSymbol = kFullHeadSymbol; } // - Choose flag unsigned int theFlagSymbol = kNoneSymbol; if (noteDur==DURATION_8 || noteDur == DURATION_3_16 || noteDur == DURATION_7_32) { theFlagSymbol = GRFlag::H8U; } else if(noteDur==DURATION_16 || noteDur == DURATION_3_32 || noteDur == DURATION_7_64) { theFlagSymbol = GRFlag::H16U; } else if(noteDur == DURATION_32) { theFlagSymbol = GRFlag::H32U; } else if (noteDur == DURATION_64) { theFlagSymbol = GRFlag::H64U; } // - Choose dot unsigned int theDotSymbol = kNoneSymbol; // if (noteDur == DURATION_3_4 || noteDur == DURATION_3_8 || noteDur == DURATION_3_16 || noteDur == DURATION_3_32) { if (noteDur.getNumerator() == 3) { theDotSymbol = kNoteDotSymbol; } // - Setup zoom hdc.selectfont(1); // Not very beautiful but avoid a bug during SVG export const float cueScale = 0.70f; hdc.SetScale(cueScale, cueScale); // - Calculate the position of the head float w, h; hdc.GetMusicFont()->GetExtent(theSymbol, &w, &h, &hdc); float xPos = (xOffset + mPosition.x) / cueScale; float yPos = (yOffset + mPosition.y - w / 2.5f) / cueScale; // - Draw Head hdc.DrawMusicSymbol(xPos, yPos, theSymbol); offsetX = w * cueScale; // - Draw Stem if (theSymbol != kWholeNoteHeadSymbol) { float stemLen = 3 * LSPACE; float stemTagSize = 1; const float stemCharSize = LSPACE * stemTagSize; const float halfStemCharSize = 0.5f * stemCharSize; hdc.DrawMusicSymbol( xPos, yPos, kStemUp1Symbol ); // - Draws until the length has been completed ... float offsy = -halfStemCharSize; while( -offsy < stemLen ) // * mSize) { if(( stemCharSize - offsy ) > stemLen ) // * mSize) { offsy = (-(stemLen) // * mSize) + stemCharSize ); hdc.DrawMusicSymbol( xPos, yPos + offsy, kStemUp2Symbol ); break; } hdc.DrawMusicSymbol( xPos, yPos + offsy, kStemUp2Symbol ); offsy -= halfStemCharSize; } } // - Draw flag if (theFlagSymbol != kNoneSymbol) hdc.DrawMusicSymbol( xPos, yPos - 4 * LSPACE, theFlagSymbol ); // - Draw Dot if (theDotSymbol != kNoneSymbol) { hdc.GetMusicFont()->GetExtent(theDotSymbol, &w, &h, &hdc); hdc.DrawMusicSymbol( xPos + 2 * LSPACE, yPos, theDotSymbol); offsetX += LSPACE; } // - Cleanup hdc.SetScale(1 / cueScale, 1 / cueScale); return offsetX; }
/** \brief Draws the score page. The GuidoEngine does not draw nor erase the background. Client applications must display it by themself. Usually, printing does not require to draw a background. */ void GRPage::OnDraw( VGDevice & hdc, const GuidoOnDrawDesc & inDrawInfos ) const { setScaling( hdc, (float)inDrawInfos.sizex, (float)inDrawInfos.sizey ); // if croll coords are in virtual units: hdc.SetOrigin( - (float)inDrawInfos.scrollx, - (float)inDrawInfos.scrolly ); // (JB) sign change // if scroll coords are in device units: // hdc.SetOrigin( - (float)inDrawInfos.scrollx / hdc.GetXScale(), // - (float)inDrawInfos.scrolly / hdc.GetYScale()); if ( /*fullredraw ||*/ inDrawInfos.updateRegion.erase )// (JB) || c->ps.hdc == NULL { gClipRect.Set( 0, 0, getPageWidth(), getPageHeight()); } else { /* was: // This is the update region const GCoord left = c->updateRegion.left; const GCoord top = c->updateRegion.top; const GCoord right = c->updateRegion.right; const GCoord bottom = c->updateRegion.bottom; DPtoLPRect( hdc, left, top, right, bottom, &gClipRect ); // (JB) still ok ? */ gClipRect.Set( float(inDrawInfos.updateRegion.left), float(inDrawInfos.updateRegion.top), float(inDrawInfos.updateRegion.right), float(inDrawInfos.updateRegion.bottom) ); } #if (0) // Draw margins. const float x1 = getMarginLeft(); const float x2 = getPageWidth() - getMarginRight(); const float x3 = getPageWidth(); const float y1 = getMarginTop(); const float y2 = getPageHeight() - getMarginBottom(); const float y3 = getPageHeight(); hdc.PushPen( VGColor( 150, 150, 255 ), 5 ); // opaque hdc.PushFillColor( VGColor( 0, 0, 0, ALPHA_OPAQUE )); // DrawBoundingBox( hdc, GColor( 200, 255, 200 )); hdc.Rectangle( 0, 0, x3, y3 ); hdc.Rectangle( x1, y1, x2, y2 ); hdc.Line( 0, 0, x1, y1 ); // top left hdc.Line( 0, y3, x1, y2 ); // bottom left hdc.Line( x3, 0, x2, y1 ); // top right hdc.Line( x3, y3, x2, y2 ); // bottom right hdc.PopFillColor(); hdc.PopPen(); #endif // - Draws elements of the page. OnDraw( hdc ); // trace (hdc); }
void GRCluster::OnDraw(VGDevice &hdc) const { if (mDraw) { if (fNoteFormatColor) { VGColor color(fNoteFormatColor); hdc.PushPen(color, 1); if (!mColRef) hdc.PushFillColor(color); } if (mColRef) { VGColor color(mColRef); hdc.PushFillColor(color); hdc.PushPenColor(color); } // - Quarter notes and less if (fDuration < DURATION_2) { const float xCoords [] = { mMapping.left, mMapping.right, mMapping.right, mMapping.left}; const float yCoords [] = { mMapping.top, mMapping.top, mMapping.bottom, mMapping.bottom}; hdc.Polygon(xCoords, yCoords, 4); } else { const float xCoords1 [] = { mMapping.left, mMapping.right, mMapping.right, mMapping.left}; const float yCoords1 [] = { mMapping.top, mMapping.top, mMapping.top + 6 * mTagSize * fsize, mMapping.top + 6 * mTagSize * fsize}; const float xCoords2 [] = { mMapping.right - 6 * mTagSize * fsize, mMapping.right, mMapping.right, mMapping.right - 6 * mTagSize * fsize}; const float yCoords2 [] = { mMapping.top, mMapping.top, mMapping.bottom, mMapping.bottom}; const float xCoords3 [] = { mMapping.left, mMapping.right, mMapping.right, mMapping.left}; const float yCoords3 [] = { mMapping.bottom - 6 * mTagSize * fsize, mMapping.bottom - 6 * mTagSize * fsize, mMapping.bottom, mMapping.bottom}; const float xCoords4 [] = { mMapping.left, mMapping.left + 6 * mTagSize * fsize, mMapping.left + 6 * mTagSize * fsize, mMapping.left}; const float yCoords4 [] = { mMapping.top, mMapping.top, mMapping.bottom, mMapping.bottom}; hdc.Polygon(xCoords1, yCoords1, 4); hdc.Polygon(xCoords2, yCoords2, 4); hdc.Polygon(xCoords3, yCoords3, 4); hdc.Polygon(xCoords4, yCoords4, 4); } // - Restore context if (mColRef) { hdc.PopPenColor(); hdc.PopFillColor(); } if (fNoteFormatColor) { if (!mColRef) hdc.PopFillColor(); hdc.PopPen(); } } }
// -------------------------------------------------------------------------- void GRRepeatBegin::OnDraw(VGDevice & hdc ) const { if (!mDraw || fSize < kMinNoteSize) return; VGColor prevColor = hdc.GetFontColor(); if (mColRef) { hdc.PushFillColor(VGColor(mColRef)); hdc.SetFontColor(VGColor(mColRef)); } // - Vertical adjustement according to staff's line number float offsety1 = (fmod(- 0.5f * fLineNumber - 2, 3) + 1.5f) * LSPACE; float offsety2 = 0; if (fLineNumber != 0 && fLineNumber != 1) offsety2 = ((fLineNumber - 5) % 6) * LSPACE; float rightLineThickness = 1.8f * kLineThick * fSize; // - Horizontal adjustement according to staff's lines size and staff's size const float offsetX = 0.5f * (fStaffThickness - 4) - 30 * (fSize - 1) + (fSize - 1) * (fStaffThickness - 4) * 0.5f + 40; const float spacing = fBaseThickness + LSPACE * 0.4f * fSize - rightLineThickness; const float x1 = mPosition.x - mBoundingBox.Width() + offsetX; const float x2 = x1 + spacing; const float y1 = mPosition.y + offsety1 * fSize; const float y2 = y1 + (mBoundingBox.bottom + offsety2) * fSize; hdc.Rectangle(x1, y1, x1 + fBaseThickness, y2); hdc.Rectangle(x2, y1, x2 + rightLineThickness, y2); /* Two points drawing */ float offsety1AccordingToLineNumber = 0; float offsety2AccordingToLineNumber = 0; if (fLineNumber == 0) offsety1AccordingToLineNumber = - LSPACE / 2 * fSize; else if (fLineNumber == 1) offsety1AccordingToLineNumber = - LSPACE * fSize; else if (fLineNumber == 2) { offsety1AccordingToLineNumber = 14 * fSize; offsety2AccordingToLineNumber = - 2 * offsety1AccordingToLineNumber; } int pointSymbol = 220; float pointOffsety1 = - 5 * fSize + offsety1AccordingToLineNumber; float pointOffsety2 = pointOffsety1 + LSPACE * fSize + offsety2AccordingToLineNumber; float pointOffsetx = 28 * (fSize - 1) + 0.5f * (fStaffThickness - 4) + (fSize - 1) * (fStaffThickness - 4) * 0.5f + 8; float pointSize = 0.4f * fSize; DrawSymbol(hdc, pointSymbol, pointOffsetx, pointOffsety1, pointSize); DrawSymbol(hdc, pointSymbol, pointOffsetx, pointOffsety2, pointSize); /**********************/ if (mColRef) { hdc.SetFontColor(prevColor); hdc.PopFillColor(); } }
void GRBeam::OnDraw( VGDevice & hdc) const { if (error) return; if(!mDraw) return; GRSystemStartEndStruct * sse = getSystemStartEndStruct( gCurSystem ); if (sse == 0) return; GRBeamSaveStruct * st = (GRBeamSaveStruct *)sse->p; assert(st); if (mColRef) { VGColor color ( mColRef ); // custom or black hdc.PushFillColor( color ); hdc.PushPen( color, 1); } float ax [4] = { st->p[0].x, st->p[1].x, st->p[3].x, st->p[2].x }; float ay [4] = { st->p[0].y, st->p[1].y, st->p[3].y, st->p[2].y }; // This does the drawing! hdc.Polygon(ax, ay, 4); if (st->simpleBeams) { GuidoPos smplpos = st->simpleBeams->GetHeadPosition(); while (smplpos) { GRSimpleBeam * smplbeam = st->simpleBeams->GetNext(smplpos); smplbeam->OnDraw(hdc); } } if(drawDur) { const char * fraction = st->duration.c_str(); size_t n = st->duration.length(); hdc.PushPenWidth(4); if(sse->startflag != GRSystemStartEndStruct::OPENLEFT) { hdc.Line(st->DurationLine[0].x, st->DurationLine[0].y, st->DurationLine[1].x, st->DurationLine[1].y); hdc.Line(st->DurationLine[1].x, st->DurationLine[1].y, st->DurationLine[2].x, st->DurationLine[2].y); hdc.Line(st->DurationLine[3].x, st->DurationLine[3].y, st->DurationLine[4].x, st->DurationLine[4].y); } else hdc.Line(st->DurationLine[1].x, st->DurationLine[1].y, st->DurationLine[4].x, st->DurationLine[4].y); if(sse->endflag != GRSystemStartEndStruct::OPENRIGHT) hdc.Line(st->DurationLine[4].x, st->DurationLine[4].y, st->DurationLine[5].x, st->DurationLine[5].y); const VGFont* hmyfont; hmyfont = FontManager::gFontText; hdc.SetTextFont( hmyfont ); if (sse->startflag != GRSystemStartEndStruct::OPENLEFT) hdc.DrawString(st->DurationLine[2].x + LSPACE/4, st->DurationLine[2].y + LSPACE / 2, fraction, n); hdc.PopPenWidth(); } if (mColRef) { hdc.PopPen(); hdc.PopFillColor(); } }
// ---------------------------------------------------------------------------- // * DoDraw // ---------------------------------------------------------------------------- void GuidoCarbonControl::DoDraw() { const GRHandler guidoRef = GetGuidoGR(); if( guidoRef == 0 ) return; ControlRef theControl = GetControlRef(); if( theControl == 0 ) return; // - Get our local size int localWidth; int localHeight; GetSize( &localWidth, &localHeight ); CGRect deviceRect = ::CGRectMake( 0, 0, localWidth, localHeight ); // VGDevice * device = GetGDevice(); // <- was const int kScrollBarHeight = 15; // - Create the graphic context. It must be initialized with the actual size of the window, // otherwise the y-origin is not calculated properly. WindowRef winRef = ::GetControlOwner( theControl ); GrafPtr port = ::GetWindowPort( winRef ); CGContextRef contextRef = 0; OSStatus status = ::CreateCGContextForPort( port, &contextRef ); if( status != noErr ) return; GSystemOSX system(contextRef, NULL); VGDevice* device = system.CreateDisplayDevice(); device->NotifySize(localWidth, localHeight + kScrollBarHeight ); ::CGContextRelease(contextRef); // because the device now owns the context. // - Draw the background device->BeginDraw(); device->PushPen( VGColor( 0, 0, 0, ALPHA_OPAQUE ), 1 ); device->PushFillColor( VGColor( 255, 255, 255, ALPHA_TRANSPARENT )); device->Rectangle( 0, 0, localWidth, localHeight ); device->PopFillColor(); device->PopPen(); // - Setup the clipping rectangle, to avoid drawing on scrollbars. ::CGContextClipToRect( contextRef, deviceRect ); // - Draw the music score int virtualScrollX = (int)((float)mScrollX * 10 / GetZoom()); int virtualScrollY = (int)((float)mScrollY * 10 / GetZoom()); float virtualVisibleWidth = localWidth * 10 / GetZoom(); float virtualVisibleHeight = localHeight * 10 / GetZoom(); float fullScoreWidth; float fullScoreHeight; GetFullScoreSize( &fullScoreWidth, &fullScoreHeight ); GuidoOnDrawDesc desc; desc.handle = guidoRef; desc.hdc = device; desc.updateRegion.erase = false; desc.updateRegion.left = virtualScrollX; // absolute virtual coordinates clip rect desc.updateRegion.top = virtualScrollY; desc.updateRegion.right = (int)(virtualScrollX + virtualVisibleWidth); desc.updateRegion.bottom = (int)(virtualScrollY + virtualVisibleHeight); desc.scrollx = (int)virtualScrollX; desc.scrolly = (int)virtualScrollY; desc.page = GetPageNum(); desc.sizex = (int)fullScoreWidth; desc.sizey = (int)fullScoreHeight; MClock clock; GuidoOnDraw( &desc ); // debug #if 0 std::cout << "Score : sizex = " << desc.sizex << " ; sizey = " << desc.sizey << std::endl; std::cout << "Guido: time do draw the score: " << clock.Milliseconds() << " ms" << std::endl; // std::cout << "Guido: graphical objects: " << GuidoGRObjectCount() << std::endl; #endif if( GetParam( kDrawSymbolMap ) == 1 ) DrawSymbolMap(); // drawMap (guidoRef, device, GetPageNum()); device->EndDraw(); delete device; }
// ----------------------------------------------------------------------------- void GRBowing::OnDraw( VGDevice & hdc) const { // DrawBoundingBox( hdc, GColor( 255, 120, 150, 120 )); // DEBUG if(!mDraw) return; if (error) return; assert( gCurSystem ); GRSystemStartEndStruct * sse = getSystemStartEndStruct( gCurSystem ); if( sse == 0) return; // don't draw // now we need to get the position and offset for the current bowing ... GRBowingSaveStruct * bowInfos = (GRBowingSaveStruct *)sse->p; assert(bowInfos); /* NVPoint pstart, pmid, pend, poffsetUp, poffsetDown; pstart.x=bowInfos->position.x+bowInfos->offsets[0].x; pstart.y=bowInfos->position.y+bowInfos->offsets[0].y; pmid.x=bowInfos->position.x+bowInfos->offsets[1].x; pmid.y=bowInfos->position.y+bowInfos->offsets[1].y; pend.x=bowInfos->position.x+bowInfos->offsets[2].x; pend.y=bowInfos->position.y+bowInfos->offsets[2].y; */ // GColor backColor = hdc.GetTextBackgroundColor(); // hdc.SetTextBackgroundColor( 255,0,0 ); // why red? // now we do it with correct colors: // VGColor color ( mColRef ); // custom or black if (mColRef) hdc.PushFillColor( VGColor( mColRef ) ); // hdc.PushPen( color, 1 ); const float x = bowInfos->position.x; const float y = bowInfos->position.y; // keith hamel ::drawSlur( hdc, x + bowInfos->offsets[0].x, y + bowInfos->offsets[0].y, x + bowInfos->offsets[1].x, y + bowInfos->offsets[1].y, x + bowInfos->offsets[2].x, y + bowInfos->offsets[2].y, bowInfos->inflexion ); // no floodfill until point-issue is eliminated ///ExtFloodFill(hdc,pmid.x,pmid.y,fg,FLOODFILLSURFACE); // FloodFill(hdc,pmid.x,pmid.y,fg); // restore old pen and brush // hdc.PopPen(); if (mColRef) hdc.PopFillColor(); // overdraw borderlines with black color /* drawslur(hdc, pstart,poffsetUp,pend); drawslur(hdc, pstart,poffsetDown,pend); */ // restore old backgound color // hdc.SetTextBackgroundColor( backColor ); }
/** \brief Manage the drawing of trill line */ void GRTrill::OnDraw(VGDevice & hdc , float right, float noteY, int nVoice) { VGColor oldColor = hdc.GetFontColor(); if (fType == 0) { //TRILL=0 NVRect r = mBoundingBox; r += getPosition(); float left; float lastPos = GRTrill::getLastPosX(nVoice); // we check if the trill line is begining or continuing another if (begin) { // the 'tr' is drawn only at the begining of the trill, if the parameter 'tr' isn't set as false if (fShowTR) GRNotationElement::OnDraw(hdc); // in order to adapt the accidental to the size of the trill : fAccidental->setPosition(fAccidental->getPosition() + NVPoint(mBoundingBox.Width()/2*(mTagSize-1), - mBoundingBox.Height()/2*(mTagSize-1))); fAccidental->setSize(mTagSize/2); fAccidental->OnDraw(hdc); NVRect rAcc = fAccidental->getBoundingBox(); rAcc += fAccidental->getPosition(); float leftR = r.left + r.Width()*mTagSize; float leftA = rAcc.left + rAcc.Width()*mTagSize + fAccidental->getOffset().x - mTagOffset.x; // check the position of the accidental to know where to begin the trill line if (leftA > leftR && (fAccidental->getOffset().y - mTagOffset.y) > 0 && (fAccidental->getOffset().y - mTagOffset.y) < r.Height()+rAcc.Height()) left = leftA; else left = leftR; } else { // continue the line from the last position (or at the begining of a new system) if (lastPos < right) left = lastPos; else left = r.left - LSPACE; } // now we iterates the symbol kTilde as many times as posible from "left" to "right" float x = (left - r.left); if (!begin) x -= mTagOffset.x; else left += mTagOffset.x; while (left + widthOfTilde <= right) { if (fDrawOnNoteHead) GRNotationElement::OnDrawSymbol(hdc, kTilde, x, noteY - getPosition().y, mTagSize); else GRNotationElement::OnDrawSymbol(hdc, kTilde, x, 0, mTagSize); x += widthOfTilde; left += widthOfTilde; } GRTrill::getLastPosX(nVoice) = left; } else { if (fShowTR) GRNotationElement::OnDraw(hdc); fAccidental->OnDraw(hdc); } hdc.SetFontColor(oldColor); }
/** \brief Draws a slur. (JB) experimental modifications to original code It takes 3 control points x1,y1,x2,y2,x3,y3 and draws a curv from x1, y1 through x2,y2 (approximately) to x3, y3. The thickness of the slur is set by SLUR_THICKNESS (1 - 10) */ void drawSlur(VGDevice & hdc, float x1, float y1, float x2, float y2, float x3, float y3, float inflexion ) { float delx1, delx2, ratio; float addY2, addX, addY, x2a, y2a, x2b, y2b; float maxD;//, h1, h2; // if start and endpoint is the same, just don't do anything. // this is a hack, whatsoever, because this should not really happen! if (x1==x3) return; const float oneOverDeltaX = (1.0f / (x3 - x1)); maxD = (SLUR_THICKNESS * 1.25f); ratio = (y3 - y1) * oneOverDeltaX; addY2 = (y2 - y1) / 3; addX = (x3 - x1) / (2 + inflexion); // defines the attack of the curve. addY = addX * ratio; x2a = x2 - addX; y2a = y2 - addY + addY2; x2b = x2 + addX; y2b = y2 - addY + addY2; // h1 = (y2a > y1) ? (y2a - y1) : (y1 - y2a); // h2 = (y2b > y3) ? (y2b - y3) : (y3 - y2b); // if (x2a - x1 > h1) x2a = x1 + h1; // if (x3 - x2b > h2) x2b = x3 - h2; delx1 = ((y3 - y1) * SLUR_THICKNESS) * oneOverDeltaX; delx2 = ((y3 - y1) * SLUR_THICKNESS) * oneOverDeltaX; if (delx1 > maxD) delx1 = maxD; if (delx2 > maxD) delx2 = maxD; if (delx1 < -maxD) delx1 = -maxD; if (delx2 < -maxD) delx2 = -maxD; const int ptCount = (2 * ( NSEGS + 3 )); NVPoint thePoints[ ptCount ]; //ptCount ]; // CALCULATE THE FIRST CURVE // PROBABLY YOU WANT TO START A POLYGON NOW int index = 0; makeCurve( x1, y1, x2a, y2a, x2b, y2b, x3, y3, NSEGS, thePoints, &index ); y2a = (y2a < y1 ? y2a + SLUR_THICKNESS : y2a - SLUR_THICKNESS); y2b = (y2b < y3 ? y2b + SLUR_THICKNESS : y2b - SLUR_THICKNESS); x2a += delx1; x2b += delx2; // CALCULATE THE SECOND CURVE makeCurve( x3, y3, x2b, y2b, x2a, y2a, x1, y1, NSEGS, thePoints, &index ); //PROBABLY YOU WANT TO CLOSE THE POLYGON NOW AND FILL IT float xPoints [ ptCount ]; float yPoints [ ptCount ]; for( int currPt = 0; currPt < index; ++ currPt ) { xPoints [ currPt ] = thePoints[ currPt ].x; yPoints [ currPt ] = thePoints[ currPt ].y; } hdc.Polygon( xPoints, yPoints, index ); /* - DEBUG -> hdc.PushPen( GColor( 200, 0, 0 ), 5 ); hdc.Line( x1 - 20, y1 - 20, x1 + 20, y1 + 20); hdc.Line( x1 - 20, y1 + 20, x1 + 20, y1 - 20); hdc.PushPen( GColor( 200, 0, 200 ), 5 ); hdc.Line( x2 - 20, y2 - 20, x2 + 20, y2 + 20); hdc.Line( x2 - 20, y2 + 20, x2 + 20, y2 - 20); hdc.PopPen(); hdc.Line( x2a - 20, y2a - 20, x2a + 20, y2a + 20); hdc.Line( x2a - 20, y2a + 20, x2a + 20, y2a - 20); hdc.Line( x2b - 20, y2b - 20, x2b + 20, y2b + 20); hdc.Line( x2b - 20, y2b + 20, x2b + 20, y2b - 20); hdc.Line( x3 - 20, y3 - 20, x3 + 20, y3 + 20); hdc.Line( x3 - 20, y3 + 20, x3 + 20, y3 - 20); hdc.PopPen(); // <- */ }
// ---------------------------------------------------------------------------- void GRTuplet::OnDraw(VGDevice & hdc) const { if(!mDraw) return; assert(gCurSystem); GRSystemStartEndStruct * sse = getSystemStartEndStruct(gCurSystem); if (sse == 0) return; VGColor prevFontColor = hdc.GetFontColor(); if (mColRef) { hdc.SetFontColor(VGColor(mColRef)); hdc.PushPenColor(VGColor(mColRef)); } GRTupletSaveStruct * st = (GRTupletSaveStruct *)sse->p; const ARTuplet * arTuplet = getARTuplet(); int charCount = 0; float const thickness = arTuplet->getThickness(); float const dxOffset = (arTuplet->getDX() ? arTuplet->getDX()->getValue() : 0); // - Draws the number const int numerator = arTuplet->getNumerator(); if (numerator > 0) { std::stringstream bufferNumeratorDenominatorStream; const int denominator = arTuplet->getDenominator(); if (denominator > 0) bufferNumeratorDenominatorStream << numerator << ":" << denominator; else bufferNumeratorDenominatorStream << numerator; std::string bufferNumeratorDenominator = bufferNumeratorDenominatorStream.str(); charCount = bufferNumeratorDenominator.size(); const VGFont *font = 0; const NVstring fontName("Times New Roman"); NVstring attrs; if (arTuplet->isTextBold()) attrs = "b"; font = FontManager::FindOrCreateFont(int(80 * arTuplet->getTextSize()), &fontName, &attrs); hdc.SetTextFont(font); /* In order that numerator/denominator stays at the same vertical position even if size is changed */ float extentCharNumeratorDenominatorx; float extentCharNumeratorDenominatory; FontManager::gFontScriab->GetExtent(bufferNumeratorDenominator.c_str(), bufferNumeratorDenominator.size(), &extentCharNumeratorDenominatorx, &extentCharNumeratorDenominatory, &hdc); int offset = int(extentCharNumeratorDenominatory / 11.2 * arTuplet->getTextSize() - 40); /***************************************************************************************************/ hdc.SetFontAlign(VGDevice::kAlignCenter | VGDevice::kAlignBottom); hdc.DrawString(st->textpos.x + dxOffset, st->textpos.y + offset, bufferNumeratorDenominator.c_str(), charCount); } // - Draws the braces const float middleX = (st->p1.x + st->p2.x) * 0.5f; const float middleY = (st->p1.y + st->p2.y) * 0.5f; const float slope = (st->p2.y - st->p1.y) / (st->p2.x - st->p1.x); //<- could be stored const float textSpace = ((float)charCount + float(0.5)) * LSPACE * float(0.5) * arTuplet->getTextSize(); if (mShowLeftBrace | mShowRightBrace) { hdc.PushPenWidth(thickness); if (mShowLeftBrace) { //arTuplet->getLeftBrace()) // (mBraceState & BRACELEFT) float p1X = st->p1.x + dxOffset; if (sse->startflag == GRSystemStartEndStruct::LEFTMOST) { GDirection d = mDirection; // If a position is explicitely set, we use it. if (arTuplet->isPositionAbove() == 1) d = dirUP; else if (arTuplet->isPositionAbove() == -1) d = dirDOWN; hdc.Line(p1X, st->p1.y + 0.5f * LSPACE * (float)d, p1X, st->p1.y); } hdc.Line(p1X, st->p1.y, middleX - textSpace + dxOffset, middleY - slope * textSpace ); } if (mShowRightBrace) { //arTuplet->getRightBrace()) // (mBraceState & BRACERIGHT) float p2X = st->p2.x + dxOffset; hdc.Line(middleX + textSpace + dxOffset, middleY + slope * textSpace, p2X, st->p2.y); if (sse->endflag == GRSystemStartEndStruct::RIGHTMOST) { GDirection d = mDirection; // If a position is explicitely set, we use it. if (arTuplet->isPositionAbove() == 1) d = dirUP; else if (arTuplet->isPositionAbove() == -1) d = dirDOWN; hdc.Line(p2X, st->p2.y, p2X, st->p2.y + 0.5f * LSPACE * (float)d); } } hdc.PopPenWidth(); } if (mColRef) { hdc.SetFontColor(prevFontColor); hdc.PopPenColor(); } }
//------------------------------------------------------------------------- void QGuidoPainter::draw( QPainter * painter , int page , const QRect& drawRectangle , const QRect& redrawRectangle) { if ( !hasValidGR() ) return; painter->save(); painter->setClipRect( drawRectangle ); painter->translate( drawRectangle.x() , drawRectangle.y() ); //Creation of temporaries Qt implementations of VGSystem & VGDevice. VGSystem * sys = new GSystemQt( painter ); VGDevice * dev = sys->CreateDisplayDevice(); //Update the mDesc with the specified page and draw dimensions. mDesc.hdc = dev; page = MAX(1 , page); page = MIN(pageCount() , page); mDesc.page = page; mDesc.sizex = drawRectangle.width(); mDesc.sizey = drawRectangle.height(); //mDesc.scrollx = -drawRectangle.x(); //mDesc.scrolly = -drawRectangle.y(); if ( redrawRectangle.isNull() ) { //Redraw everything mDesc.updateRegion.erase = true; } else { //1. Computes the actual drawing rectangle //(because the Guido Score won't strech and will keep its height/width ratio, //the drawing rectangle is different from the QPainter's QPaintDevice rectangle.). float ratio = heightForWidth(1000,page) / 1000.0f; //This ratio means that: height = ratio * width. bool drawRectTooHigh = ( mDesc.sizey >= (mDesc.sizex * ratio) ); int actualWidth, actualHeight; if ( drawRectTooHigh ) { actualWidth = mDesc.sizex; actualHeight = actualWidth * ratio; } else { actualHeight = mDesc.sizey; actualWidth = actualHeight / ratio; } //2. Conversion of the redrawRectangle from QPaintDevice coordinate space to GuidoVirtualUnit. GuidoPageFormat format; GuidoGetPageFormat( mDesc.handle , page , &format ); float widthConversionFactor = actualWidth / format.width; float heightConversionFactor = actualHeight / format.height; // pixel / conversionFactor = GuidoVirtualUnit mDesc.updateRegion.left = (redrawRectangle.x() - drawRectangle.x()) / widthConversionFactor; mDesc.updateRegion.top = (redrawRectangle.y() - drawRectangle.y()) / heightConversionFactor; mDesc.updateRegion.right = ( (redrawRectangle.x() - drawRectangle.x()) + redrawRectangle.width() ) / widthConversionFactor; mDesc.updateRegion.bottom = ( (redrawRectangle.y() - drawRectangle.y()) + redrawRectangle.height() ) / heightConversionFactor; mDesc.updateRegion.erase = false; } // QTime time; // time.start(); //Actual draw of the Guido Score. VGColor color(fCurrentColor.red(), fCurrentColor.green(), fCurrentColor.blue(), fCurrentColor.alpha()); dev->SelectPenColor (color); dev->SelectFillColor(color); dev->SetFontColor (color); #if absoluteTransform1 || absoluteTransform2 // DF Apr. 28 2011 // rescaling introduced to take account of the QTDevice::SetScale change // the QTDevice::SetScale change corresponds to the common VGDevice demantic and implementation // actually commented out due to unresolved problems with rotations qreal xs, ys; QPainter * p = (QPainter*)dev->GetNativeContext(); p->worldTransform().map(qreal(mDesc.sizex), qreal(mDesc.sizey), &xs, &ys); mDesc.sizex = xs; mDesc.sizey = ys; #endif GuidoOnDraw (&mDesc); // qDebug("Score : width = %d , height = %d" , mDesc.sizex , mDesc.sizey ); // qDebug("QGuidoPainter: Draw time : %d ms" , time.elapsed() ); delete dev; delete sys; painter->restore(); }