/** \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 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); }
//---------------------------------------------------------------------------------- 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 GRCrescendo::OnDraw( VGDevice & hdc) const { if (!mDraw) return; if (fCrescInfos->points[0].x == fCrescInfos->points[1].x) return; assert(gCurSystem); GRSystemStartEndStruct * sse = getSystemStartEndStruct(gCurSystem); if (sse == 0) return; const VGColor prevTextColor = hdc.GetFontColor(); if (mColRef) { hdc.PushPenColor(VGColor(mColRef)); hdc.PushFillColor(VGColor(mColRef)); hdc.SetFontColor(VGColor(mColRef)); } hdc.PushPenWidth(fCrescInfos->thickness); hdc.Line(fCrescInfos->points[0].x , fCrescInfos->points[0].y, fCrescInfos->points[1].x , fCrescInfos->points[1].y); hdc.Line(fCrescInfos->points[0].x , fCrescInfos->points[0].y, fCrescInfos->points[2].x , fCrescInfos->points[2].y); const float xMarkingOffset = fCrescInfos->points[1].x + 30; const float yMarkingOffset = fCrescInfos->points[0].y - 277 + (mTagSize - 1) * 25; if (fCrescInfos->fMarkingSymbol != 0) OnDrawSymbol(hdc, fCrescInfos->fMarkingSymbol, xMarkingOffset, yMarkingOffset, mTagSize); hdc.PopPenWidth(); if (mColRef) { hdc.SetFontColor(prevTextColor); hdc.PopFillColor(); hdc.PopPenColor(); } }
// ---------------------------------------------------------------------------- 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 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 ); }
/** \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); }
// -------------------------------------------------------------------------- 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 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(); }
// ---------------------------------------------------------------------------- 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(); } }