void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF &, const int frameIndex ) { bool emptyTable = mTableContents.length() == 0; if ( emptyTable && mEmptyTableMode == QgsLayoutTable::HideTable ) { //empty table set to hide table mode, so don't draw anything return; } if ( !mLayout->renderContext().isPreviewRender() ) { //exporting composition, so force an attribute refresh //we do this in case vector layer has changed via an external source (e.g., another database user) refreshAttributes(); } //calculate which rows to show in this frame QPair< int, int > rowsToShow = rowRange( frameIndex ); double gridSizeX = mShowGrid && mVerticalGrid ? mGridStrokeWidth : 0; double gridSizeY = mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0; double cellHeaderHeight = QgsLayoutUtils::fontAscentMM( mHeaderFont ) + 2 * mCellMargin; double cellBodyHeight = QgsLayoutUtils::fontAscentMM( mContentFont ) + 2 * mCellMargin; QRectF cell; //calculate whether a header is required bool drawHeader = ( ( mHeaderMode == QgsLayoutTable::FirstFrame && frameIndex < 1 ) || ( mHeaderMode == QgsLayoutTable::AllFrames ) ); //calculate whether drawing table contents is required bool drawContents = !( emptyTable && mEmptyTableMode == QgsLayoutTable::ShowMessage ); int numberRowsToDraw = rowsToShow.second - rowsToShow.first; int numberEmptyRows = 0; if ( drawContents && mShowEmptyRows ) { numberRowsToDraw = rowsVisible( frameIndex, rowsToShow.first, true ); numberEmptyRows = numberRowsToDraw - rowsToShow.second + rowsToShow.first; } bool mergeCells = false; if ( emptyTable && mEmptyTableMode == QgsLayoutTable::ShowMessage ) { //draw a merged row for the empty table message numberRowsToDraw++; rowsToShow.second++; mergeCells = true; } QPainter *p = context.renderContext().painter(); p->save(); // painter is scaled to dots, so scale back to layout units p->scale( context.renderContext().scaleFactor(), context.renderContext().scaleFactor() ); //draw the text p->setPen( Qt::SolidLine ); double currentX = gridSizeX; double currentY = gridSizeY; if ( drawHeader ) { //draw the headers int col = 0; for ( const QgsLayoutTableColumn *column : qgis::as_const( mColumns ) ) { //draw background p->save(); p->setPen( Qt::NoPen ); p->setBrush( backgroundColor( -1, col ) ); p->drawRect( QRectF( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, cellHeaderHeight ) ); p->restore(); currentX += mCellMargin; Qt::TextFlag textFlag = static_cast< Qt::TextFlag >( 0 ); if ( column->width() <= 0 ) { //automatic column width, so we use the Qt::TextDontClip flag when drawing contents, as this works nicer for italicised text //which may slightly exceed the calculated width //if column size was manually set then we do apply text clipping, to avoid painting text outside of columns width textFlag = Qt::TextDontClip; } cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellHeaderHeight ); //calculate alignment of header Qt::AlignmentFlag headerAlign = Qt::AlignLeft; switch ( mHeaderHAlignment ) { case FollowColumn: headerAlign = column->hAlignment(); break; case HeaderLeft: headerAlign = Qt::AlignLeft; break; case HeaderCenter: headerAlign = Qt::AlignHCenter; break; case HeaderRight: headerAlign = Qt::AlignRight; break; } QgsLayoutUtils::drawText( p, cell, column->heading(), mHeaderFont, mHeaderFontColor, headerAlign, Qt::AlignVCenter, textFlag ); currentX += mMaxColumnWidthMap[ col ]; currentX += mCellMargin; currentX += gridSizeX; col++; } currentY += cellHeaderHeight; currentY += gridSizeY; } //now draw the body cells int rowsDrawn = 0; if ( drawContents ) { //draw the attribute values for ( int row = rowsToShow.first; row < rowsToShow.second; ++row ) { rowsDrawn++; currentX = gridSizeX; int col = 0; //calculate row height double rowHeight = mMaxRowHeightMap[row + 1] + 2 * mCellMargin; for ( const QgsLayoutTableColumn *column : qgis::as_const( mColumns ) ) { //draw background p->save(); p->setPen( Qt::NoPen ); p->setBrush( backgroundColor( row, col ) ); p->drawRect( QRectF( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, rowHeight ) ); p->restore(); // currentY = gridSize; currentX += mCellMargin; QVariant cellContents = mTableContents.at( row ).at( col ); QString str = cellContents.toString(); Qt::TextFlag textFlag = static_cast< Qt::TextFlag >( 0 ); if ( column->width() <= 0 && mWrapBehavior == TruncateText ) { //automatic column width, so we use the Qt::TextDontClip flag when drawing contents, as this works nicer for italicised text //which may slightly exceed the calculated width //if column size was manually set then we do apply text clipping, to avoid painting text outside of columns width textFlag = Qt::TextDontClip; } else if ( textRequiresWrapping( str, column->width(), mContentFont ) ) { str = wrappedText( str, column->width(), mContentFont ); } cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], rowHeight ); QgsLayoutUtils::drawText( p, cell, str, mContentFont, mContentFontColor, column->hAlignment(), column->vAlignment(), textFlag ); currentX += mMaxColumnWidthMap[ col ]; currentX += mCellMargin; currentX += gridSizeX; col++; } currentY += rowHeight; currentY += gridSizeY; } } if ( numberRowsToDraw > rowsDrawn ) { p->save(); p->setPen( Qt::NoPen ); //draw background of empty rows for ( int row = rowsDrawn; row < numberRowsToDraw; ++row ) { currentX = gridSizeX; int col = 0; if ( mergeCells ) { p->setBrush( backgroundColor( row + 10000, 0 ) ); p->drawRect( QRectF( gridSizeX, currentY, mTableSize.width() - 2 * gridSizeX, cellBodyHeight ) ); } else { for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) ) { Q_UNUSED( column ); //draw background //we use a bit of a hack here - since we don't want these extra blank rows to match the firstrow/lastrow rule, add 10000 to row number p->setBrush( backgroundColor( row + 10000, col ) ); p->drawRect( QRectF( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, cellBodyHeight ) ); // currentY = gridSize; currentX += mMaxColumnWidthMap[ col ] + 2 * mCellMargin; currentX += gridSizeX; col++; } } currentY += cellBodyHeight + gridSizeY; } p->restore(); } //and the borders if ( mShowGrid ) { QPen gridPen; gridPen.setWidthF( mGridStrokeWidth ); gridPen.setColor( mGridColor ); gridPen.setJoinStyle( Qt::MiterJoin ); p->setPen( gridPen ); if ( mHorizontalGrid ) { drawHorizontalGridLines( p, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader ); } if ( mVerticalGrid ) { drawVerticalGridLines( p, mMaxColumnWidthMap, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader, mergeCells ); } } //special case - no records and table is set to ShowMessage mode if ( emptyTable && mEmptyTableMode == QgsLayoutTable::ShowMessage ) { double messageX = gridSizeX + mCellMargin; double messageY = gridSizeY + ( drawHeader ? cellHeaderHeight + gridSizeY : 0 ); cell = QRectF( messageX, messageY, mTableSize.width() - messageX, cellBodyHeight ); QgsLayoutUtils::drawText( p, cell, mEmptyTableMessage, mContentFont, mContentFontColor, Qt::AlignHCenter, Qt::AlignVCenter, static_cast< Qt::TextFlag >( 0 ) ); } p->restore(); }
const Glyph& TextRenderer::getGlyph(char c) { Glyph& glyph = _glyphs[c]; if (glyph.isValid()) { return glyph; } // we use 'J' as a representative size for the solid block character QChar ch = (c == SOLID_BLOCK_CHAR) ? QChar('J') : QChar(c); QRect bounds = _metrics.boundingRect(ch); if (bounds.isEmpty()) { glyph = Glyph(0, QPoint(), QRect(), _metrics.width(ch)); return glyph; } // grow the bounds to account for effect, if any if (_effectType == SHADOW_EFFECT) { bounds.adjust(-_effectThickness, 0, 0, _effectThickness); } else if (_effectType == OUTLINE_EFFECT) { bounds.adjust(-_effectThickness, -_effectThickness, _effectThickness, _effectThickness); } // grow the bounds to account for antialiasing bounds.adjust(-1, -1, 1, 1); if (_x + bounds.width() > IMAGE_SIZE) { // we can't fit it on the current row; move to next _y += _rowHeight; _x = _rowHeight = 0; } if (_y + bounds.height() > IMAGE_SIZE) { // can't fit it on current texture; make a new one glGenTextures(1, &_currentTextureID); _x = _y = _rowHeight = 0; glBindTexture(GL_TEXTURE_2D, _currentTextureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, IMAGE_SIZE, IMAGE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); _allTextureIDs.append(_currentTextureID); } else { glBindTexture(GL_TEXTURE_2D, _currentTextureID); } // render the glyph into an image and copy it into the texture QImage image(bounds.width(), bounds.height(), QImage::Format_ARGB32); if (c == SOLID_BLOCK_CHAR) { image.fill(QColor(255, 255, 255)); } else { image.fill(0); QPainter painter(&image); painter.setFont(_font); if (_effectType == SHADOW_EFFECT) { for (int i = 0; i < _effectThickness; i++) { painter.drawText(-bounds.x() - 1 - i, -bounds.y() + 1 + i, ch); } } else if (_effectType == OUTLINE_EFFECT) { QPainterPath path; QFont font = _font; font.setStyleStrategy(QFont::ForceOutline); path.addText(-bounds.x() - 0.5, -bounds.y() + 0.5, font, ch); QPen pen; pen.setWidth(_effectThickness); pen.setJoinStyle(Qt::RoundJoin); pen.setCapStyle(Qt::RoundCap); painter.setPen(pen); painter.setRenderHint(QPainter::Antialiasing); painter.drawPath(path); } painter.setPen(QColor(255, 255, 255)); painter.drawText(-bounds.x(), -bounds.y(), ch); } glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y, bounds.width(), bounds.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); glyph = Glyph(_currentTextureID, QPoint(_x, _y), bounds, _metrics.width(ch)); _x += bounds.width(); _rowHeight = qMax(_rowHeight, bounds.height()); glBindTexture(GL_TEXTURE_2D, 0); return glyph; }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , m_ui(new Ui::MainWindow) , m_inst(0) , m_aspect(-1) , m_preview(0) , m_previewDock(0) , m_posBoxLock(false) , m_accelBoxLock(false) , m_pos(0) , m_setPosLock(false) { static_mainWindow = this; m_ui->setupUi(this); setWindowTitle("Teleprompter - DViz"); setWindowIcon(QIcon(":/data/icon-d.png")); connect(m_ui->actionOpen_Text_File, SIGNAL(triggered()), this, SLOT(slotOpen())); connect(m_ui->actionSave, SIGNAL(triggered()), this, SLOT(slotSave())); connect(m_ui->actionSave_As, SIGNAL(triggered()), this, SLOT(slotSaveAs())); connect(m_ui->actionSetup_Outputs, SIGNAL(triggered()), this, SLOT(slotOutputSetup())); connect(m_ui->actionExit, SIGNAL(triggered()), this, SLOT(slotExit())); m_ui->playBtn->setIcon(QIcon(":/data/action-play.png")); connect(m_ui->playBtn, SIGNAL(clicked()), this, SLOT(slotTogglePlay())); connect(m_ui->posBox, SIGNAL(valueChanged(int)), this, SLOT(slotPosBoxChanged(int))); connect(m_ui->accelBox, SIGNAL(valueChanged(int)), this, SLOT(slotAccelBoxChanged(int))); connect(m_ui->accelResetBtn, SIGNAL(clicked()), this, SLOT(slotResetAccel())); m_ui->accelResetBtn->setIcon(QIcon(":/data/stock-undo.png")); m_ui->accelResetBtn->setToolTip("Reset to Normal Speed (CTRL+SHIFT+Z)"); m_ui->accelResetBtn->setShortcut(QString(tr("CTRL+SHIFT+Z"))); connect(&m_animTimer, SIGNAL(timeout()), this, SLOT(animate())); m_animTimer.setInterval(ANIMATE_BASE_MS); m_editor = new RichTextEditorWidget(m_ui->mainWidget); QLayoutItem * firstItem = m_ui->mainWidget->layout()->takeAt(0); m_ui->mainWidget->layout()->addWidget(m_editor); m_ui->mainWidget->layout()->addItem(firstItem); connect(m_editor, SIGNAL(contentsChanged()), this, SLOT(slotTextChanged())); m_ui->actionSetup_Outputs->setIcon(QIcon(":data/stock-preferences.png")); QSettings s; bool flag = s.value("teleprompter/firstrun",true).toBool(); if(flag) { s.setValue("teleprompter/firstrun",false); slotOutputSetup(); } AppSettings::setGridEnabled(false); Output * output = AppSettings::outputs().first(); m_previewDock = new QDockWidget(QString(tr("%1 Preiew")).arg(output->name()), this); m_previewDock->setObjectName(output->name()); m_preview = new OutputViewer(0,m_previewDock); m_previewDock->setWidget(m_preview); addDockWidget(Qt::BottomDockWidgetArea, m_previewDock); m_group = new SlideGroup(); m_group->setGroupTitle("Group"); //AbstractItem::guessTitle(QFileInfo(fileName).baseName())); m_slide = new Slide(); m_textbox = new TextBoxItem(); m_textbox->setItemId(ItemFactory::nextId()); m_textbox->setItemName(QString("TextBoxItem%1").arg(m_textbox->itemId())); AbstractVisualItem * bg = dynamic_cast<AbstractVisualItem*>(m_slide->background()); // qDebug() << "Slide "<<slideNum<<": [\n"<<tmpList.join("\n")<<"\n]";; bg->setFillType(AbstractVisualItem::Solid); bg->setFillBrush(Qt::black); // Outline pen for the text QPen pen = QPen(Qt::black,1.5); pen.setJoinStyle(Qt::MiterJoin); m_textbox->setPos(QPointF(0,0)); m_textbox->setOutlinePen(pen); m_textbox->setOutlineEnabled(true); m_textbox->setFillBrush(Qt::white); m_textbox->setFillType(AbstractVisualItem::Solid); m_textbox->setShadowEnabled(false); // m_textbox->setShadowBrush(Qt::red); // m_textbox->setShadowBlurRadius(3); m_slide->addItem(m_textbox); m_slide->setSlideNumber(0); m_group->addSlide(m_slide); openOutput(); m_inst->setSlideGroup(m_group); openTextFile("test.txt"); }
void QSvgStrokeStyle::apply(QPainter *p, const QSvgNode *, QSvgExtraStates &states) { m_oldStroke = p->pen(); m_oldStrokeOpacity = states.strokeOpacity; m_oldStrokeDashOffset = states.strokeDashOffset; m_oldVectorEffect = states.vectorEffect; QPen pen = p->pen(); qreal oldWidth = pen.widthF(); qreal width = m_stroke.widthF(); if (oldWidth == 0) oldWidth = 1; if (width == 0) width = 1; qreal scale = oldWidth / width; if (m_strokeOpacitySet) states.strokeOpacity = m_strokeOpacity; if (m_vectorEffectSet) states.vectorEffect = m_vectorEffect; if (m_strokeSet) { if (m_style) pen.setBrush(m_style->brush(p, states)); else pen.setBrush(m_stroke.brush()); } if (m_strokeWidthSet) pen.setWidthF(m_stroke.widthF()); bool setDashOffsetNeeded = false; if (m_strokeDashOffsetSet) { states.strokeDashOffset = m_strokeDashOffset; setDashOffsetNeeded = true; } if (m_strokeDashArraySet) { if (m_stroke.style() == Qt::SolidLine) { pen.setStyle(Qt::SolidLine); } else if (m_strokeWidthSet || oldWidth == 1) { // If both width and dash array was set, the dash array is already scaled correctly. pen.setDashPattern(m_stroke.dashPattern()); setDashOffsetNeeded = true; } else { // If dash array was set, but not the width, the dash array has to be scaled with respect to the old width. QVector<qreal> dashes = m_stroke.dashPattern(); for (int i = 0; i < dashes.size(); ++i) dashes[i] /= oldWidth; pen.setDashPattern(dashes); setDashOffsetNeeded = true; } } else if (m_strokeWidthSet && pen.style() != Qt::SolidLine && scale != 1) { // If the width was set, but not the dash array, the old dash array must be scaled with respect to the new width. QVector<qreal> dashes = pen.dashPattern(); for (int i = 0; i < dashes.size(); ++i) dashes[i] *= scale; pen.setDashPattern(dashes); setDashOffsetNeeded = true; } if (m_strokeLineCapSet) pen.setCapStyle(m_stroke.capStyle()); if (m_strokeLineJoinSet) pen.setJoinStyle(m_stroke.joinStyle()); if (m_strokeMiterLimitSet) pen.setMiterLimit(m_stroke.miterLimit()); // You can have dash offset on solid strokes in SVG files, but not in Qt. // QPen::setDashOffset() will set the pen style to Qt::CustomDashLine, // so don't call the method if the pen is solid. if (setDashOffsetNeeded && pen.style() != Qt::SolidLine) { qreal currentWidth = pen.widthF(); if (currentWidth == 0) currentWidth = 1; pen.setDashOffset(states.strokeDashOffset / currentWidth); } pen.setCosmetic(states.vectorEffect); p->setPen(pen); }
void Airspace::drawFlarmAlertZone( QPainter* targetP, qreal opacity ) { if( ! GeneralConfig::instance()->getItemDrawingEnabled(typeID) || ! glConfig->isBorder(typeID) || ! isVisible() ) { return; } if( m_flarmAlertZone.isValid() == false || m_flarmAlertZone.isActive() == false ) { return; } // Map radius to map scale int scaledRadius = (int) rint( double(m_flarmAlertZone.Radius) / glMapMatrix->getScale() ); // project center point to map QPoint pcp = glMapMatrix->wgsToMap( m_flarmAlertZone.Latitude, m_flarmAlertZone.Longitude ); // map projected center point to map display QPoint mcp = glMapMatrix->map( pcp ); QBrush drawB( glConfig->getDrawBrush(typeID) ); if( opacity <= 100.0 ) { // use solid filled air regions drawB.setStyle( Qt::SolidPattern ); } QPen drawP = glConfig->getDrawPen(typeID); drawP.setJoinStyle(Qt::RoundJoin); int lw = GeneralConfig::instance()->getAirspaceLineWidth(); if( lw > 1 && glConfig->useSmallIcons() ) { lw = (lw + 1) / 2; } drawP.setWidth(lw); targetP->setPen(drawP); targetP->setBrush(drawB); if( opacity <= 100.0 && opacity > 0.0 ) { // Draw airspace filled with opacity factor targetP->setOpacity( opacity/100.0 ); targetP->drawEllipse( mcp.x() - scaledRadius, mcp.y() - scaledRadius, scaledRadius * 2, scaledRadius * 2 ); // Reset opacity, that a solid line is drawn as next targetP->setBrush(Qt::NoBrush); targetP->setOpacity( 1.0 ); } else if( opacity == 0.0 ) { // Draw only the alert zone borders without any filling inside targetP->setBrush(Qt::NoBrush); targetP->setOpacity( 1.0 ); } // Draw the outline of the alert zone with the selected brush targetP->drawEllipse( mcp.x() - scaledRadius, mcp.y() - scaledRadius, scaledRadius * 2, scaledRadius * 2 ); }
void MythPainter::DrawTextPriv(MythImage *im, const QString &msg, int flags, const QRect &r, const MythFontProperties &font) { if (!im) return; QColor outlineColor; int outlineSize = 0; int outlineAlpha; if (font.hasOutline()) font.GetOutline(outlineColor, outlineSize, outlineAlpha); QPoint shadowOffset(0, 0); QColor shadowColor; int shadowAlpha; if (font.hasShadow()) font.GetShadow(shadowOffset, shadowColor, shadowAlpha); QFontMetrics fm(font.face()); int totalHeight = fm.height() + outlineSize + std::max(outlineSize, std::abs(shadowOffset.y())); // initialPaddingX is the number of pixels from the left of the // input QRect to the left of the actual text. It is always 0 // because we don't add padding to the text rectangle. int initialPaddingX = 0; // initialPaddingY is the number of pixels from the top of the // input QRect to the top of the actual text. It may be nonzero // because of extra vertical padding. int initialPaddingY = (r.height() - totalHeight) / 2; // Hack. Normally we vertically center the text due to some // (solvable) issues in the SubtitleScreen code - the text rect // and the background rect are both created with PAD_WIDTH extra // padding, and to honor Qt::AlignTop, the text rect needs to be // without padding. This doesn't work for Qt::TextWordWrap, since // the first line will be vertically centered with subsequence // lines below. So if Qt::TextWordWrap is set, we do top // alignment. if (flags & Qt::TextWordWrap) initialPaddingY = 0; // textOffsetX is the number of pixels from r.left() to the left // edge of the core text. This assumes that flags contains // Qt::AlignLeft. int textOffsetX = initialPaddingX + std::max(outlineSize, -shadowOffset.x()); // textOffsetY is the number of pixels from r.top() to the top // edge of the core text. This assumes that flags contains // Qt::AlignTop. int textOffsetY = initialPaddingY + std::max(outlineSize, -shadowOffset.y()); QImage pm(r.size(), QImage::Format_ARGB32); QColor fillcolor = font.color(); if (font.hasOutline()) fillcolor = outlineColor; fillcolor.setAlpha(0); pm.fill(fillcolor.rgba()); QPainter tmp(&pm); QFont tmpfont = font.face(); tmpfont.setStyleStrategy(QFont::OpenGLCompatible); tmp.setFont(tmpfont); QPainterPath path; if (font.hasOutline()) path.addText(0, 0, tmpfont, msg); if (font.hasShadow()) { QRect a = QRect(0, 0, r.width(), r.height()); a.translate(shadowOffset.x() + textOffsetX, shadowOffset.y() + textOffsetY); shadowColor.setAlpha(shadowAlpha); tmp.setPen(shadowColor); tmp.drawText(a, flags, msg); } if (font.hasOutline()) { // QPainter::drawText() treats the Y coordinate as the top of // the text (when Qt::AlignTop is used). However, // QPainterPath::addText() treats the Y coordinate as the base // line of the text. To translate from the top to the base // line, we need to add QFontMetrics::ascent(). int adjX = 0; int adjY = fm.ascent(); outlineColor.setAlpha(outlineAlpha); tmp.setPen(outlineColor); path.translate(adjX + textOffsetX, adjY + textOffsetY); QPen pen = tmp.pen(); pen.setWidth(outlineSize * 2 + 1); pen.setCapStyle(Qt::RoundCap); pen.setJoinStyle(Qt::RoundJoin); tmp.setPen(pen); tmp.drawPath(path); path.translate(outlineSize, outlineSize); } tmp.setPen(QPen(font.GetBrush(), 0)); tmp.setBrush(font.GetBrush()); tmp.drawText(textOffsetX, textOffsetY, r.width(), r.height(), flags, msg); tmp.end(); im->Assign(pm); }
void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QPen& pen, QPen& selPen, double& offset ) { if ( mDataDefinedProperties.isEmpty() ) return; // shortcut //data defined properties QgsExpression* strokeWidthExpression = expression( "width" ); if ( strokeWidthExpression ) { double scaledWidth = strokeWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale ); pen.setWidthF( scaledWidth ); selPen.setWidthF( scaledWidth ); } //color QgsExpression* strokeColorExpression = expression( "color" ); if ( strokeColorExpression ) { pen.setColor( QgsSymbolLayerV2Utils::decodeColor( strokeColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ) ); } //offset QgsExpression* lineOffsetExpression = expression( "offset" ); if ( lineOffsetExpression ) { offset = lineOffsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble(); } //dash dot vector QgsExpression* dashPatternExpression = expression( "customdash" ); if ( dashPatternExpression ) { double scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale ); double dashWidthDiv = mPen.widthF(); if ( strokeWidthExpression ) { dashWidthDiv = pen.widthF(); scaledWidth = pen.widthF(); } //fix dash pattern width in Qt 4.8 QStringList versionSplit = QString( qVersion() ).split( "." ); if ( versionSplit.size() > 1 && versionSplit.at( 1 ).toInt() >= 8 && ( scaledWidth * context.renderContext().rasterScaleFactor() ) < 1.0 ) { dashWidthDiv = 1.0; } QVector<qreal> dashVector; QStringList dashList = dashPatternExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString().split( ";" ); QStringList::const_iterator dashIt = dashList.constBegin(); for ( ; dashIt != dashList.constEnd(); ++dashIt ) { dashVector.push_back( dashIt->toDouble() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv ); } pen.setDashPattern( dashVector ); } //join style QgsExpression* joinStyleExpression = expression( "joinstyle" ); if ( joinStyleExpression ) { QString joinStyleString = joinStyleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); pen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( joinStyleString ) ); } //cap style QgsExpression* capStyleExpression = expression( "capstyle" ); if ( capStyleExpression ) { QString capStyleString = capStyleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); pen.setCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( capStyleString ) ); } }
void Plotter::drawGrid(QPainter *painter) { //qDebug() << "Inside DrawGrid"; QRect rect(Margin,Margin,width()-2*Margin,height()-2*Margin); if(!rect.isValid()) return; QPen pen; QColor objColor(55,55,55,255); pen.setBrush(Qt::darkGray); pen.setStyle(Qt::DotLine); pen.setColor(objColor); pen.setCapStyle(Qt::RoundCap); pen.setJoinStyle(Qt::RoundJoin); painter->setPen(pen); //QPoint *pixPoint = new QPoint(); PlotSettings settings = zoomStack[curZoom]; if(m_bGrid) { for(int i=0;i<settings.numXTicks;i++) { int x = rect.left() + (i * (rect.width()) / settings.numXTicks); double label = settings.minX + (i*settings.spanX()/settings.numXTicks); //printf("X Axis:%f\n",label); for(float l_nPoint=1;l_nPoint<rect.height();l_nPoint+=2.0) painter->drawPoint(QPointF(x,rect.top()+l_nPoint)); painter->drawLine(x,rect.bottom(),x,rect.bottom()+5); painter->drawText(x-50,rect.bottom()+5,100,20, Qt::AlignHCenter|Qt::AlignTop,QString::number(label,5,2)); } for(int j=0;j<settings.numYTicks;j++) { int y = rect.bottom() - (j * (rect.height()) / settings.numYTicks); double label = settings.minY + (j*settings.spanY()/settings.numYTicks); //printf("Y Axis:%f\n",label); for(float l_nPoint=0;l_nPoint<rect.width();l_nPoint+=2.0) painter->drawPoint(QPointF(rect.left()+l_nPoint,y)); painter->drawLine(rect.left(),y,rect.right(),y); painter->drawText(rect.left()-Margin,y-10,Margin-5, 20,Qt::AlignRight|Qt::AlignVCenter,QString::number(label,5,2)); } pen.setStyle(Qt::SolidLine); painter->setPen(pen); //int Value =0; for(int i=0;i<rect.height();i+=((rect.height()/settings.numYTicks)/5)) { if(i!=0 && i%5!=0){ //painter->drawLine(Margin+rect.width()/2-3,Margin+i,Margin+rect.width()/2+3,Margin+i); } } for(int j=0;j<rect.width();j+=(rect.width()/settings.numXTicks)/5 ) { if(j!=0 && j%5!=0){ // painter->drawLine(Margin+j,Margin+rect.height()/2-3,Margin+j,Margin+rect.height()/2+3); } } } if(m_bGrid == false){ pen.setStyle(Qt::SolidLine); pen.setBrush(Qt::darkGray); pen.setColor(objColor); pen.setWidth(1); painter->setPen(pen); if(zoomScreenFlag==true){ /*vertical line*/ painter->drawLine(Margin+rect.width()/2-1,Margin,Margin+rect.width()/2-1,Margin+rect.height()); /*horizontal line*/ painter->drawLine(Margin,Margin+rect.height()/2-1,Margin+rect.width(),Margin+rect.height()/2-1); } else if(zoomScreenFlag==false){ /*vertical line*/ painter->drawLine(Margin+rect.width()/2-1,Margin,Margin+rect.width()/2-1,Margin+rect.height()); /*horizontal line*/ painter->drawLine(Margin,Margin+rect.height()/2-1,Margin+rect.width(),Margin+rect.height()/2-1); } for(int i=0;i<rect.height();i+=((rect.height()/settings.numYTicks)/2)) { if(i!=0 && i%2!=0) { if(zoomScreenFlag==true){ //painter->drawLine((Margin+rect.width()/2-3)-1,Margin+i,(Margin+rect.width()/2+3)-1,Margin+i); } } } for(int j=0;j<rect.width();j=j+(rect.width()/settings.numXTicks)+5 ) { if(j!=0) { //painter->drawLine(Margin+j-5,Margin+rect.height()/2-3,Margin+j-5,Margin+rect.height()/2+3); } } } if(m_bVILabels == true) { pen.setWidth(2); pen.setBrush(Qt::gray); painter->setPen(pen); //qDebug() << "XLabel" << m_strXLabel << "YLabel" << m_strYLabel; // painter->drawText(Margin+rect.width()/2+8,3,65,45,Qt::AlignLeft|Qt::AlignTop,m_strY1Label); // painter->drawText(4,Margin+rect.height()/2+2,35,45,Qt::AlignLeft|Qt::AlignTop,m_strX1Label); // painter->drawText(Margin+rect.width()-35,Margin+rect.height()/2,35,45,Qt::AlignHCenter|Qt::AlignTop,m_strX2Label); // painter->drawText(Margin+rect.width()/2+8,Margin+rect.height()-20,65,45,Qt::AlignLeft|Qt::AlignTop,m_strY2Label); painter->drawText(Margin+rect.width()/2+8,8,65,45,Qt::AlignLeft|Qt::AlignTop,"+"+m_strY1Label); painter->drawText(15,Margin+rect.height()/2+2,35,45,Qt::AlignLeft|Qt::AlignTop,"+"+m_strX1Label); painter->drawText(Margin+rect.width()-45,Margin+rect.height()/2,35,45,Qt::AlignHCenter|Qt::AlignTop,m_strX2Label); painter->drawText(Margin+rect.width()/2+8,Margin+rect.height()-25,65,45,Qt::AlignLeft|Qt::AlignTop,m_strY2Label); } //painter->drawRect(rect.adjusted(+0,+0,-1,-1)); // qDebug() << "outSide DrawGrid"; //painter->drawRect(rect.adjusted(+0,+0,-1,-1)); }
void PlayableCover::paintEvent( QPaintEvent* event ) { Q_UNUSED( event ); QPainter painter( this ); painter.setRenderHint( QPainter::Antialiasing ); painter.drawPixmap( 0, 0, pixmap() ); if ( !m_showText ) return; QRect r = contentsRect().adjusted( margin(), margin(), -margin(), -margin() ); QPixmap buffer( r.size() ); buffer.fill( Qt::transparent ); QPainter bufpainter( &buffer ); bufpainter.setRenderHint( QPainter::Antialiasing ); QTextOption to; to.setWrapMode( QTextOption::NoWrap ); QColor c1; c1.setRgb( 0, 0, 0 ); c1.setAlphaF( 0.00 ); QColor c2; c2.setRgb( 0, 0, 0 ); c2.setAlphaF( 0.88 ); QString text; QFont font = QLabel::font(); font.setPointSize( TomahawkUtils::defaultFontSize() ); QFont boldFont = font; boldFont.setBold( true ); boldFont.setPointSize( TomahawkUtils::defaultFontSize() + 5 ); QString top, bottom; if ( m_artist ) { top = m_artist->name(); } else if ( m_album ) { top = m_album->name(); bottom = m_album->artist()->name(); } else if ( m_query ) { top = m_query->queryTrack()->track(); bottom = m_query->queryTrack()->artist(); } int bottomHeight = QFontMetrics( font ).boundingRect( bottom ).height(); int topHeight = QFontMetrics( boldFont ).boundingRect( top ).height(); int frameHeight = bottomHeight + topHeight + 4; QRect gradientRect = r.adjusted( 0, r.height() - frameHeight * 3, 0, 0 ); QLinearGradient gradient( QPointF( 0, 0 ), QPointF( 0, 1 ) ); gradient.setCoordinateMode( QGradient::ObjectBoundingMode ); gradient.setColorAt( 0.0, c1 ); gradient.setColorAt( 0.6, c2 ); gradient.setColorAt( 1.0, c2 ); bufpainter.save(); bufpainter.setPen( Qt::transparent ); bufpainter.setBrush( gradient ); bufpainter.drawRect( gradientRect ); bufpainter.restore(); bufpainter.setPen( Qt::white ); QRect textRect = r.adjusted( 8, r.height() - frameHeight - 16, -8, -16 ); bool oneLiner = false; if ( bottom.isEmpty() ) oneLiner = true; bufpainter.setFont( boldFont ); if ( oneLiner ) { bufpainter.save(); QFont f = bufpainter.font(); while ( f.pointSizeF() > 9 && bufpainter.fontMetrics().width( top ) > textRect.width() ) { f.setPointSizeF( f.pointSizeF() - 0.2 ); bufpainter.setFont( f ); } to.setAlignment( Qt::AlignHCenter | Qt::AlignVCenter ); text = bufpainter.fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - 3 ); bufpainter.drawText( textRect, text, to ); bufpainter.restore(); } else { to.setAlignment( Qt::AlignHCenter | Qt::AlignTop ); text = bufpainter.fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - 3 ); bufpainter.drawText( textRect, text, to ); bufpainter.setFont( font ); QRect r = textRect; r.setTop( r.bottom() - bufpainter.fontMetrics().height() ); r.adjust( 4, 0, -4, -1 ); text = bufpainter.fontMetrics().elidedText( bottom, Qt::ElideRight, textRect.width() - 16 ); int textWidth = bufpainter.fontMetrics().width( text ); r.adjust( ( r.width() - textWidth ) / 2 - 6, 0, - ( ( r.width() - textWidth ) / 2 - 6 ), 0 ); m_itemRects.clear(); m_itemRects << r; if ( m_hoveredRect == r ) { TomahawkUtils::drawQueryBackground( &bufpainter, r ); bufpainter.setPen( TomahawkUtils::Colors::SELECTION_FOREGROUND ); } to.setAlignment( Qt::AlignHCenter | Qt::AlignBottom ); bufpainter.drawText( textRect.adjusted( 5, -1, -5, -1 ), text, to ); } { QBrush brush( buffer ); QPen pen; pen.setColor( Qt::transparent ); pen.setJoinStyle( Qt::RoundJoin ); float frameWidthPct = 0.20; painter.setBrush( brush ); painter.setPen( pen ); painter.drawRoundedRect( r, frameWidthPct * 100.0, frameWidthPct * 100.0, Qt::RelativeSize ); } }
static inline void qwtDrawStar2Symbols( QPainter *painter, const QPointF *points, int numPoints, const QwtSymbol &symbol ) { QPen pen = symbol.pen(); if ( pen.width() > 1 ) pen.setCapStyle( Qt::FlatCap ); pen.setJoinStyle( Qt::MiterJoin ); painter->setPen( pen ); painter->setBrush( symbol.brush() ); const double cos30 = 0.866025; // cos(30°) const double dy = 0.25 * symbol.size().height(); const double dx = 0.5 * symbol.size().width() * cos30 / 3.0; QPolygonF star( 12 ); QPointF *starPoints = star.data(); const bool doAlign = QwtPainter::roundingAlignment( painter ); for ( int i = 0; i < numPoints; i++ ) { double x = points[i].x(); double y = points[i].y(); if ( doAlign ) { x = qRound( x ); y = qRound( y ); } double x1 = x - 3 * dx; double y1 = y - 2 * dy; if ( doAlign ) { x1 = qRound( x - 3 * dx ); y1 = qRound( y - 2 * dy ); } const double x2 = x1 + 1 * dx; const double x3 = x1 + 2 * dx; const double x4 = x1 + 3 * dx; const double x5 = x1 + 4 * dx; const double x6 = x1 + 5 * dx; const double x7 = x1 + 6 * dx; const double y2 = y1 + 1 * dy; const double y3 = y1 + 2 * dy; const double y4 = y1 + 3 * dy; const double y5 = y1 + 4 * dy; starPoints[0].rx() = x4; starPoints[0].ry() = y1; starPoints[1].rx() = x5; starPoints[1].ry() = y2; starPoints[2].rx() = x7; starPoints[2].ry() = y2; starPoints[3].rx() = x6; starPoints[3].ry() = y3; starPoints[4].rx() = x7; starPoints[4].ry() = y4; starPoints[5].rx() = x5; starPoints[5].ry() = y4; starPoints[6].rx() = x4; starPoints[6].ry() = y5; starPoints[7].rx() = x3; starPoints[7].ry() = y4; starPoints[8].rx() = x1; starPoints[8].ry() = y4; starPoints[9].rx() = x2; starPoints[9].ry() = y3; starPoints[10].rx() = x1; starPoints[10].ry() = y2; starPoints[11].rx() = x3; starPoints[11].ry() = y2; QwtPainter::drawPolygon( painter, star ); } }
void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameIndex ) { if ( !p ) { return; } bool emptyTable = mTableContents.length() == 0; if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::HideTable ) { //empty table set to hide table mode, so don't draw anything return; } if ( mComposition->plotStyle() == QgsComposition::Print || mComposition->plotStyle() == QgsComposition::Postscript ) { //exporting composition, so force an attribute refresh //we do this in case vector layer has changed via an external source (eg, another database user) refreshAttributes(); } //calculate which rows to show in this frame QPair< int, int > rowsToShow = rowRange( frameIndex ); double gridSize = mShowGrid ? mGridStrokeWidth : 0; double cellHeaderHeight = QgsComposerUtils::fontAscentMM( mHeaderFont ) + 2 * mCellMargin; double cellBodyHeight = QgsComposerUtils::fontAscentMM( mContentFont ) + 2 * mCellMargin; QRectF cell; //calculate whether a header is required bool drawHeader = (( mHeaderMode == QgsComposerTableV2::FirstFrame && frameIndex < 1 ) || ( mHeaderMode == QgsComposerTableV2::AllFrames ) ); //calculate whether drawing table contents is required bool drawContents = !( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage ); int numberRowsToDraw = rowsToShow.second - rowsToShow.first; int numberEmptyRows = 0; if ( drawContents && mShowEmptyRows ) { numberRowsToDraw = rowsVisible( frameIndex, rowsToShow.first, true ); numberEmptyRows = numberRowsToDraw - rowsToShow.second + rowsToShow.first; } bool mergeCells = false; if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage ) { //draw a merged row for the empty table message numberRowsToDraw++; rowsToShow.second++; mergeCells = true; } p->save(); //antialiasing on p->setRenderHint( QPainter::Antialiasing, true ); //draw table background if ( mBackgroundColor.alpha() > 0 ) { p->save(); p->setPen( Qt::NoPen ); p->setBrush( QBrush( mBackgroundColor ) ); double totalHeight = ( drawHeader || ( numberRowsToDraw > 0 ) ? gridSize : 0 ) + ( drawHeader ? cellHeaderHeight + gridSize : 0.0 ); if ( drawContents ) { for ( int row = rowsToShow.first; row < rowsToShow.second; ++row ) { totalHeight += mMaxRowHeightMap[ row + 1 ] + 2 * mCellMargin + gridSize; } if ( numberEmptyRows > 0 ) { //draw empty rows totalHeight += ( cellBodyHeight + gridSize ) * numberEmptyRows; } } else { totalHeight += cellBodyHeight + gridSize; } if ( totalHeight > 0 ) { QRectF backgroundRect( 0, 0, mTableSize.width(), totalHeight ); p->drawRect( backgroundRect ); } p->restore(); } //now draw the text p->setPen( Qt::SolidLine ); double currentX = gridSize; double currentY = gridSize; if ( drawHeader ) { //draw the headers int col = 0; for ( QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin(); columnIt != mColumns.constEnd(); ++columnIt ) { currentX += mCellMargin; Qt::TextFlag textFlag = ( Qt::TextFlag )0; if (( *columnIt )->width() <= 0 ) { //automatic column width, so we use the Qt::TextDontClip flag when drawing contents, as this works nicer for italicised text //which may slightly exceed the calculated width //if column size was manually set then we do apply text clipping, to avoid painting text outside of columns width textFlag = Qt::TextDontClip; } cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellHeaderHeight ); //calculate alignment of header Qt::AlignmentFlag headerAlign = Qt::AlignLeft; switch ( mHeaderHAlignment ) { case FollowColumn: headerAlign = ( *columnIt )->hAlignment(); break; case HeaderLeft: headerAlign = Qt::AlignLeft; break; case HeaderCenter: headerAlign = Qt::AlignHCenter; break; case HeaderRight: headerAlign = Qt::AlignRight; break; } QgsComposerUtils::drawText( p, cell, ( *columnIt )->heading(), mHeaderFont, mHeaderFontColor, headerAlign, Qt::AlignVCenter, textFlag ); currentX += mMaxColumnWidthMap[ col ]; currentX += mCellMargin; currentX += gridSize; col++; } currentY += cellHeaderHeight; currentY += gridSize; } //now draw the body cells if ( drawContents ) { //draw the attribute values for ( int row = rowsToShow.first; row < rowsToShow.second; ++row ) { currentX = gridSize; int col = 0; //calculate row height double rowHeight = mMaxRowHeightMap[row + 1] + 2 * mCellMargin; for ( QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin(); columnIt != mColumns.constEnd(); ++columnIt ) { // currentY = gridSize; currentX += mCellMargin; QVariant cellContents = mTableContents.at( row ).at( col ); QString str = cellContents.toString(); Qt::TextFlag textFlag = ( Qt::TextFlag )0; if (( *columnIt )->width() <= 0 && mWrapBehaviour == TruncateText ) { //automatic column width, so we use the Qt::TextDontClip flag when drawing contents, as this works nicer for italicised text //which may slightly exceed the calculated width //if column size was manually set then we do apply text clipping, to avoid painting text outside of columns width textFlag = Qt::TextDontClip; } else if ( textRequiresWrapping( str, ( *columnIt )->width(), mContentFont ) ) { str = wrappedText( str, ( *columnIt )->width(), mContentFont ); } cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], rowHeight ); QgsComposerUtils::drawText( p, cell, str, mContentFont, mContentFontColor, ( *columnIt )->hAlignment(), ( *columnIt )->vAlignment(), textFlag ); currentX += mMaxColumnWidthMap[ col ]; currentX += mCellMargin; currentX += gridSize; col++; } currentY += rowHeight; currentY += gridSize; } } //and the borders if ( mShowGrid ) { QPen gridPen; gridPen.setWidthF( mGridStrokeWidth ); gridPen.setColor( mGridColor ); gridPen.setJoinStyle( Qt::MiterJoin ); p->setPen( gridPen ); drawHorizontalGridLines( p, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader ); drawVerticalGridLines( p, mMaxColumnWidthMap, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader, mergeCells ); } //special case - no records and table is set to ShowMessage mode if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage ) { double messageX = gridSize + mCellMargin; double messageY = gridSize + ( drawHeader ? cellHeaderHeight + gridSize : 0 ); cell = QRectF( messageX, messageY, mTableSize.width() - messageX, cellBodyHeight ); QgsComposerUtils::drawText( p, cell, mEmptyTableMessage, mContentFont, mContentFontColor, Qt::AlignHCenter, Qt::AlignVCenter, ( Qt::TextFlag )0 ); } p->restore(); }
static inline void qwtDrawTriangleSymbols( QPainter *painter, QwtTriangle::Type type, const QPointF *points, int numPoints, const QwtSymbol &symbol ) { const QSize size = symbol.size(); QPen pen = symbol.pen(); pen.setJoinStyle( Qt::MiterJoin ); painter->setPen( pen ); painter->setBrush( symbol.brush() ); const bool doAlign = QwtPainter::roundingAlignment( painter ); double sw2 = 0.5 * size.width(); double sh2 = 0.5 * size.height(); if ( doAlign ) { sw2 = qFloor( sw2 ); sh2 = qFloor( sh2 ); } QPolygonF triangle( 3 ); QPointF *trianglePoints = triangle.data(); for ( int i = 0; i < numPoints; i++ ) { const QPointF &pos = points[i]; double x = pos.x(); double y = pos.y(); if ( doAlign ) { x = qRound( x ); y = qRound( y ); } const double x1 = x - sw2; const double x2 = x1 + size.width(); const double y1 = y - sh2; const double y2 = y1 + size.height(); switch ( type ) { case QwtTriangle::Left: { trianglePoints[0].rx() = x2; trianglePoints[0].ry() = y1; trianglePoints[1].rx() = x1; trianglePoints[1].ry() = y; trianglePoints[2].rx() = x2; trianglePoints[2].ry() = y2; break; } case QwtTriangle::Right: { trianglePoints[0].rx() = x1; trianglePoints[0].ry() = y1; trianglePoints[1].rx() = x2; trianglePoints[1].ry() = y; trianglePoints[2].rx() = x1; trianglePoints[2].ry() = y2; break; } case QwtTriangle::Up: { trianglePoints[0].rx() = x1; trianglePoints[0].ry() = y2; trianglePoints[1].rx() = x; trianglePoints[1].ry() = y1; trianglePoints[2].rx() = x2; trianglePoints[2].ry() = y2; break; } case QwtTriangle::Down: { trianglePoints[0].rx() = x1; trianglePoints[0].ry() = y1; trianglePoints[1].rx() = x; trianglePoints[1].ry() = y2; trianglePoints[2].rx() = x2; trianglePoints[2].ry() = y1; break; } } QwtPainter::drawPolygon( painter, triangle ); } }
void Lib_dialog::draw (){ QPainter painter; painter.begin(ui->widget); if (fx.getCount()==0 && fx.getinicialize()) {painter.end(); return;} painter.setRenderHint(QPainter::Antialiasing); QPen pen; pen.setStyle(Qt::SolidLine); //��� ����� �� ����������� pen.setWidth(1);//������� ����� pen.setBrush(Qt::green); //���� pen.setCapStyle(Qt::RoundCap); //������������ � ����� pen.setJoinStyle(Qt::RoundJoin); //������ ���� painter.setPen(pen); //QColor currentColor (); QRect geom; geom=ui->widget->geometry(); int hght=geom.height(); int wdth=geom.width(); float minx=fx.getMinX(); float miny=fx.getMinY(); float maxx=fx.getMaxX(); float maxy=fx.getMaxY(); float wd=maxx-minx; float hd=maxy-miny; StructXY grid; if (fx.getGrid(&grid)) { float dfs=round(minx/grid.x)*grid.x; do { float n=(dfs-minx)/wd; int x1=n*wdth; QLine ln (x1,0,x1,hght); dfs+=grid.x; painter.drawLine (ln);} while (dfs<maxx+grid.x); dfs=round(miny/grid.y)*grid.y; do { float n=(dfs-miny)/hd; int y1=n*hght; QLine ln (0,y1,wdth,y1); dfs+=grid.y; painter.drawLine (ln);} while (dfs<maxy+grid.y); } pen.setBrush(Qt::black); painter.setPen(pen); float n=(fx[0].x-minx)/wd; int x1=n*wdth; n=(fx[0].y-miny)/hd; int y1=hght-n*hght; int i; { QPainterPath path; path.addEllipse(x1-4,y1-4,8,8); painter.fillPath(path, Qt::red); int x2,y2; int i; for (i=1; i<fx.getCount(); i++){ n=(fx[i].x-minx)/wd; x1=n*wdth; n=(fx[i-1].x-minx)/wd; x2=n*wdth; n=(fx[i].y-miny)/hd; y1=hght-n*hght; n=(fx[i-1].y-miny)/hd; y2=hght-n*hght; path.addEllipse(x1-4,y1-4,8,8); painter.fillPath(path, Qt::red); QLine ln ( x1,y1,x2,y2); painter.drawLine (ln); }} QPainterPath path; if (fx.getCurPoint(&i)) { n=(fx[i].x-minx)/wd; int x=n*wdth; n=(fx[i].y-miny)/hd; int y=hght-n*hght; path.addEllipse(x-5,y-5,10,10); painter.fillPath(path, Qt::blue); } painter.end(); }
void GraphicsItemNode::paint(QPainter * painter, const QStyleOptionGraphicsItem *, QWidget *) { QPainterPath outlinePath = shape(); //Fill the node's colour QBrush brush(m_colour); painter->fillPath(outlinePath, brush); //If the node contains a BLAST hit, draw that on top. if (g_settings->nodeColourScheme == BLAST_HITS_COLOUR) { std::vector<BlastHitPart> parts; if (g_settings->doubleMode) { if (m_deBruijnNode->thisNodeHasBlastHits()) parts = m_deBruijnNode->getBlastHitPartsForThisNode(); } else { if (m_deBruijnNode->thisNodeOrReverseComplementHasBlastHits()) parts = m_deBruijnNode->getBlastHitPartsForThisNodeOrReverseComplement(); } if (parts.size() > 0) { QPen partPen; partPen.setWidthF(m_width); partPen.setCapStyle(Qt::FlatCap); partPen.setJoinStyle(Qt::BevelJoin); for (size_t i = 0; i < parts.size(); ++i) { partPen.setColor(parts[i].m_colour); painter->setPen(partPen); painter->drawPath(makePartialPath(parts[i].m_nodeFractionStart, parts[i].m_nodeFractionEnd)); } } } //Draw the node outline QColor outlineColour = g_settings->outlineColour; double outlineThickness = g_settings->outlineThickness; if (isSelected()) { outlineColour = g_settings->selectionColour; outlineThickness = g_settings->selectionThickness; } if (outlineThickness > 0.0) { outlinePath = outlinePath.simplified(); QPen outlinePen(QBrush(outlineColour), outlineThickness, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin); painter->setPen(outlinePen); painter->drawPath(outlinePath); } //Draw text if there is any to display. if (g_settings->anyNodeDisplayText()) { //The text should always be displayed upright, so //counter the view's rotation here. painter->setRenderHint(QPainter::TextAntialiasing, true); painter->setFont(g_settings->labelFont); QString displayText = getNodeText(); QSize textSize = getNodeTextSize(displayText); double textWidth = textSize.width(); double textHeight = textSize.height(); //The text outline is made by drawing the text first in white at a slight offset //at many angles. The larger the text outline, the more angles are needed to //make the outline look nice. if (g_settings->textOutline) { int offsetSteps = 8; if (g_settings->textOutlineThickness > 0.5) offsetSteps = 16; if (g_settings->textOutlineThickness > 1.0) offsetSteps = 32; double offsetDistance = g_settings->textOutlineThickness; painter->translate(getCentre()); painter->rotate(-g_graphicsView->m_rotation); for (int i = 0; i < offsetSteps; ++i) { double offsetAngle = 6.2832 * (double(i) / offsetSteps); double xOffset = offsetDistance * cos(offsetAngle); double yOffset = offsetDistance * sin(offsetAngle); QRectF shadowTextRectangle(-textWidth / 2.0 + xOffset, -textHeight / 2.0 + yOffset, textWidth, textHeight); painter->setPen(Qt::white); painter->drawText(shadowTextRectangle, Qt::AlignCenter, displayText); } painter->rotate(g_graphicsView->m_rotation); painter->translate(-1.0 * getCentre()); } QRectF textRectangle(-textWidth / 2.0, -textHeight / 2.0, textWidth, textHeight); painter->setPen(g_settings->textColour); painter->translate(getCentre()); painter->rotate(-g_graphicsView->m_rotation); painter->drawText(textRectangle, Qt::AlignCenter, displayText); painter->rotate(g_graphicsView->m_rotation); painter->translate(-1.0 * getCentre()); } }
// This takes a very naive approach to producing at 'C' in a contrasting // color. For a much more effective technique, see: // http://qt.nokia.com/doc/qq/qq26-adaptivecoloring.html QPixmap colorSwatch(const QColor &color, const QSize &size) { QString key = QString("COLORSWATCH:%1:%2x%3").arg(color.name()) .arg(size.width()).arg(size.height()); QPixmap pixmap(size); #if QT_VERSION >= 0x040600 if (!QPixmapCache::find(key, &pixmap)) { #else if (!QPixmapCache::find(key, pixmap)) { #endif pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.setRenderHints(QPainter::Antialiasing| QPainter::TextAntialiasing); painter.setPen(Qt::NoPen); painter.setBrush(color); painter.drawEllipse(0, 0, size.width(), size.height()); if (size.width() > 32) { painter.setFont(QFont("Helvetica", qMax(8, size.height() - 6), QFont::Black)); QColor textColor(color.darker()); if (color.red() == color.green() && color.red() == color.blue()) textColor = (color.red() > 90 ? Qt::black : Qt::white); painter.setPen(textColor); painter.drawText( QRectF(0, 0, size.width(), size.height()), QObject::tr("C"), QTextOption(Qt::AlignCenter)); } painter.end(); QPixmapCache::insert(key, pixmap); } return pixmap; } QPixmap brushSwatch(const Qt::BrushStyle style, const QColor &color, const QSize &size) { QString key = QString("BRUSHSTYLESWATCH:%1:%2:%3x%4") .arg(static_cast<int>(style)).arg(color.name()) .arg(size.width()).arg(size.height()); QPixmap pixmap(size); #if QT_VERSION >= 0x040600 if (!QPixmapCache::find(key, &pixmap)) { #else if (!QPixmapCache::find(key, pixmap)) { #endif pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::NoPen); painter.setBrush(QBrush(color, style)); painter.drawRect(0, 0, size.width(), size.height()); painter.end(); QPixmapCache::insert(key, pixmap); } return pixmap; } QPixmap penStyleSwatch(const Qt::PenStyle style, const QColor &color, const QSize &size) { QString key = QString("PENSTYLESWATCH:%1:%2:%3x%4") .arg(static_cast<int>(style)).arg(color.name()) .arg(size.width()).arg(size.height()); QPixmap pixmap(size); #if QT_VERSION >= 0x040600 if (!QPixmapCache::find(key, &pixmap)) { #else if (!QPixmapCache::find(key, pixmap)) { #endif pixmap.fill(Qt::transparent); QPainter painter(&pixmap); QPen pen(style); pen.setColor(color); pen.setWidth(2); painter.setPen(pen); const int Y = size.height() / 2; painter.drawLine(0, Y, size.width(), Y); painter.end(); QPixmapCache::insert(key, pixmap); } return pixmap; } QPixmap penCapSwatch(const Qt::PenCapStyle capStyle, const QColor &color, const QSize &size) { QString key = QString("PENCAPSTYLESWATCH:%1:%2:%3x%4") .arg(static_cast<int>(capStyle)).arg(color.name()) .arg(size.width()).arg(size.height()); QPixmap pixmap(size); #if QT_VERSION >= 0x040600 if (!QPixmapCache::find(key, &pixmap)) { #else if (!QPixmapCache::find(key, pixmap)) { #endif pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing); QPen pen; pen.setCapStyle(Qt::SquareCap); pen.setWidthF(size.height() / 2.5); pen.setColor(Qt::white); painter.setPen(pen); const int Y = size.height() / 2; painter.drawLine(0, Y, size.width(), Y); pen.setColor(color); pen.setCapStyle(capStyle); painter.setPen(pen); painter.drawLine(size.width() / 2.5, Y, size.width(), Y); painter.end(); QPixmapCache::insert(key, pixmap); } return pixmap; } QPixmap penJoinSwatch(const Qt::PenJoinStyle joinStyle, const QColor &color, const QSize &size) { QString key = QString("PENJOINSTYLESWATCH:%1:%2:%3x%4") .arg(static_cast<int>(joinStyle)).arg(color.name()) .arg(size.width()).arg(size.height()); QPixmap pixmap(size); #if QT_VERSION >= 0x040600 if (!QPixmapCache::find(key, &pixmap)) { #else if (!QPixmapCache::find(key, pixmap)) { #endif const double Indent = size.width() / 5.0; QPolygonF polygon; polygon << QPointF(Indent, Indent) << QPointF(Indent, size.height() - Indent) << QPointF(size.width() - Indent, size.height() - Indent); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); painter.setRenderHint(QPainter::Antialiasing); QPen pen; pen.setJoinStyle(joinStyle); pen.setColor(color); pen.setWidthF(size.height() / 2.5); painter.setPen(pen); painter.drawPolyline(polygon); painter.end(); QPixmapCache::insert(key, pixmap); } return pixmap; }
//------------------------------------------------------------------------- void QGuidoItemContainer::init() { mGuidoItem = new QGuidoGraphicsItem( this ); #if !linux // bug in Qt 4.4 with the linux cache mode mGuidoItem->setCacheMode( QGraphicsItem::DeviceCoordinateCache ); #endif #ifdef USES_GUIDO_AR mMidiRef = -1; mPlayerState = STOPPED; QLanguageItem::plug( new QPaletteItemDropper( PALETTE_GUIDO_ELEMENT , QList<int>() << PALETTE_GUIDO_ELEMENT , this , this ) ); #endif connect( mGuidoItem , SIGNAL(geometryHasChanged()), this, SLOT(guidoGeometryChanged()) ); mIsOptimalPageFillOn = DEFAULT_OPTIMAL_PAGE_FILL; mIsProportionalRenderingOn = DEFAULT_PROPORTIONAL_RENDERING; mGuidoItem->setResizePageToMusic( DEFAULT_RESIZE_PAGE ); setMinMaxScale(0,0); mHeadBar = new QTextPathItem( "" , true , TITLE_BAR_FONT_COLOR , TITLE_BAR_FONT , TITLE_BAR_FONT_PEN_WIDTH , this ); mHeadBar->setZValue( 1 ); mSelectionItem = new QGraphicsPathItem(this); mSelectionItem->setZValue(-1); setAcceptHoverEvents(true); connect( this , SIGNAL(descriptiveNameChanged()) , this, SLOT(descriptiveNameHasChanged()) ); // Set pens & brushes mPenBrushSwitcher.addFlag( SELECTION_FLAG_SELECTED , 2 , PenBrush(SELECTED_PEN , SELECTED_BRUSH ) ); mPenBrushSwitcher.addFlag( SELECTION_FLAG_HIGHLIGHTED , 1 , PenBrush(HIGHLIGHTED_PEN , HIGHLIGHTED_BRUSH ) ); mPenBrushSwitcher.addFlag( SELECTION_FLAG_IDLE , 0, PenBrush(STANDARD_PEN , STANDARD_BRUSH ) ); mPenBrushSwitcher.setFlag( SELECTION_FLAG_IDLE , true ); mPenBrushSwitcher.setSwitchedFlag(SELECTION_FLAG_IDLE, SELECTION_SWITCH_INVALID_CODE, PenBrush(INVALID_PEN, INVALID_STANDARD_BRUSH ) ); mPenBrushSwitcher.setSwitchedFlag(SELECTION_FLAG_HIGHLIGHTED, SELECTION_SWITCH_INVALID_CODE, PenBrush(INVALID_PEN, INVALID_HIGHLIGHTED_BRUSH ) ); mPenBrushSwitcher.setSwitchedFlag(SELECTION_FLAG_SELECTED, SELECTION_SWITCH_INVALID_CODE, PenBrush(INVALID_PEN, INVALID_BRUSH_SELECTED ) ); //Imported from QGuidoSPageItemContainer mNextPageTurner = new QPageTurnerItem( true, QPolygonF() , this ); mPreviousPageTurner = new QPageTurnerItem( false, QPolygonF() , this ); mNextPageTurner->setZValue(4); mPreviousPageTurner->setZValue(4); mPageLabelItem = new QTextPathItem( "" , true , Qt::black , QFont(FONT_FAMILY , FONT_SIZE) , 1 , this ); mPageLabelItem->setZValue(2); //Visibility controlled in updatePageItemsVisibility, only for non-storage items. mPageLabelItem->setVisible( false ); mNextPageTurner->setVisible(false); mPreviousPageTurner->setVisible(false); //Set pen QPen pen = QPen( Qt::black ); pen.setJoinStyle( Qt::RoundJoin ); pen.setWidth( ARROW_PEN_WIDTH ); mNextPageTurner->setBrush( SELECTED_BRUSH ); mPreviousPageTurner->setBrush( SELECTED_BRUSH ); mNextPageTurner->setPen( pen ); mPreviousPageTurner->setPen( pen ); mPageLabelItem->setPen( SELECTED_PEN ); mPageLabelItem->setBrush( SELECTED_BRUSH ); updatePageIndexLabel(); guidoUpdateGeometry( INVALID_RECT ); mResizeMode = RESIZE_NORMAL; mResizer = 0; }
/*! \internal Draws the line ending with the specified \a painter at the position \a pos. The direction of the line ending is controlled with \a dir. */ void QCPLineEnding::draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const { if (mStyle == esNone) return; QVector2D lengthVec(dir.normalized()); if (lengthVec.isNull()) lengthVec = QVector2D(1, 0); QVector2D widthVec(-lengthVec.y(), lengthVec.x()); lengthVec *= (float)(mLength*(mInverted ? -1 : 1)); widthVec *= (float)(mWidth*0.5*(mInverted ? -1 : 1)); QPen penBackup = painter->pen(); QBrush brushBackup = painter->brush(); QPen miterPen = penBackup; miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey QBrush brush(painter->pen().color(), Qt::SolidPattern); switch (mStyle) { case esNone: break; case esFlatArrow: { QPointF points[3] = {pos.toPointF(), (pos-lengthVec+widthVec).toPointF(), (pos-lengthVec-widthVec).toPointF() }; painter->setPen(miterPen); painter->setBrush(brush); painter->drawConvexPolygon(points, 3); painter->setBrush(brushBackup); painter->setPen(penBackup); break; } case esSpikeArrow: { QPointF points[4] = {pos.toPointF(), (pos-lengthVec+widthVec).toPointF(), (pos-lengthVec*0.8f).toPointF(), (pos-lengthVec-widthVec).toPointF() }; painter->setPen(miterPen); painter->setBrush(brush); painter->drawConvexPolygon(points, 4); painter->setBrush(brushBackup); painter->setPen(penBackup); break; } case esLineArrow: { QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), pos.toPointF(), (pos-lengthVec-widthVec).toPointF() }; painter->setPen(miterPen); painter->drawPolyline(points, 3); painter->setPen(penBackup); break; } case esDisc: { painter->setBrush(brush); painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); painter->setBrush(brushBackup); break; } case esSquare: { QVector2D widthVecPerp(-widthVec.y(), widthVec.x()); QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), (pos-widthVecPerp-widthVec).toPointF(), (pos+widthVecPerp-widthVec).toPointF(), (pos+widthVecPerp+widthVec).toPointF() }; painter->setPen(miterPen); painter->setBrush(brush); painter->drawConvexPolygon(points, 4); painter->setBrush(brushBackup); painter->setPen(penBackup); break; } case esDiamond: { QVector2D widthVecPerp(-widthVec.y(), widthVec.x()); QPointF points[4] = {(pos-widthVecPerp).toPointF(), (pos-widthVec).toPointF(), (pos+widthVecPerp).toPointF(), (pos+widthVec).toPointF() }; painter->setPen(miterPen); painter->setBrush(brush); painter->drawConvexPolygon(points, 4); painter->setBrush(brushBackup); painter->setPen(penBackup); break; } case esBar: { painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); break; } case esHalfBar: { painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); break; } case esSkewedBar: { if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) { // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line painter->drawLine((pos+widthVec+lengthVec*0.2f*(mInverted?-1:1)).toPointF(), (pos-widthVec-lengthVec*0.2f*(mInverted?-1:1)).toPointF()); } else { // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly painter->drawLine((pos+widthVec+lengthVec*0.2f*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), (pos-widthVec-lengthVec*0.2f*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); } break; } } }
//--------------------------------------------------------------------- // Calls to drawRect(), drawRoundedRect() and drawEllipse() are // forwarded here. <func> is the respective QPainter function and // may or may not be called. static void DrawGenericRect (QImage *image, int x, int y, int width, int height, void (*func) (QPainter * /*p*/, int /*x*/, int /*y*/, int /*width*/, int/*height*/), const kpColor &fcolor, int penWidth, kpColor bcolor, const kpColor &fStippleColor, bool isEllipseLike) { #if DEBUG_KP_PIXMAP_FX qCDebug(kpLogPixmapfx) << "kppixmapfx.cpp:DrawGenericRect(" << x << "," << y << "," << width << "," << height << ",func=" << func << ")" << " pen.color=" << (int *) fcolor.toQRgb () << " penWidth=" << penWidth << " bcolor=" << (int *) (bcolor.isValid () ? bcolor.toQRgb () : 0xabadcafe) << " isEllipseLike=" << isEllipseLike << endl; #endif if ( (width == 0) || (height == 0) ) return; Q_ASSERT (func); // Check foreground colour valid. // Background is allowed to be invalid (no fill). Q_ASSERT (fcolor.isValid ()); if (width == 1 || height == 1) { #if DEBUG_KP_PIXMAP_FX qCDebug(kpLogPixmapfx) << "\twidth=1 or height=1 - draw line"; #endif kpPixmapFX::drawLine (image, x, y, x + width - 1, y + height - 1, fcolor, 1/*force pen width to 1*/, fStippleColor); return; } // Outline is so big that fill won't be seen? if (penWidth * 2 >= width || penWidth * 2 >= height) { #if DEBUG_KP_PIXMAP_FX qCDebug(kpLogPixmapfx) << "\toutline dominates fill - fill with outline"; #endif // Fill with outline. // TODO: doesn't emulate non-Qt::SolidLine pens // TODO: Transition from this hack to normal drawing makes the // ellipse look like it moves 1 pixel to the right due to // Qt missing a pixel on the left of some sizes of ellipses. penWidth = 1; bcolor = fcolor; // Outline colour. } QPainter painter(image); ::QPainterSetPenWithStipple(&painter, fcolor, penWidth, fStippleColor, isEllipseLike); QPen pen = painter.pen(); pen.setJoinStyle(Qt::MiterJoin); // rectangle shall always have square corners painter.setPen(pen); if (bcolor.isValid ()) painter.setBrush (QBrush (bcolor.toQColor())); // HACK: seems to be needed if set_Pen_(Qt::color0) else fills with Qt::color0. else painter.setBrush (Qt::NoBrush); // Fight Qt behaviour of painting width = fill width + pen width // and height = fill height + pen height. Get rid of pen width. (*func) (&painter, x + penWidth / 2, y + penWidth / 2, width - penWidth, height - penWidth); }
void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QPen& pen, QPen& selPen, double& offset ) { //data defined properties double scaledWidth = 0; QgsExpression* strokeWidthExpression = expression( "width" ); if ( strokeWidthExpression ) { scaledWidth = strokeWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit ); pen.setWidthF( scaledWidth ); selPen.setWidthF( scaledWidth ); } else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) { scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit ); pen.setWidthF( scaledWidth ); selPen.setWidthF( scaledWidth ); } //color QgsExpression* strokeColorExpression = expression( "color" ); if ( strokeColorExpression ) { pen.setColor( QgsSymbolLayerV2Utils::decodeColor( strokeColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ) ); } //offset offset = mOffset; QgsExpression* lineOffsetExpression = expression( "offset" ); if ( lineOffsetExpression ) { offset = lineOffsetExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble(); } //dash dot vector QgsExpression* dashPatternExpression = expression( "customdash" ); if ( dashPatternExpression ) { QVector<qreal> dashVector; QStringList dashList = dashPatternExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString().split( ";" ); QStringList::const_iterator dashIt = dashList.constBegin(); for ( ; dashIt != dashList.constEnd(); ++dashIt ) { dashVector.push_back( dashIt->toDouble() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit ) / mPen.widthF() ); } pen.setDashPattern( dashVector ); } //join style QgsExpression* joinStyleExpression = expression( "joinstyle" ); if ( joinStyleExpression ) { QString joinStyleString = joinStyleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); pen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( joinStyleString ) ); } //cap style QgsExpression* capStyleExpression = expression( "capstyle" ); if ( capStyleExpression ) { QString capStyleString = capStyleExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString(); pen.setCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( capStyleString ) ); } }
void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); if (d->points.size() < 2) return ; // draw the bounding rect if the arrow is selected if (isSelected() /* && !m_hoverBegin && !m_hoverEnd */) { painter->save(); painter->setPen(Qt::blue); painter->drawRect(boundingRect()); painter->restore(); } if (d->points.isEmpty()) return ; // prepare pen and brush painter->save(); QPen pen; pen.setWidthF(lineWidth()) ; pen.setCapStyle(Qt::RoundCap) ; pen.setJoinStyle(Qt::RoundJoin) ; pen.setColor(getColor()) ; painter->setPen(pen) ; QPainterPath path ; // draw the line path.moveTo(d->points.first()) ; if (d->spline && splinePossible(d->points.size())) { for (int i = 1 ; i+2 < d->points.size() ; i += 3) path.cubicTo(d->points[i], d->points[i+1], d->points[i+2]); if (isSelected()) // Draw help lines { painter->save(); painter->setPen(Qt::gray) ; QPointF previous(d->points.first()) ; for (int i = 1 ; i+2 < d->points.size() ; i += 3) { painter->drawLine(previous, d->points[i]) ; painter->drawLine(d->points[i+1], d->points[i+2]); previous = d->points[i+2] ; } painter->restore(); } } else foreach(const QPointF p, d->points.mid(1)) path.lineTo(p) ; path.translate(-pos()); painter->drawPath(path) ; // draw arrow tips painter->setBrush(pen.color()); qreal tipScaling = relativeWidth(); if (MolScene *sc = qobject_cast<MolScene*>(scene())) tipScaling *= sc->settings()->arrowTipWidth()->get(); if ((UpperBackward | LowerBackward) & d->arrowType) painter->drawPath(generateArrowTip(d->points.last(), d->points[d->points.size()-2], pos(), UpperBackward & d->arrowType, LowerBackward & d->arrowType, tipScaling )); if ((UpperForward | LowerForward) & d->arrowType) painter->drawPath(generateArrowTip(d->points.first(), d->points[1], pos(), LowerForward & d->arrowType, UpperForward & d->arrowType, tipScaling )) ; painter->restore(); graphicsItem::paint(painter, option, widget); }
void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QPen& pen, QPen& selPen, double& offset ) { if ( !hasDataDefinedProperties() ) return; // shortcut //data defined properties bool hasStrokeWidthExpression = false; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH ) ) { context.setOriginalValueVariable( mWidth ); double scaledWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH, context, mWidth ).toDouble(), mWidthUnit, mWidthMapUnitScale ); pen.setWidthF( scaledWidth ); selPen.setWidthF( scaledWidth ); hasStrokeWidthExpression = true; } //color bool ok; if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_COLOR ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( pen.color() ) ); QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_COLOR, context, QVariant(), &ok ).toString(); if ( ok ) pen.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ); } //offset if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET ) ) { context.setOriginalValueVariable( mOffset ); offset = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET, context, offset ).toDouble(); } //dash dot vector if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_CUSTOMDASH ) ) { double scaledWidth = QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), mWidth, mWidthUnit, mWidthMapUnitScale ); double dashWidthDiv = mPen.widthF(); if ( hasStrokeWidthExpression ) { dashWidthDiv = pen.widthF(); scaledWidth = pen.widthF(); } //fix dash pattern width in Qt 4.8 QStringList versionSplit = QString( qVersion() ).split( '.' ); if ( versionSplit.size() > 1 && versionSplit.at( 1 ).toInt() >= 8 && ( scaledWidth * context.renderContext().rasterScaleFactor() ) < 1.0 ) { dashWidthDiv = 1.0; } QVector<qreal> dashVector; QStringList dashList = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_CUSTOMDASH, context, QVariant(), &ok ).toString().split( ';' ); if ( ok ) { QStringList::const_iterator dashIt = dashList.constBegin(); for ( ; dashIt != dashList.constEnd(); ++dashIt ) { dashVector.push_back( QgsSymbolLayerV2Utils::convertToPainterUnits( context.renderContext(), dashIt->toDouble(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv ); } pen.setDashPattern( dashVector ); } } //line style if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_LINE_STYLE ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenStyle( pen.style() ) ); QString lineStyleString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_LINE_STYLE, context, QVariant(), &ok ).toString(); if ( ok ) pen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( lineStyleString ) ); } //join style if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_JOINSTYLE ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenJoinStyle( pen.joinStyle() ) ); QString joinStyleString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_JOINSTYLE, context, QVariant(), &ok ).toString(); if ( ok ) pen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( joinStyleString ) ); } //cap style if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_CAPSTYLE ) ) { context.setOriginalValueVariable( QgsSymbolLayerV2Utils::encodePenCapStyle( pen.capStyle() ) ); QString capStyleString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_CAPSTYLE, context, QVariant(), &ok ).toString(); if ( ok ) pen.setCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( capStyleString ) ); } }
/** coloridx: 0 - yellow, 1 - red, 2 - green, 3 - blue, if < 0 - only position without bounding box is drawn */ void draw_bbox(QPainter &painter, const PartBBox &part_bbox, int coloridx, int pen_width) { if (coloridx >= 0) { painter.setPen(Qt::yellow); int marker_radius = 3; int part_axis_length = 10; painter.drawEllipse(QRect((int)(part_bbox.part_pos(0) - marker_radius), (int)(part_bbox.part_pos(1) - marker_radius), 2*marker_radius, 2*marker_radius)); boost_math::double_vector v(2); v = part_bbox.part_pos + part_axis_length * part_bbox.part_x_axis; painter.drawLine((int)part_bbox.part_pos(0), (int)part_bbox.part_pos(1), (int)v(0), (int)v(1)); painter.setPen(Qt::red); v = part_bbox.part_pos + part_axis_length * part_bbox.part_y_axis; painter.drawLine((int)part_bbox.part_pos(0), (int)part_bbox.part_pos(1), (int)v(0), (int)v(1)); painter.setPen(Qt::yellow); QPen pen; if (coloridx == 0) pen.setColor(Qt::yellow); else if (coloridx == 1) pen.setColor(Qt::red); else if (coloridx == 2) pen.setColor(Qt::green); else if (coloridx == 3) pen.setColor(Qt::blue); else pen.setColor(Qt::black); pen.setJoinStyle(Qt::RoundJoin); pen.setWidth(pen_width); painter.setPen(pen); QPolygonF polygon; get_part_polygon(part_bbox, polygon); painter.drawPolygon(polygon); } else { painter.setPen(Qt::yellow); if (coloridx == -1) painter.setPen(Qt::yellow); else if (coloridx == -2) painter.setPen(Qt::red); else if (coloridx == -3) painter.setPen(Qt::green); else painter.setPen(Qt::blue); int x = part_bbox.part_pos(0); int y = part_bbox.part_pos(1); painter.drawLine(x-1, y, x+1, y); painter.drawLine(x, y-1, x, y+1); } }
void Airspace::drawRegion( QPainter* targetP, qreal opacity ) { // qDebug("Airspace::drawRegion(): TypeId=%d, opacity=%f, Name=%s", // typeID, opacity, getInfoString().toLatin1().data() ); if( ! GeneralConfig::instance()->getItemDrawingEnabled(typeID) || ! glConfig->isBorder(typeID) || ! isVisible()) { return; } if( m_flarmAlertZone.isValid() ) { // A Flarm Alert zone has to be drawn. drawFlarmAlertZone( targetP, opacity ); return; } QPolygon mP = glMapMatrix->map(projPolygon); if( mP.size() < 3 ) { return; } QPainterPath pp; pp.moveTo( mP.at(0) ); for( int i = 1; i < mP.size(); i++ ) { pp.lineTo( mP.at(i) ); } pp.closeSubpath(); QBrush drawB( glConfig->getDrawBrush(typeID) ); if( opacity <= 100.0 ) { // use solid filled air regions drawB.setStyle( Qt::SolidPattern ); } QPen drawP = glConfig->getDrawPen(typeID); drawP.setJoinStyle(Qt::RoundJoin); int lw = GeneralConfig::instance()->getAirspaceLineWidth(); extern MapConfig* _globalMapConfig; if( lw > 1 && _globalMapConfig->useSmallIcons() ) { lw = (lw + 1) / 2; } drawP.setWidth(lw); targetP->setPen(drawP); targetP->setBrush(drawB); if( opacity <= 100.0 && opacity > 0.0 ) { // Draw airspace filled with opacity factor targetP->setOpacity( opacity/100.0 ); targetP->drawPolygon(mP); // Reset opacity, that a solid line is drawn as next targetP->setBrush(Qt::NoBrush); targetP->setOpacity( 1.0 ); } else if( opacity == 0.0 ) { // draw only airspace borders without any filling inside targetP->setBrush(Qt::NoBrush); targetP->setOpacity( 1.0 ); } // Draw the outline of the airspace with the selected brush targetP->drawPath(pp); }
void BackgroundItem::setBackground( QPixmap *pixmap, PlacementType _parentRelativeType, Meta *_meta, BackgroundMeta &_background, BorderMeta &_border, MarginsMeta &_margin, StringListMeta &_subModel, int _submodelLevel, QString &toolTip) { meta = _meta; background = _background; border = _border; margin = _margin; subModelColor = _subModel; submodelLevel = _submodelLevel; parentRelativeType = _parentRelativeType; BorderData borderData = _border.valuePixels(); BackgroundData backgroundData = _background.value(); int bt = borderData.thickness; QColor penColor,brushColor; QRectF prect(bt/2,bt/2,pixmap->width()-1-bt,pixmap->height()-1-bt); pixmap->setAlphaChannel(*pixmap); pixmap->fill(Qt::transparent); QPainter painter(pixmap); switch(backgroundData.type) { case BackgroundData::BgImage: { QString image_name = backgroundData.string; QFile file(image_name); if ( ! file.exists()) { return; } QImage image(image_name); if (backgroundData.stretch) { QSize psize = pixmap->size(); QSize isize = image.size(); qreal sx = psize.width(); qreal sy = psize.height(); sx /= isize.width(); sy /= isize.height(); painter.scale(sx,sy); painter.drawImage(0,0,image); } else { for (int y = 0; y < pixmap->height(); y += image.height()) { for (int x = 0; x < pixmap->width(); x += image.width()) { painter.drawImage(x,y,image); } } } brushColor = Qt::transparent; } break; case BackgroundData::BgTransparent: break; case BackgroundData::BgColor: case BackgroundData::BgSubmodelColor: if (backgroundData.type == BackgroundData::BgColor) { brushColor = LDrawColor::color(backgroundData.string); } else { brushColor = LDrawColor::color(_subModel.value(submodelLevel)); } break; } qreal rx = borderData.radius; qreal ry = borderData.radius; qreal dx = pixmap->width(); qreal dy = pixmap->height(); if (dx && dy) { if (dx > dy) { // the rx is going to appear larger that ry, so decrease rx based on ratio rx *= dy; rx /= dx; } else { ry *= dx; ry /= dy; } } if (borderData.type == BorderData::BdrNone) { penColor = Qt::transparent; } else { penColor = LDrawColor::color(borderData.color); } QPen pen; pen.setColor(penColor); pen.setWidth(bt); pen.setCapStyle(Qt::RoundCap); pen.setJoinStyle(Qt::RoundJoin); painter.setPen(pen); painter.setBrush(brushColor); painter.setRenderHints(QPainter::HighQualityAntialiasing,true); painter.setRenderHints(QPainter::Antialiasing,true); if (borderData.type == BorderData::BdrRound) { painter.drawRoundRect(prect,rx,ry); } else { painter.drawRect(prect); } setToolTip(toolTip); setFlag(QGraphicsItem::ItemIsSelectable,true); setFlag(QGraphicsItem::ItemIsMovable,true); }
void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget ) { Q_UNUSED( itemStyle ); Q_UNUSED( pWidget ); if ( !painter ) { return; } if ( mComposition->plotStyle() == QgsComposition::Print || mComposition->plotStyle() == QgsComposition::Postscript ) { //exporting composition, so force an attribute refresh //we do this in case vector layer has changed via an external source (eg, another database user) refreshAttributes(); } drawBackground( painter ); painter->save(); //antialiasing on painter->setRenderHint( QPainter::Antialiasing, true ); painter->setPen( Qt::SolidLine ); //now draw the text double currentX = mGridStrokeWidth; double currentY; QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin(); int col = 0; double cellHeaderHeight = fontAscentMillimeters( mHeaderFont ) + 2 * mLineTextDistance; double cellBodyHeight = fontAscentMillimeters( mContentFont ) + 2 * mLineTextDistance; QRectF cell; for ( ; columnIt != mColumns.constEnd(); ++columnIt ) { currentY = mGridStrokeWidth; currentX += mLineTextDistance; cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellHeaderHeight ); //calculate alignment of header Qt::AlignmentFlag headerAlign = Qt::AlignLeft; switch ( mHeaderHAlignment ) { case FollowColumn: headerAlign = ( *columnIt )->hAlignment(); break; case HeaderLeft: headerAlign = Qt::AlignLeft; break; case HeaderCenter: headerAlign = Qt::AlignHCenter; break; case HeaderRight: headerAlign = Qt::AlignRight; break; } drawText( painter, cell, ( *columnIt )->heading(), mHeaderFont, headerAlign, Qt::AlignVCenter, Qt::TextDontClip ); currentY += cellHeaderHeight; currentY += mGridStrokeWidth; //draw the attribute values QList<QgsAttributeMap>::const_iterator attIt = mAttributeMaps.begin(); for ( ; attIt != mAttributeMaps.end(); ++attIt ) { cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellBodyHeight ); const QgsAttributeMap ¤tAttributeMap = *attIt; QString str = currentAttributeMap[ col ].toString(); drawText( painter, cell, str, mContentFont, ( *columnIt )->hAlignment(), Qt::AlignVCenter, Qt::TextDontClip ); currentY += cellBodyHeight; currentY += mGridStrokeWidth; } currentX += mMaxColumnWidthMap[ col ]; currentX += mLineTextDistance; currentX += mGridStrokeWidth; col++; } //and the borders if ( mShowGrid ) { QPen gridPen; gridPen.setWidthF( mGridStrokeWidth ); gridPen.setColor( mGridColor ); gridPen.setJoinStyle( Qt::MiterJoin ); painter->setPen( gridPen ); drawHorizontalGridLines( painter, mAttributeMaps.size() ); drawVerticalGridLines( painter, mMaxColumnWidthMap ); } painter->restore(); //draw frame and selection boxes if necessary drawFrame( painter ); if ( isSelected() ) { drawSelectionBoxes( painter ); } }
QImage* MyTextEffect::drawImage() { QFont myFont; QPen myPen; myPen.setJoinStyle( Qt::RoundJoin ); QBrush myBrush( QColor(0,0,0,0) ); QColor backgroundColor(0,0,0,0); int outline = 0; int align = 1; int arrowType = 0, arrowSize = 0, arrowPos = 0; QStringList sl = currentText.split("\n"); while ( !sl.isEmpty() ) { if ( sl.last().trimmed().isEmpty() ) sl.takeLast(); else break; } if ( sl.count() ) { QStringList desc = sl[0].split("|"); if ( desc.count() >= 9 ) { myFont.fromString( desc[0] ); myFont.setPointSize( desc[1].toInt() ); myFont.setBold( desc[2].toInt() ); myFont.setItalic( desc[3].toInt() ); QStringList fc = desc[4].split( "." ); if ( fc.count() == 2 ) { QColor col; col.setNamedColor( fc[ 0 ] ); col.setAlpha( fc[ 1 ].toInt() ); myPen.setColor( col ); myBrush.setColor( col ); } QStringList bc = desc[5].split( "." ); if ( bc.count() == 2 ) { backgroundColor.setNamedColor( bc[ 0 ] ); backgroundColor.setAlpha( bc[ 1 ].toInt() ); } align = desc[6].toInt(); int osize = desc[7].toInt(); if ( osize > 0 ) { QStringList oc = desc[8].split( "." ); if ( oc.count() == 2 ) { outline = osize; myPen.setWidth( osize ); myFont.setStyleStrategy( QFont::ForceOutline ); QColor col; col.setNamedColor( oc[ 0 ] ); col.setAlpha( oc[ 1 ].toInt() ); myPen.setColor( col ); } } } if ( desc.count() >= 12 ) { arrowType = desc[9].toInt(); arrowSize = desc[10].toInt(); arrowPos = desc[11].toInt(); } sl.takeFirst(); } QImage *image = new QImage( 10, 10, QImage::Format_ARGB32_Premultiplied ); QPainter painter; painter.begin( image ); painter.setPen( myPen ); painter.setBrush( myBrush ); painter.setFont( myFont ); QList<QRectF> br; QFontMetrics metrics( myFont ); int h = sl.count() * metrics.lineSpacing(); int w = 0; for ( int i = 0; i < sl.count(); ++i ) { QRectF minrect( 0, 0, 1, 1 ); QRectF r = painter.boundingRect( minrect, Qt::AlignHCenter | Qt::AlignVCenter, sl[i] ); if ( r.width() > w ) w = r.width(); br.append( r ); } QRectF minrect( 0, 0, 1, 1 ); int margin = qMax( painter.boundingRect( minrect, Qt::AlignHCenter | Qt::AlignVCenter, "M" ).width() / 3.0, 3.0 ); painter.end(); double x = ((double)outline + margin * 2) / 2.0; double y = x; w += 2 * x; h += 2 * y; if ( w > iwidth ) { x -= (w - iwidth) / 2.0; w = iwidth; } if ( h > iheight ) { y -= (h - iheight) / 2.0; h = iheight; } QPointF polygon[7]; arrowSize = h * arrowSize / 100.0; int n = 0; int leftOffset = 0, topOffset = 0; int wMargin = 0, hMargin = 0; if (arrowType) { switch (arrowType) { case 1: { leftOffset = arrowSize; wMargin = arrowSize; polygon[n].setX(1 + arrowSize); polygon[n++].setY(1); polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 - arrowSize / 2.0) ) ); polygon[n++].setX(1 + arrowSize); polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0) ) ); polygon[n++].setX(1); polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 + arrowSize / 2.0) ) ); polygon[n++].setX(1 + arrowSize); polygon[n].setX(1 + arrowSize); polygon[n++].setY(h - 1); polygon[n].setX(w - 1 + arrowSize); polygon[n++].setY(h - 1); polygon[n].setX(w - 1 + arrowSize); polygon[n++].setY(1); break; } case 2: { wMargin = arrowSize; polygon[n].setX(1); polygon[n++].setY(1); polygon[n].setX(1); polygon[n++].setY(h - 1); polygon[n].setX(w - 1); polygon[n++].setY(h - 1); polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 + arrowSize / 2.0) ) ); polygon[n++].setX(w - 1); polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0) ) ); polygon[n++].setX(w - 1 + arrowSize); polygon[n].setY(qMax(1.0, qMin(h - 1.0, h * arrowPos / 100.0 - arrowSize / 2.0) ) ); polygon[n++].setX(w - 1); polygon[n].setX(w - 1); polygon[n++].setY(1); break; } case 3: { topOffset = arrowSize; hMargin = arrowSize; polygon[n].setX(1); polygon[n++].setY(1 + arrowSize); polygon[n].setX(1); polygon[n++].setY(h - 1 + arrowSize); polygon[n].setX(w - 1); polygon[n++].setY(h - 1 + arrowSize); polygon[n].setX(w - 1); polygon[n++].setY(1 + arrowSize); polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 + arrowSize / 2.0) ) ); polygon[n++].setY(1 + arrowSize); polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0) ) ); polygon[n++].setY(1); polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 - arrowSize / 2.0) ) ); polygon[n++].setY(1 + arrowSize); break; } case 4: { hMargin = arrowSize; polygon[n].setX(1); polygon[n++].setY(1); polygon[n].setX(1); polygon[n++].setY(h - 1); polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 - arrowSize / 2.0) ) ); polygon[n++].setY(h - 1); polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0) ) ); polygon[n++].setY(h - 1 + arrowSize); polygon[n].setX(qMax(1.0, qMin(w - 1.0, w * arrowPos / 100.0 + arrowSize / 2.0) ) ); polygon[n++].setY(h - 1); polygon[n].setX(w - 1); polygon[n++].setY(h - 1); polygon[n].setX(w - 1); polygon[n++].setY(1); break; } } } delete image; image = new QImage( w + wMargin, h + hMargin, QImage::Format_ARGB32_Premultiplied ); image->fill( QColor(0,0,0,0) ); painter.begin( image ); painter.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing ); if ( backgroundColor.alpha() > 0 ) { painter.setPen( QColor(0,0,0,0) ); painter.setBrush( backgroundColor ); if (arrowType) { painter.drawPolygon( polygon, 7 ); } else { painter.drawRect( 1, 1, w - 2, h - 2 ); } } painter.setPen( myPen ); painter.setBrush( myBrush ); painter.setFont( myFont ); for ( int i = 0; i < sl.count(); ++i ) { QPointF point( 0, y + topOffset + metrics.ascent() ); switch ( align ) { case 2: { point.setX( leftOffset + (double)w / 2.0 - br[i].width() / 2.0 ); break; } case 3: { point.setX( leftOffset + w - x - br[i].width() ); break; } default: { point.setX( leftOffset + x ); break; } } if ( outline ) { QPainterPath myPath; myPath.addText( point, myFont, sl[i] ); painter.drawPath( myPath ); } else painter.drawText( point, sl[i] ); y += metrics.lineSpacing(); } painter.end(); return image; }