Esempio n. 1
0
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 );
    }
  }
}
Esempio n. 2
0
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 );
}
Esempio n. 3
0
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();
}
Esempio n. 5
0
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();
}
Esempio n. 6
0
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;
}
Esempio n. 7
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);
      }
Esempio n. 8
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;
            }
      }
Esempio n. 9
0
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();
}