void QgsFillSymbolV2::renderPolygonUsingLayer( QgsSymbolLayerV2* layer, const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context ) { QgsSymbolV2::SymbolType layertype = layer->type(); QgsPaintEffect* effect = layer->paintEffect(); if ( effect && effect->enabled() ) { QRectF bounds = polygonBounds( points, rings ); QList<QPolygonF>* translatedRings = translateRings( rings, -bounds.left(), -bounds.top() ); QPainter* p = context.renderContext().painter(); p->save(); p->translate( bounds.topLeft() ); effect->begin( context.renderContext() ); if ( layertype == QgsSymbolV2::Fill ) { (( QgsFillSymbolLayerV2* )layer )->renderPolygon( points.translated( -bounds.topLeft() ), translatedRings, context ); } else if ( layertype == QgsSymbolV2::Line ) { (( QgsLineSymbolLayerV2* )layer )->renderPolygonOutline( points.translated( -bounds.topLeft() ), translatedRings, context ); } delete translatedRings; effect->end( context.renderContext() ); p->restore(); } else { if ( layertype == QgsSymbolV2::Fill ) { (( QgsFillSymbolLayerV2* )layer )->renderPolygon( points, rings, context ); } else if ( layertype == QgsSymbolV2::Line ) { (( QgsLineSymbolLayerV2* )layer )->renderPolygonOutline( points, rings, context ); } } }
QgsComposerNodesItem::QgsComposerNodesItem( QString tagName, QPolygonF polygon, QgsComposition* c ) : QgsComposerItem( c ) , mTagName( tagName ) , mSelectedNode( -1 ) , mDrawNodes( false ) { const QRectF boundingRect = polygon.boundingRect(); setSceneRect( boundingRect ); const QPointF topLeft = boundingRect.topLeft(); mPolygon = polygon.translated( -topLeft ); }
void QgsLineSymbolV2::renderPolylineUsingLayer( QgsLineSymbolLayerV2 *layer, const QPolygonF &points, QgsSymbolV2RenderContext &context ) { QgsPaintEffect* effect = layer->paintEffect(); if ( effect && effect->enabled() ) { QPainter* p = context.renderContext().painter(); p->save(); p->translate( points.boundingRect().topLeft() ); effect->begin( context.renderContext() ); layer->renderPolyline( points.translated( -points.boundingRect().topLeft() ), context ); effect->end( context.renderContext() ); p->restore(); } else { layer->renderPolyline( points, context ); } }
void OrthogonalRenderer::drawMapObject(QPainter *painter, const MapObject *object, const QColor &color) const { painter->save(); const QRectF &bounds = object->bounds(); QRectF rect(tileToPixelCoords(bounds.topLeft()), tileToPixelCoords(bounds.bottomRight())); painter->translate(rect.topLeft()); rect.moveTopLeft(QPointF(0, 0)); if (!object->cell().isEmpty()) { const Cell &cell = object->cell(); CellRenderer(painter).render(cell, QPointF(), CellRenderer::BottomLeft); if (testFlag(ShowTileObjectOutlines)) { const QRect rect = cell.tile->image().rect(); QPen pen(Qt::SolidLine); pen.setWidth(0); painter->setPen(pen); painter->drawRect(rect); pen.setStyle(Qt::DotLine); pen.setColor(color); painter->setPen(pen); painter->drawRect(rect); } } else { const QPen linePen(color, 2); const QPen shadowPen(Qt::black, 2); QColor brushColor = color; brushColor.setAlpha(50); const QBrush fillBrush(brushColor); painter->setRenderHint(QPainter::Antialiasing); switch (object->shape()) { case MapObject::Rectangle: { if (rect.isNull()) rect = QRectF(QPointF(-10, -10), QSizeF(20, 20)); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); // Draw the shadow painter->setPen(shadowPen); painter->drawRect(rect.translated(QPointF(1, 1))); if (!name.isEmpty()) painter->drawText(QPoint(1, -5 + 1), name); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawRect(rect); if (!name.isEmpty()) painter->drawText(QPoint(0, -5), name); break; } case MapObject::Polyline: { QPolygonF screenPolygon = tileToPixelCoords(object->polygon()); painter->setPen(shadowPen); painter->drawPolyline(screenPolygon.translated(1, 1)); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawPolyline(screenPolygon); break; } case MapObject::Polygon: { QPolygonF screenPolygon = tileToPixelCoords(object->polygon()); painter->setPen(shadowPen); painter->drawPolygon(screenPolygon.translated(1, 1)); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawPolygon(screenPolygon); break; } case MapObject::Ellipse: { if (rect.isNull()) rect = QRectF(QPointF(-10, -10), QSizeF(20, 20)); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); // Draw the shadow painter->setPen(shadowPen); painter->drawEllipse(rect.translated(QPointF(1, 1))); if (!name.isEmpty()) painter->drawText(QPoint(1, -5 + 1), name); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawEllipse(rect); if (!name.isEmpty()) painter->drawText(QPoint(0, -5), name); break; } } } painter->restore(); }
void OrthogonalRenderer::drawMapObject(QPainter *painter, const MapObject *object, const QColor &color) const { painter->save(); const QRectF bounds = object->bounds(); QRectF rect(bounds); painter->translate(rect.topLeft()); rect.moveTopLeft(QPointF(0, 0)); const Cell &cell = object->cell(); if (!cell.isEmpty()) { CellRenderer(painter).render(cell, QPointF(), CellRenderer::BottomLeft); if (testFlag(ShowTileObjectOutlines)) { const Tile *tile = cell.tile; const QSize imgSize = tile->size(); const QPointF tileOffset = tile->tileset()->tileOffset(); QRectF rect(QPointF(tileOffset.x(), tileOffset.y() - imgSize.height()), imgSize); QPen pen(Qt::SolidLine); pen.setCosmetic(true); painter->setPen(pen); painter->drawRect(rect); pen.setStyle(Qt::DotLine); pen.setColor(color); painter->setPen(pen); painter->drawRect(rect); } } else { const qreal lineWidth = objectLineWidth(); const qreal scale = painterScale(); const qreal shadowDist = (lineWidth == 0 ? 1 : lineWidth) / scale; const QPointF shadowOffset = QPointF(shadowDist * 0.5, shadowDist * 0.5); QPen linePen(color, lineWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); linePen.setCosmetic(true); QPen shadowPen(linePen); shadowPen.setColor(Qt::black); QColor brushColor = color; brushColor.setAlpha(50); const QBrush fillBrush(brushColor); painter->setRenderHint(QPainter::Antialiasing); // Trying to draw an ellipse with 0-width is causing a hang in // CoreGraphics when drawing the path requested by the // QCoreGraphicsPaintEngine. Draw them as rectangle instead. MapObject::Shape shape = object->shape(); if (shape == MapObject::Ellipse && ((rect.width() == qreal(0)) ^ (rect.height() == qreal(0)))) { shape = MapObject::Rectangle; } switch (shape) { case MapObject::Rectangle: { if (rect.isNull()) rect = QRectF(QPointF(-10, -10), QSizeF(20, 20)); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); // Draw the shadow painter->setPen(shadowPen); painter->drawRect(rect.translated(shadowOffset)); if (!name.isEmpty()) painter->drawText(QPointF(0, -4 - lineWidth / 2) + shadowOffset, name); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawRect(rect); if (!name.isEmpty()) painter->drawText(QPointF(0, -4 - lineWidth / 2), name); break; } case MapObject::Polyline: { QPolygonF screenPolygon = pixelToScreenCoords(object->polygon()); painter->setPen(shadowPen); painter->drawPolyline(screenPolygon.translated(shadowOffset)); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawPolyline(screenPolygon); break; } case MapObject::Polygon: { QPolygonF screenPolygon = pixelToScreenCoords(object->polygon()); painter->setPen(shadowPen); painter->drawPolygon(screenPolygon.translated(shadowOffset)); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawPolygon(screenPolygon); break; } case MapObject::Ellipse: { if (rect.isNull()) rect = QRectF(QPointF(-10, -10), QSizeF(20, 20)); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); // Draw the shadow painter->setPen(shadowPen); painter->drawEllipse(rect.translated(shadowOffset)); if (!name.isEmpty()) painter->drawText(QPoint(1, -5 + 1), name); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawEllipse(rect); if (!name.isEmpty()) painter->drawText(QPoint(0, -5), name); break; } } } painter->restore(); }
int main(int argc, char **argv) { if (argc < 4) { fprintf(stderr, "import <maps.json> <map id> <file.tif>\n"); return -1; } OGRRegisterAll(); GDALAllRegister(); QFile rootFile(argv[1]); QString mapId(argv[2]); QFileInfo filename(argv[3]); RootData rootData(NULL); Map *map = rootData.maps()[mapId]; Projection *pjGeo = Geographic::getProjection(NAD27); Projection *pj = map->projection(); readQuadIndex(0, "/Users/hawkinsp/geo/drg/index/drg100.shp", "drg100", pj); readQuadIndex(1, "/Users/hawkinsp/geo/drg/index/drg24.shp", "drg24", pj); // Index information seems buggy for these quads -- just use the regular grid. quads.remove("o37122g4"); // San Francisco North quads.remove("o37122g5"); // Point Bonita GDALDataset *ds = (GDALDataset *)GDALOpen(filename.filePath().toLatin1().data(), GA_ReadOnly); if (!ds) { fprintf(stderr, "ERROR: Could not open dataset.\n"); return -1; } const char *proj = ds->GetProjectionRef(); Quad quad; getQuadInfo(filename, pj, quad); // Read projection OGRSpatialReference srs; srs.importFromWkt((char **)&proj); // Size of the DRG QSize drgSize = QSize(ds->GetRasterXSize(), ds->GetRasterYSize()); printf("DRG id: %s, name %s, size %dx%d\n", quad.id.toLatin1().data(), quad.name.toLatin1().data(), drgSize.width(), drgSize.height()); // ------------------------------------------ // Read geotransform coefficients. The geotransform describe the mapping from // DRG image space to projection space. double geoTransformCoeff[6]; ds->GetGeoTransform(geoTransformCoeff); // Top left coordinate of the drg in projection space QPointF fProjTopLeft = QPointF(geoTransformCoeff[0], geoTransformCoeff[3]); // Size of a drg pixel in projection space QSizeF fPixelSize = QSizeF(geoTransformCoeff[1], geoTransformCoeff[5]); // Check Y pixel size is the negation of the X pixel size if (fabs(fPixelSize.width() + fPixelSize.height()) >= epsilon) { fprintf(stderr, "Invalid pixel sizes\n"); return -1; } // We assume the geotransform consists of only translation and scaling. // We'd need to do a more general image transformation to handle shearing. if (fabs(geoTransformCoeff[2]) >= epsilon || fabs(geoTransformCoeff[4]) >= epsilon) { fprintf(stderr, "ERROR: DRG geotransform has shear component.\n"); return -1; } // Transforms from drg space to projection space and vice versa QTransform drgProjTransform; drgProjTransform.translate(fProjTopLeft.x(), fProjTopLeft.y()); drgProjTransform.scale(fPixelSize.width(), fPixelSize.height()); QTransform projDrgTransform = drgProjTransform.inverted(); // Size of the DRG in projection space QSizeF fProjSize = QSizeF(qreal(ds->GetRasterXSize()) * fPixelSize.width(), qreal(ds->GetRasterYSize()) * fPixelSize.height()); QRectF projRect = QRectF(fProjTopLeft, fProjSize); // Rectangle covered by the entire map image QRectF mapRect = map->projToMap().mapRect(projRect); printf("Map Rect: %lf %lf %lf %lf\n", mapRect.left(), mapRect.top(), mapRect.right(), mapRect.bottom()); // Compute the initial scale factor and tile level QSizeF mapPixelSize = map->mapPixelSize(); assert(mapPixelSize.width() + mapPixelSize.height() < epsilon); QSizeF scale(fPixelSize.width() / mapPixelSize.width(), fPixelSize.height() / mapPixelSize.height()); int maxLevel = map->maxLevel(); while (scale.width() >= 1.1) { maxLevel--; scale /= 2.0; } // printf("scale %lf %lf\n", scale.width(), scale.height()); //return 0; // Compute the quad boundary QPolygonF projQuad(quad.boundary); QPolygonF geoQuad = pjGeo->transformFrom(pj, projQuad); QRectF geoQuadBounds(geoQuad.boundingRect()); printf("Series: %d %s\n", quad.series, map->layer(quad.series).name().toLatin1().data()); printf("Geographic quad boundary: %lf %lf %lf %lf\n", geoQuadBounds.left(), geoQuadBounds.top(), geoQuadBounds.right(), geoQuadBounds.bottom()); // Quad bounding rectangle in map space QRectF projQuadBounds = projQuad.boundingRect(); QRectF mapQuadBounds = map->projToMap().mapRect(projQuadBounds); printf("Quad bounding rectangle in map space: %lf %lf %lf %lf\n", mapQuadBounds.left(), mapQuadBounds.top(), mapQuadBounds.right(), mapQuadBounds.bottom()); // Quad bounding rectangle in drg space QPolygonF drgBounds = projDrgTransform.map(projQuad); QRectF drgQuadBounds = drgBounds.boundingRect(); printf("Quad bounding rectangle in drg space: %lf %lf %lf %lf\n", drgQuadBounds.left(), drgQuadBounds.top(), drgQuadBounds.right(), drgQuadBounds.bottom()); // Read the image QImage drg(filename.filePath()); if (drgQuadBounds.left() < -drgQuadSlackPixels || drgQuadBounds.right() > drgSize.width() + drgQuadSlackPixels || drgQuadBounds.top() < -drgQuadSlackPixels || drgQuadBounds.bottom() > drgSize.height() + drgQuadSlackPixels) { QString mfile("misalign-" + filename.baseName() + ".png"); fprintf(stderr, "WARNING: DRG and quadrangle boundaries are misaligned; diagnostic saved to '%s'!\n", mfile.toLatin1().data()); QImage image = drg.convertToFormat(QImage::Format_RGB32); QPainter p; p.begin(&image); QPainterPath pp; pp.addPolygon(drgBounds); p.setPen(QPen(Qt::blue, 2)); p.drawPath(pp); p.end(); image.save(mfile, "png"); } /*printf("top left %lf %lf\n", fProjTopLeft.x(), fProjTopLeft.y());*/ /*for (int i = 0; i< projectedQuad.size(); i++) { printf("quad proj %lf %lf\n", projectedQuad[i].x(), projectedQuad[i].y()); }*/ QDir dir; // for (int level = maxLevel; level >= 0; level--, scale /= 2.0) { int level = maxLevel; QSizeF rasterSizeF = QSizeF(ds->GetRasterXSize() * scale.width(), ds->GetRasterYSize() * scale.height()); QSize rasterSize = rasterSizeF.toSize(); printf("level %d size %dx%d\n", level, rasterSize.width(), rasterSize.height()); QImage drgScaled = drg.scaled(rasterSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); QPolygonF imageQuad; for (int i = 0; i < projQuad.size(); i++) { QPointF p = projQuad[i] - fProjTopLeft; imageQuad << QPointF(p.x() * scale.width() / fPixelSize.width(), p.y() * scale.height() / fPixelSize.height()); } QSizeF baseTileSize(map->baseTileSize(), map->baseTileSize()); int tileSize = map->tileSize(level); QRectF tileRectF = QRectF(mapQuadBounds.topLeft() / qreal(tileSize), mapQuadBounds.bottomRight() / qreal(tileSize)); QRect tileRect(QPoint(int(floor(tileRectF.left())), int(floor(tileRectF.top()))), QPoint(int(ceil(tileRectF.right())), int(ceil(tileRectF.bottom())))); /* printf("tile rect %d %d %d %d\n", tileRect.left(), tileRect.top(), tileRect.right(), tileRect.bottom());*/ for (int tileY = tileRect.top(); tileY <= tileRect.bottom(); tileY++) { for (int tileX = tileRect.left(); tileX <= tileRect.right(); tileX++) { Tile key(tileX, tileY, level, quad.series); QPointF tileTopLeft(tileX * tileSize, tileY * tileSize); QPointF deltaTileTopLeft = tileTopLeft - mapRect.topLeft(); qreal s = qreal(1 << (map->maxLevel() - level)); QPointF topLeft(deltaTileTopLeft.x() / s, deltaTileTopLeft.y() / s); QRectF src(topLeft, baseTileSize); QFileInfo tilePath(map->tilePath(key)); dir.mkpath(tilePath.path()); QImage image; if (tilePath.exists()) { QImage idxImage = QImage(tilePath.filePath()); image = idxImage.convertToFormat(QImage::Format_RGB32); } else { image = QImage(256, 256, QImage::Format_RGB32); image.setColorTable(drg.colorTable()); image.fill(QColor(255, 255, 255).rgb()); } QPainterPath pp; pp.addPolygon(imageQuad.translated(-topLeft)); QPainter painter; painter.begin(&image); painter.setClipPath(pp); painter.drawImage(-topLeft, drgScaled); // painter.setPen(QPen(QColor(0, 0, 255))); // painter.drawPath(pp); painter.end(); QImage tile = image.convertToFormat(QImage::Format_Indexed8, drg.colorTable(), Qt::ThresholdDither); tile.save(tilePath.filePath(), "png"); // printf("tile: %s\n", tilePath.filePath().toLatin1().data()); } } // } return 0; }
void Bend::layout() { // during mtest, there may be no score. If so, exit. if (!score()) return; qreal _spatium = spatium(); if (staff() && !staff()->isTabStaff(tick())) { if (!parent()) { noteWidth = -_spatium*2; notePos = QPointF(0.0, _spatium*3); } } qreal _lw = _lineWidth; Note* note = toNote(parent()); if (note == 0) { noteWidth = 0.0; notePos = QPointF(); } else { notePos = note->pos(); noteWidth = note->width(); } QRectF bb; QFontMetricsF fm(font(_spatium), MScore::paintDevice()); int n = _points.size(); qreal x = noteWidth; qreal y = -_spatium * .8; qreal x2, y2; qreal aw = _spatium * .5; QPolygonF arrowUp; arrowUp << QPointF(0, 0) << QPointF(aw*.5, aw) << QPointF(-aw*.5, aw); QPolygonF arrowDown; arrowDown << QPointF(0, 0) << QPointF(aw*.5, -aw) << QPointF(-aw*.5, -aw); for (int pt = 0; pt < n; ++pt) { if (pt == (n-1)) break; int pitch = _points[pt].pitch; if (pt == 0 && pitch) { y2 = -notePos.y() -_spatium * 2; x2 = x; bb |= QRectF(x, y, x2-x, y2-y); bb |= arrowUp.translated(x2, y2 + _spatium * .2).boundingRect(); int idx = (pitch + 12)/25; const char* l = label[idx]; bb |= fm.boundingRect(QRectF(x2, y2, 0, 0), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip, QString(l)); y = y2; } if (pitch == _points[pt+1].pitch) { if (pt == (n-2)) break; x2 = x + _spatium; y2 = y; bb |= QRectF(x, y, x2-x, y2-y); } else if (pitch < _points[pt+1].pitch) { // up x2 = x + _spatium*.5; y2 = -notePos.y() -_spatium * 2; qreal dx = x2 - x; qreal dy = y2 - y; QPainterPath path; path.moveTo(x, y); path.cubicTo(x+dx/2, y, x2, y+dy/4, x2, y2); bb |= path.boundingRect(); bb |= arrowUp.translated(x2, y2 + _spatium * .2).boundingRect(); int idx = (_points[pt+1].pitch + 12)/25; const char* l = label[idx]; QRectF r; bb |= fm.boundingRect(QRectF(x2, y2, 0, 0), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip, QString(l)); } else { // down x2 = x + _spatium*.5; y2 = y + _spatium * 3; qreal dx = x2 - x; qreal dy = y2 - y; QPainterPath path; path.moveTo(x, y); path.cubicTo(x+dx/2, y, x2, y+dy/4, x2, y2); bb |= path.boundingRect(); bb |= arrowDown.translated(x2, y2 - _spatium * .2).boundingRect(); } x = x2; y = y2; } bb.adjust(-_lw, -_lw, _lw, _lw); setbbox(bb); setPos(0.0, 0.0); }
void Bend::draw(QPainter* painter) const { qreal _spatium = spatium(); qreal _lw = _lineWidth; QPen pen(curColor(), _lw, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); painter->setPen(pen); painter->setBrush(QBrush(curColor())); QFont f = font(_spatium * MScore::pixelRatio); painter->setFont(f); QFontMetrics fm(f, MScore::paintDevice()); qreal x = noteWidth + _spatium * .2; qreal y = -_spatium * .8; qreal x2, y2; qreal aw = score()->styleP(Sid::bendArrowWidth); QPolygonF arrowUp; arrowUp << QPointF(0, 0) << QPointF(aw * .5, aw) << QPointF(-aw *.5, aw); QPolygonF arrowDown; arrowDown << QPointF(0, 0) << QPointF(aw * .5, -aw) << QPointF(-aw *.5, -aw); int n = _points.size(); for (int pt = 0; pt < n-1; ++pt) { int pitch = _points[pt].pitch; if (pt == 0 && pitch) { y2 = -notePos.y() -_spatium * 2; x2 = x; painter->drawLine(QLineF(x, y, x2, y2)); painter->setBrush(curColor()); painter->drawPolygon(arrowUp.translated(x2, y2)); int idx = (pitch + 12)/25; const char* l = label[idx]; QString s(l); qreal textWidth = fm.width(s); qreal textHeight = fm.height(); painter->drawText(QRectF(x2 - textWidth / 2, y2 - textHeight / 2, .0, .0), Qt::AlignVCenter|Qt::TextDontClip, s); y = y2; } if (pitch == _points[pt+1].pitch) { if (pt == (n-2)) break; x2 = x + _spatium; y2 = y; painter->drawLine(QLineF(x, y, x2, y2)); } else if (pitch < _points[pt+1].pitch) { // up x2 = x + _spatium*.5; y2 = -notePos.y() -_spatium * 2; qreal dx = x2 - x; qreal dy = y2 - y; QPainterPath path; path.moveTo(x, y); path.cubicTo(x+dx/2, y, x2, y+dy/4, x2, y2); painter->setBrush(Qt::NoBrush); painter->drawPath(path); painter->setBrush(curColor()); painter->drawPolygon(arrowUp.translated(x2, y2 )); int idx = (_points[pt+1].pitch + 12)/25; const char* l = label[idx]; qreal ty = y2; // - _spatium; painter->drawText(QRectF(x2, ty, .0, .0), Qt::AlignHCenter | Qt::AlignBottom | Qt::TextDontClip, QString(l)); } else { // down x2 = x + _spatium*.5; y2 = y + _spatium * 3; qreal dx = x2 - x; qreal dy = y2 - y; QPainterPath path; path.moveTo(x, y); path.cubicTo(x+dx/2, y, x2, y+dy/4, x2, y2); painter->setBrush(Qt::NoBrush); painter->drawPath(path); painter->setBrush(curColor()); painter->drawPolygon(arrowDown.translated(x2, y2)); } x = x2; y = y2; } }
void OrthogonalRenderer::drawMapObject(QPainter *painter, const MapObject *object, const QColor &color) const { painter->save(); const QRectF bounds = object->bounds(); QRectF rect(bounds); painter->translate(rect.topLeft()); rect.moveTopLeft(QPointF(0, 0)); if (!object->cell().isEmpty()) { const Cell &cell = object->cell(); CellRenderer(painter).render(cell, QPointF(), CellRenderer::BottomLeft); if (testFlag(ShowTileObjectOutlines)) { const QRect rect = cell.tile->image().rect(); QPen pen(Qt::SolidLine); pen.setCosmetic(true); painter->setPen(pen); painter->drawRect(rect); pen.setStyle(Qt::DotLine); pen.setColor(color); painter->setPen(pen); painter->drawRect(rect); } } else { const qreal lineWidth = objectLineWidth(); const qreal scale = painterScale(); const qreal shadowDist = (lineWidth == 0 ? 1 : lineWidth) / scale; const QPointF shadowOffset = QPointF(shadowDist * 0.5, shadowDist * 0.5); QPen linePen(color, lineWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); linePen.setCosmetic(true); QPen shadowPen(linePen); shadowPen.setColor(Qt::black); QColor brushColor = color; brushColor.setAlpha(50); const QBrush fillBrush(brushColor); painter->setRenderHint(QPainter::Antialiasing); switch (object->shape()) { case MapObject::Rectangle: { if (rect.isNull()) rect = QRectF(QPointF(-10, -10), QSizeF(20, 20)); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); // Draw the shadow painter->setPen(shadowPen); painter->drawRect(rect.translated(shadowOffset)); if (!name.isEmpty()) painter->drawText(QPointF(0, -4 - lineWidth / 2) + shadowOffset, name); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawRect(rect); if (!name.isEmpty()) painter->drawText(QPointF(0, -4 - lineWidth / 2), name); break; } case MapObject::Polyline: { QPolygonF screenPolygon = pixelToScreenCoords(object->polygon()); painter->setPen(shadowPen); painter->drawPolyline(screenPolygon.translated(shadowOffset)); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawPolyline(screenPolygon); break; } case MapObject::Polygon: { QPolygonF screenPolygon = pixelToScreenCoords(object->polygon()); painter->setPen(shadowPen); painter->drawPolygon(screenPolygon.translated(shadowOffset)); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawPolygon(screenPolygon); break; } case MapObject::Ellipse: { if (rect.isNull()) rect = QRectF(QPointF(-10, -10), QSizeF(20, 20)); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); // Draw the shadow painter->setPen(shadowPen); painter->drawEllipse(rect.translated(shadowOffset)); if (!name.isEmpty()) painter->drawText(QPoint(1, -5 + 1), name); painter->setPen(linePen); painter->setBrush(fillBrush); painter->drawEllipse(rect); if (!name.isEmpty()) painter->drawText(QPoint(0, -5), name); break; } } } painter->restore(); }