Example #1
0
void QgsLineStringV2::transform( const QTransform& t )
{
  mCoords = t.map( mCoords );
}
Example #2
0
QBezier QBezier::mapBy(const QTransform &transform) const
{
    return QBezier::fromPoints(transform.map(pt1()), transform.map(pt2()), transform.map(pt3()), transform.map(pt4()));
}
Example #3
0
void TextNode::applyDeltaMatrix(QPointF delta) {
	QTransform t;
	t.fromTranslate(delta.x(), delta.y());
	applyMatrix(t);
}
bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFactor, const QString& layerName, QgsSymbolV2RenderContext *context, const QgsFeature*, QPointF shift ) const
{
  //width
  double symbolWidth = mSymbolWidth;

  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH ) ) //1. priority: data defined setting on symbol layer le
  {
    context->setOriginalValueVariable( mSymbolWidth );
    symbolWidth = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_WIDTH, *context, mSymbolWidth ).toDouble();
  }
  else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
  {
    symbolWidth = mSize;
  }
  if ( mSymbolWidthUnit == QgsSymbolV2::MM )
  {
    symbolWidth *= mmMapUnitScaleFactor;
  }

  //height
  double symbolHeight = mSymbolHeight;
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_HEIGHT ) ) //1. priority: data defined setting on symbol layer level
  {
    context->setOriginalValueVariable( mSymbolHeight );
    symbolHeight = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_HEIGHT, *context, mSymbolHeight ).toDouble();
  }
  else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
  {
    symbolHeight = mSize;
  }
  if ( mSymbolHeightUnit == QgsSymbolV2::MM )
  {
    symbolHeight *= mmMapUnitScaleFactor;
  }

  //outline width
  double outlineWidth = mOutlineWidth;

  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH ) )
  {
    context->setOriginalValueVariable( mOutlineWidth );
    outlineWidth = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_WIDTH, *context, mOutlineWidth ).toDouble();
  }
  if ( mOutlineWidthUnit == QgsSymbolV2::MM )
  {
    outlineWidth *= outlineWidth;
  }

  //fill color
  bool ok;
  QColor fc = mColor;
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR ) )
  {
    context->setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mColor ) );
    QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_FILL_COLOR, *context, QVariant(), &ok ).toString();
    if ( ok )
      fc = QgsSymbolLayerV2Utils::decodeColor( colorString );
  }

  //outline color
  QColor oc = mOutlineColor;
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR ) )
  {
    context->setOriginalValueVariable( QgsSymbolLayerV2Utils::encodeColor( mOutlineColor ) );
    QString colorString = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_OUTLINE_COLOR, *context, QVariant(), &ok ).toString();
    if ( ok )
      oc = QgsSymbolLayerV2Utils::decodeColor( colorString );
  }

  //symbol name
  QString symbolName = mSymbolName;
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME ) )
  {
    context->setOriginalValueVariable( mSymbolName );
    symbolName = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_SYMBOL_NAME, *context, mSymbolName ).toString();
  }

  //offset
  double offsetX = 0;
  double offsetY = 0;
  markerOffset( *context, offsetX, offsetY );
  QPointF off( offsetX, offsetY );

  //priority for rotation: 1. data defined symbol level, 2. symbol layer rotation (mAngle)
  double rotation = 0.0;
  if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION ) )
  {
    context->setOriginalValueVariable( mAngle );
    rotation = evaluateDataDefinedProperty( QgsSymbolLayerV2::EXPR_ROTATION, *context, mAngle ).toDouble() + mLineAngle;
  }
  else if ( !qgsDoubleNear( mAngle + mLineAngle, 0.0 ) )
  {
    rotation = mAngle + mLineAngle;
  }
  rotation = -rotation; //rotation in Qt is counterclockwise
  if ( rotation )
    off = _rotatedOffset( off, rotation );

  QTransform t;
  t.translate( shift.x() + offsetX, shift.y() + offsetY );

  if ( !qgsDoubleNear( rotation, 0.0 ) )
    t.rotate( rotation );

  double halfWidth = symbolWidth / 2.0;
  double halfHeight = symbolHeight / 2.0;

  if ( symbolName == "circle" )
  {
    if ( qgsDoubleNear( halfWidth, halfHeight ) )
    {
      QPointF pt( t.map( QPointF( 0, 0 ) ) );
      e.writeFilledCircle( layerName, oc, pt, halfWidth );
    }
    else
    {
      QgsPolyline line;
      line.reserve( 40 );
      double stepsize = 2 * M_PI / 40;
      for ( int i = 0; i < 39; ++i )
      {
        double angle = stepsize * i;
        double x = halfWidth * cos( angle );
        double y = halfHeight * sin( angle );
        QPointF pt( t.map( QPointF( x, y ) ) );
        line.push_back( pt );
      }
      //close ellipse with first point
      line.push_back( line.at( 0 ) );
      if ( mBrush.style() != Qt::NoBrush )
        e.writePolygon( QgsPolygon() << line, layerName, "SOLID", fc );
      if ( mPen.style() != Qt::NoPen )
        e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth );
    }
  }
  else if ( symbolName == "rectangle" )
  {
    QgsPolygon p( 1 );
    p[0].resize( 5 );
    p[0][0] = t.map( QPointF( -halfWidth, -halfHeight ) );
    p[0][1] = t.map( QPointF( halfWidth, -halfHeight ) );
    p[0][2] = t.map( QPointF( halfWidth, halfHeight ) );
    p[0][3] = t.map( QPointF( -halfWidth, halfHeight ) );
    p[0][4] = p[0][0];
    if ( mBrush.style() != Qt::NoBrush )
      e.writePolygon( p, layerName, "SOLID", fc );
    if ( mPen.style() != Qt::NoPen )
      e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth );
    return true;
  }
  else if ( symbolName == "cross" && mPen.style() != Qt::NoPen )
  {
    QgsPolyline line( 2 );
    line[0] = t.map( QPointF( -halfWidth, 0 ) );
    line[1] = t.map( QPointF( halfWidth, 0 ) );
    e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth );

    line[0] = t.map( QPointF( 0, halfHeight ) );
    line[1] = t.map( QPointF( 0, -halfHeight ) );
    e.writePolyline( line, layerName, "CONTINUOUS", oc, outlineWidth );

    return true;
  }
  else if ( symbolName == "triangle" )
  {
    QgsPolygon p( 1 );
    p[0].resize( 4 );
    p[0][0] = QPointF( t.map( QPointF( -halfWidth, -halfHeight ) ) );
    p[0][1] = QPointF( t.map( QPointF( halfWidth, -halfHeight ) ) );
    p[0][2] = QPointF( t.map( QPointF( 0, halfHeight ) ) );
    p[0][3] = p[0][0];
    if ( mBrush.style() != Qt::NoBrush )
      e.writePolygon( p, layerName, "SOLID", fc );
    if ( mPen.style() != Qt::NoPen )
      e.writePolyline( p[0], layerName, "CONTINUOUS", oc, outlineWidth );
    return true;
  }

  return false; //soon...
}
Example #5
0
void CWorld::Create(int width, int height, int textureID, float heightMap, int MPU, bool indoor, const string& bitmap)
{
	m_width = width;
	m_height = height;
	m_MPU = MPU;
	m_inDoor = indoor;

	m_cameraPos = D3DXVECTOR3(MPU * -14, heightMap + MPU * 25, MPU * -14);
	m_cameraAngle.x = 45.0f;
	m_cameraAngle.y = -30.0f;

	_initialize();

	int x, i, y, x2, y2;
	CLandscape* land;
	for (y = 0; y < m_height; y++)
	{
		for (x = 0; x < m_width; x++)
		{
			land = m_lands[y * m_width + x] = new CLandscape(m_device, this, x * MAP_SIZE, y * MAP_SIZE);
			land->GetLayer(textureID);
		}
	}

	QImage image;
	if (!bitmap.isEmpty() && image.load(bitmap))
	{
		QTransform rot;
		rot.rotate(90);
		image = image.transformed(rot);
		for (y = 0; y < m_height; y++)
		{
			for (x = 0; x < m_width; x++)
			{
				land = m_lands[y * m_width + x];
				for (x2 = 0; x2 < (MAP_SIZE + 1); x2++)
				{
					for (y2 = 0; y2 < (MAP_SIZE + 1); y2++)
					{
						land->m_heightMap[x2 *(MAP_SIZE + 1) + y2] = QColor(image.pixel(
							(int)(((float)(x2 + y * MAP_SIZE) / (float)(m_height * MAP_SIZE)) * (float)image.width()),
							(int)(((float)(y2 + x * MAP_SIZE) / (float)(m_width * MAP_SIZE)) * (float)image.height())
							)).redF() * heightMap;
					}
				}
			}
		}
	}
	else
	{
		for (y = 0; y < m_height; y++)
		{
			for (x = 0; x < m_width; x++)
			{
				land = m_lands[y * m_width + x];
				for (i = 0; i < (MAP_SIZE + 1) * (MAP_SIZE + 1); i++)
					land->m_heightMap[i] = heightMap;
			}
		}
	}
}
Example #6
0
void KWidget::setzRotateAngle( qreal angle )
{
    QTransform t = transform();
    setTransform(t.rotate(angle, Qt::ZAxis));
}
Example #7
0
void CanvasMode_EditArc::applyValues(double start, double end, double height, double width)
{
	PageItem *currItem = m_doc->m_Selection->itemAt(0);
	QRectF oldR = currItem->getBoundingRect().adjusted(-5, -5, 10, 10);
	PageItem_Arc *item = currItem->asArc();
	QTransform bb;
	bb.scale(height / width, 1.0);
	QLineF inp = QLineF(QPointF(width / 2.0, height / 2.0), QPointF(width, height / 2.0));
	inp.setAngle(start);
	QLineF res = bb.map(inp);
	inp.setAngle(end);
	QLineF ena = bb.map(inp);
	m_startAngle = res.angle();
	m_endAngle = ena.angle();
	double nSweep = m_endAngle - m_startAngle;
	if (nSweep < 0)
		nSweep += 360;
	double oldX = currItem->xPos();
	double oldY = currItem->yPos();
	double newX = oldX + m_centerPoint.x() - (width / 2.0);
	double newY = oldY + m_centerPoint.y() - (height / 2.0);
	item->setXYPos(newX, newY, true);
	FPointArray old = item->PoLine;
	QPainterPath pp;
	pp.moveTo(width / 2.0, height / 2.0);
	pp.arcTo(QRectF(0, 0, width, height), m_startAngle, nSweep);
	pp.closeSubpath();
	currItem->PoLine.fromQPainterPath(pp, true);
	FPoint wh = getMaxClipF(&currItem->PoLine);
	currItem->setWidthHeight(wh.x(),wh.y());
	m_doc->adjustItemSize(currItem);
	currItem->OldB2 = currItem->width();
	currItem->OldH2 = currItem->height();
	if (UndoManager::undoEnabled())
	{
		ScItemState<QPair<FPointArray, FPointArray> > *ss = new ScItemState<QPair<FPointArray, FPointArray> >(Um::EditArc,"",Um::IPolygon);
		ss->set("ARC");
		ss->set("OLD_WIDTH",item->arcWidth);
		ss->set("NEW_WIDTH",width);
		ss->set("OLD_XPOS",oldX);
		ss->set("OLD_YPOS",oldY);
		ss->set("OLD_HEIGHT",item->arcHeight);
		ss->set("NEW_HEIGHT",height);
		ss->set("OLD_START",item->arcStartAngle);
		ss->set("NEW_START",m_startAngle);
		ss->set("OLD_SWEEP",item->arcSweepAngle);
		ss->set("NEW_SWEEP",nSweep);
		ss->setItem(qMakePair(old,item->PoLine));
		ss->set("NEW_XPOS",item->xPos());
		ss->set("NEW_YPOS",item->yPos());
		undoManager->action(currItem,ss);
	}
	item->arcStartAngle = m_startAngle;
	item->arcSweepAngle = nSweep;
	item->arcWidth = width;
	item->arcHeight = height;
	m_startPoint = currItem->PoLine.pointQF(2);
	m_endPoint = currItem->PoLine.pointQF(currItem->PoLine.size() - 4);
	m_centerPoint = currItem->PoLine.pointQF(0);
	m_widthPoint = QPointF(m_centerPoint.x() - item->arcWidth / 2.0, m_centerPoint.y());
	m_heightPoint = QPointF(m_centerPoint.x(), m_centerPoint.y() - item->arcHeight / 2.0);
	m_doc->setRedrawBounding(currItem);
	QRectF newR(currItem->getBoundingRect());
	m_doc->regionsChanged()->update(newR.united(oldR));

//	QTransform itemMatrix = currItem->getTransform();
//	m_doc->regionsChanged()->update(itemMatrix.mapRect(QRectF(0, 0, currItem->width(), currItem->height())).adjusted(-currItem->width() / 2.0, -currItem->height() / 2.0, currItem->width(), currItem->height()));
}
Example #8
0
QPointF Body::toLocal( const QPointF& p ) const {
    QTransform transform;
    //transform.translate(-position().x(),-position().y());
    transform.rotateRadians(-angle());
    return transform.map(p-position());
}
// --------------------------------------------------------
void TouchWidgetRenderer::drawResizers(
	GLResourceContainer * container,
	const SceneTouchPoint * resizing_point,
	const QPointF & circle_center,
	float circle_radius,
	const QPointF & base_target,
	QList<float> resizer_angles ) const
{
	static Warping<qreal> resizer_activeness(0.0f, 0.2f);
	static bool resizer_active = false;
	static QPointF last_resizer_pos;
	static float touch_angle_target = 0;

	QPointF base_pos = QLineF(circle_center, base_target).unitVector().pointAt(circle_radius);
	float base_angle = QLineF(base_target, circle_center).angleTo(QLineF(0,0,1,0));

	// trigger the warp towards 1 or 0 if the status just changed and evaluate it
	if((resizing_point != NULL) != resizer_active)
	{
		resizer_active = (resizing_point != NULL);
		resizer_activeness.setTarget(resizer_active ? 1.0f : 0.0f);
	}
	float activeness = resizer_activeness.value();

	// update resizer position and angle based on current touch
	if(resizer_active)
	{
		last_resizer_pos = resizing_point->pos();
		touch_angle_target = QLineF(last_resizer_pos, circle_center).angleTo(QLineF(0,0,1,0));;

		touch_angle_target += 60;
		while(touch_angle_target>120) touch_angle_target-=120;
		while(touch_angle_target<-120) touch_angle_target+=120;
		touch_angle_target -= 60;
	}

	// compute resizer size
	const float resizer_diameter = 0.3f * circle_radius * (activeness*0.5+1);
	QSizeF resizer_size(resizer_diameter, resizer_diameter);

	// draw individual angles
	foreach(float resizer_angle, resizer_angles)
	{
		// compute desired angle
		float blended_angle = (touch_angle_target+resizer_angle)*activeness + resizer_angle*(1-activeness);

		// compute resizer handle location
		QTransform transform;
		transform.translate(circle_center.x(), circle_center.y());
		transform.rotate(blended_angle);
		transform.translate(-circle_center.x(), -circle_center.y());
		QPointF resizer_pos = transform.map(base_pos);

		// draw resizer handle
		if(activeness < 1)
		{
			drawTexturedQuad(container->texture("mglass_resizer"), resizer_pos, resizer_size, blended_angle+base_angle+180);
		}
		if(activeness > 0)
		{
			drawTexturedQuad(container->texture("mglass_resizer_active"), resizer_pos, resizer_size, blended_angle+base_angle+180, activeness);
		}
	}
Example #10
0
void QgsComposerItem::changeItemRectangle( const QPointF& currentPosition,
    const QPointF& mouseMoveStartPos,
    const QGraphicsRectItem* originalItem,
    double dx, double dy,
    QGraphicsRectItem* changeItem )
{
  Q_UNUSED( dx );
  Q_UNUSED( dy );
  if ( !changeItem || !originalItem || !mComposition )
  {
    return;
  }

  //test if change item is a composer item. If so, prefer call to  setSceneRect() instead of setTransform() and setRect()
  QgsComposerItem* changeComposerItem = dynamic_cast<QgsComposerItem *>( changeItem );

  double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
  QPointF snappedPosition = mComposition->snapPointToGrid( currentPosition );
  //double diffX = snappedPosition.x() - mouseMoveStartPos.x();
  //double diffY = snappedPosition.y() - mouseMoveStartPos.y();
  double diffX = 0;
  double diffY = 0;

  switch ( mCurrentMouseMoveAction )
  {
      //vertical resize
    case QgsComposerItem::ResizeUp:
      diffY = snappedPosition.y() - originalItem->transform().dy();
      mx = 0; my = diffY; rx = 0; ry = -diffY;
      break;

    case QgsComposerItem::ResizeDown:
      diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
      mx = 0; my = 0; rx = 0; ry = diffY;
      break;

      //horizontal resize
    case QgsComposerItem::ResizeLeft:
      diffX = snappedPosition.x() - originalItem->transform().dx();
      mx = diffX, my = 0; rx = -diffX; ry = 0;
      break;

    case QgsComposerItem::ResizeRight:
      diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
      mx = 0; my = 0; rx = diffX, ry = 0;
      break;

      //diagonal resize
    case QgsComposerItem::ResizeLeftUp:
      diffX = snappedPosition.x() - originalItem->transform().dx();
      diffY = snappedPosition.y() - originalItem->transform().dy();
      mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
      break;

    case QgsComposerItem::ResizeRightDown:
      diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
      diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
      mx = 0; my = 0; rx = diffX, ry = diffY;
      break;

    case QgsComposerItem::ResizeRightUp:
      diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
      diffY = snappedPosition.y() - originalItem->transform().dy();
      mx = 0; my = diffY, rx = diffX, ry = -diffY;
      break;

    case QgsComposerItem::ResizeLeftDown:
      diffX = snappedPosition.x() - originalItem->transform().dx();
      diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
      mx = diffX, my = 0; rx = -diffX; ry = diffY;
      break;

    case QgsComposerItem::MoveItem:
    {
      //calculate total move difference
      double moveX = currentPosition.x() - mouseMoveStartPos.x();
      double moveY = currentPosition.y() - mouseMoveStartPos.y();

      QPointF upperLeftPoint( originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY );
      QPointF snappedLeftPoint = mComposition->snapPointToGrid( upperLeftPoint );

      double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx();
      double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy();

      if ( !changeComposerItem )
      {
        QTransform moveTransform;
        moveTransform.translate( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY );
        changeItem->setTransform( moveTransform );
      }
      else  //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group)
      {
        changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + moveRectX,
                                          originalItem->transform().dy() + moveRectY,
                                          originalItem->rect().width(), originalItem->rect().height() ) );
        changeComposerItem->updateItem();
      }
    }
    return;
    case QgsComposerItem::NoAction:
      break;
  }

  if ( !changeComposerItem )
  {
    QTransform itemTransform;
    itemTransform.translate( originalItem->transform().dx() + mx, originalItem->transform().dy() + my );
    changeItem->setTransform( itemTransform );
    QRectF itemRect( 0, 0, originalItem->rect().width() + rx,  originalItem->rect().height() + ry );
    changeItem->setRect( itemRect );
  }
  else //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group)
  {
    changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + mx, originalItem->transform().dy() + my,
                                      originalItem->rect().width() + rx, originalItem->rect().height() + ry ) );
    changeComposerItem->updateItem();
  }
}
Example #11
0
QPointF Body::fromLocal( const QPointF& p ) const {
    QTransform transform;
    transform.translate(position().x(),position().y());
    transform.rotateRadians(-angle());
    return transform.map(p);
}
Example #12
0
void BI_FootprintPad::updateGraphicsItemTransform() noexcept {
  QTransform t;
  if (mFootprint.getIsMirrored()) t.scale(qreal(-1), qreal(1));
  t.rotate(-mRotation.toDeg());
  mGraphicsItem->setTransform(t);
}
void QSanSelectableItem::scaleSmoothly(qreal ratio) {
    QTransform trans = transform();
    trans.scale(ratio, ratio);
    setTransform(trans);
}
Example #14
0
void KisColorSelector::drawLightStrip(QPainter& painter, const QRect& rect)
{
    bool     isVertical = true;
    qreal    penSize    = qreal(qMin(QWidget::width(), QWidget::height())) / 200.0;
    KisColor color(m_selectedColor);
    
    painter.resetTransform();
    
    if (getNumLightPieces() > 1) {
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(QBrush(Qt::red), penSize));
        
        QTransform matrix;
        matrix.translate(rect.x(), rect.y());
        matrix.scale(rect.width(), rect.height());
        
        for(int i=0; i<getNumLightPieces(); ++i) {
            float  t1    = float(i)   / float(getNumLightPieces());
            float  t2    = float(i+1) / float(getNumLightPieces());
            float  light = 1.0f - (float(i) / float(getNumLightPieces()-1));
            float  diff  = t2 - t1;// + 0.001;
            QRectF r     = isVertical ? QRectF(0.0, t1, 1.0, diff) : QRect(t1, 0.0, diff, 1.0);
            
            color.setX(getLight(light, color.getH(), m_relativeLight));
            
            r = matrix.mapRect(r);
            painter.fillRect(r, color.getQColor());
            
            if (i == m_selectedLightPiece)
                painter.drawRect(r);
        }
    }
    else {
        int size = isVertical ? rect.height() : rect.width();
        painter.setRenderHint(QPainter::Antialiasing, false);
        
        if (isVertical) {
            for(int i=0; i<size; ++i) {
                int   y     = rect.y() + i;
                float light = 1.0f - (float(i) / float(size-1));
                color.setX(getLight(light, color.getH(), m_relativeLight));
                painter.setPen(color.getQColor());
                painter.drawLine(rect.left(), y, rect.right(), y);
            }
        }
        else {
            for(int i=0; i<size; ++i) {
                int   x     = rect.x() + i;
                float light = 1.0f - (float(i) / float(size-1));
                color.setX(getLight(light, color.getH(), m_relativeLight));
                painter.setPen(color.getQColor());
                painter.drawLine(x, rect.top(), x, rect.bottom());
            }
        }
        
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(QBrush(Qt::red), penSize));
        float t = 1.0f - m_light;
        
        if (isVertical) {
            int y = rect.y() + int(size * t);
            painter.drawLine(rect.left(), y, rect.right(), y);
        }
        else {
            int x = rect.x() + int(size * t);
            painter.drawLine(x, rect.top(), x, rect.bottom());
        }
    }
}
qreal KisTransformUtils::scaleFromPerspectiveMatrix(const QTransform &t, const QPointF &basePt) {
    const QRectF testRect(basePt, QSizeF(1.0, 1.0));
    QRectF resultRect = t.mapRect(testRect);

    return 0.5 * (resultRect.width(), resultRect.height());
}
Example #16
0
void KMultiTabBarTab::paintEvent(QPaintEvent*) {
	QPainter painter(this);

	QStyleOptionToolButton opt;
	initStyleOption(&opt);

	// Paint bevel..
	if (underMouse() || isChecked()) {
		opt.text.clear();
		opt.icon = QIcon();
		style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &painter, this);
	}

	int hMargin, vMargin;
	computeMargins(&hMargin, &vMargin);

	// We first figure out how much room we have for the text, based on
	// icon size and margin, try to fit in by eliding, and perhaps
	// give up on drawing the text entirely if we're too short on room
	QPixmap icon = iconPixmap();
	int textRoom = 0;
	int iconRoom = 0;

	QString t;
	if (shouldDrawText()) {
		if (isVertical()) {
			iconRoom = icon.height() + 2*vMargin;
			textRoom = height() - iconRoom - vMargin;
		} else {
			iconRoom = icon.width() + 2*hMargin;
			textRoom = width() - iconRoom - hMargin;
		}

		t = painter.fontMetrics().elidedText(text(), Qt::ElideRight, textRoom);

		// See whether anything is left. Qt will return either
		// ... or the ellipsis unicode character, 0x2026
		if (t == QLatin1String("...") || t == QChar(0x2026))
			t.clear();
	}

	// Label time.... Simple case: no text, so just plop down the icon right in the center
	// We only do this when the button never draws the text, to avoid jumps in icon position
	// when resizing
 	if (!shouldDrawText()) {
 		style()->drawItemPixmap(&painter, rect(), Qt::AlignCenter | Qt::AlignVCenter, icon);
 		return;
 	}

	// Now where the icon/text goes depends on text direction and tab position
	QRect iconArea;
	QRect labelArea;

	bool bottomIcon = false;
	bool rtl = layoutDirection() == Qt::RightToLeft;
	if (isVertical()) {
		if (m_position == KMultiTabBar::Left && !rtl)
			bottomIcon = true;
		if (m_position == KMultiTabBar::Right && rtl)
			bottomIcon = true;
	}
	//alignFlags = Qt::AlignLeading | Qt::AlignVCenter;

	if (isVertical()) {
		if (bottomIcon) {
			labelArea = QRect(0, vMargin, width(), textRoom);
			iconArea  = QRect(0, vMargin + textRoom, width(), iconRoom);
		} else {
			labelArea = QRect(0, iconRoom, width(), textRoom);
			iconArea  = QRect(0, 0, width(), iconRoom);
		}
	} else {
		// Pretty simple --- depends only on RTL/LTR
		if (rtl) {
			labelArea = QRect(hMargin, 0, textRoom, height());
			iconArea  = QRect(hMargin + textRoom, 0, iconRoom, height());
		} else {
			labelArea = QRect(iconRoom, 0, textRoom, height());
			iconArea  = QRect(0, 0, iconRoom, height());
		}
	}

	style()->drawItemPixmap(&painter, iconArea, Qt::AlignCenter | Qt::AlignVCenter, icon);

	if (t.isEmpty())
		return;

	QRect labelPaintArea = labelArea;

	if (isVertical()) {
		// If we're vertical, we paint to a simple 0,0 origin rect,
		// and get the transformations to get us in the right place
		labelPaintArea = QRect(0, 0, labelArea.height(), labelArea.width());

		QTransform tr;

		if (bottomIcon) {
			tr.translate(labelArea.x(), labelPaintArea.width() + labelArea.y());
			tr.rotate(-90);
		} else {
			tr.translate(labelPaintArea.height() + labelArea.x(), labelArea.y());
			tr.rotate(90);
		}
		painter.setTransform(tr);
	}

	style()->drawItemText(&painter, labelPaintArea, Qt::AlignLeading | Qt::AlignVCenter,
	                      palette(), true, t, QPalette::ButtonText);
}
Example #17
0
void AbstractDiagram::Private::addLabel(
    LabelPaintCache* cache,
    const QModelIndex& index,
    const CartesianDiagramDataCompressor::CachePosition* position,
    const PositionPoints& points,
    const Position& autoPositionPositive, const Position& autoPositionNegative,
    const qreal value, qreal favoriteAngle /* = 0.0 */ )
{
    CartesianDiagramDataCompressor::AggregatedDataValueAttributes allAttrs(
        aggregatedAttrs( index, position ) );

    QMap<QModelIndex, DataValueAttributes>::const_iterator it;
    for ( it = allAttrs.constBegin(); it != allAttrs.constEnd(); ++it ) {
        DataValueAttributes dva = it.value();
        if ( !dva.isVisible() ) {
            continue;
        }

        const bool isPositive = ( value >= 0.0 );

        RelativePosition relPos( dva.position( isPositive ) );
        relPos.setReferencePoints( points );
        if ( relPos.referencePosition().isUnknown() ) {
            relPos.setReferencePosition( isPositive ? autoPositionPositive : autoPositionNegative );
        }

        // Rotate the label position (not the label itself) if the diagram is rotated so that the defaults still work
        if ( isTransposed() ) {
            KChartEnums::PositionValue posValue = relPos.referencePosition().value();
            if ( posValue >= KChartEnums::PositionNorthWest && posValue <= KChartEnums::PositionWest ) {
                // rotate 90 degrees clockwise
                posValue = static_cast< KChartEnums::PositionValue >( posValue + 2 );
                if ( posValue > KChartEnums::PositionWest ) {
                    // wraparound
                    posValue = static_cast< KChartEnums::PositionValue >( posValue -
                                ( KChartEnums::PositionWest - KChartEnums::PositionNorthWest ) );
                }
                relPos.setReferencePosition( Position( posValue ) );
            }
        }

        const QPointF referencePoint = relPos.referencePoint();
        if ( !diagram->coordinatePlane()->isVisiblePoint( referencePoint ) ) {
            continue;
        }

        const qreal fontHeight = cachedFontMetrics( dva.textAttributes().
                calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ), diagram )->height();

        // Note: When printing data value texts and padding's Measure is using automatic reference area
        //       detection, the font height is used as reference size for both horizontal and vertical
        //       padding.
        QSizeF relativeMeasureSize( fontHeight, fontHeight );

        if ( !dva.textAttributes().hasRotation() ) {
            TextAttributes ta = dva.textAttributes();
            ta.setRotation( favoriteAngle );
            dva.setTextAttributes( ta );
        }

        // get the size of the label text using a subset of the information going into the final layout
        const QString text = formatDataValueText( dva, index, value );
        QTextDocument doc;
        doc.setDocumentMargin( 0 );
        if ( Qt::mightBeRichText( text ) ) {
            doc.setHtml( text );
        } else {
            doc.setPlainText( text );
        }
        const QFont calculatedFont( dva.textAttributes()
                                    .calculatedFont( plane, KChartEnums::MeasureOrientationMinimum ) );
        doc.setDefaultFont( calculatedFont );

        const QRectF plainRect = doc.documentLayout()->frameBoundingRect( doc.rootFrame() );

        /**
        * A few hints on how the positioning of the text frame is done:
        *
        * Let's assume we have a bar chart, a text for a positive value
        * to be drawn, and "North" as attrs.positivePosition().
        *
        * The reference point (pos) is then set to the top center point
        * of a bar. The offset now depends on the alignment:
        *
        *    Top: text is centered horizontally to the bar, bottom of
        *         text frame starts at top of bar
        *
        *    Bottom: text is centered horizontally to the bar, top of
        *            text frame starts at top of bar
        *
        *    Center: text is centered horizontally to the bar, center
        *            line of text frame is same as top of bar
        *
        *    TopLeft: right edge of text frame is horizontal center of
        *             bar, bottom of text frame is top of bar.
        *
        *    ...
        *
        * Positive and negative value labels are treated equally, "North"
        * also refers to the top of a negative bar, and *not* to the bottom.
        *
        *
        * "NorthEast" likewise refers to the top right edge of the bar,
        * "NorthWest" to the top left edge of the bar, and so on.
        *
        * In other words, attrs.positivePosition() always refers to a
        * position of the *bar*, and relPos.alignment() always refers
        * to an alignment of the text frame relative to this position.
        */

        QTransform transform;
        {
            // move to the general area where the label should be
            QPointF calcPoint = relPos.calculatedPoint( relativeMeasureSize );
            transform.translate( calcPoint.x(), calcPoint.y() );
            // align the text rect; find out by how many half-widths / half-heights to move.
            int dx = -1;
            if ( relPos.alignment() & Qt::AlignLeft ) {
                dx -= 1;
            } else if ( relPos.alignment() & Qt::AlignRight ) {
                 dx += 1;
            }

            int dy = -1;
            if ( relPos.alignment() & Qt::AlignTop ) {
                dy -= 1;
            } else if ( relPos.alignment() & Qt::AlignBottom ) {
                dy += 1;
            }
            transform.translate( qreal( dx ) * plainRect.width() * 0.5,
                                 qreal( dy ) * plainRect.height() * 0.5 );

            // rotate the text rect around its center
            transform.translate( plainRect.center().x(), plainRect.center().y() );
            int rotation = dva.textAttributes().rotation();
            if ( !isPositive && dva.mirrorNegativeValueTextRotation() ) {
                rotation *= -1;
            }
            transform.rotate( rotation );
            transform.translate( -plainRect.center().x(), -plainRect.center().y() );
        }

        QPainterPath labelArea;
        //labelArea.addPolygon( transform.mapToPolygon( plainRect.toRect() ) );
        //labelArea.closeSubpath();
        // Not doing that because QTransform has a special case for 180° that gives a different than
        // usual ordering of the points in the polygon returned by mapToPolygon( const QRect & ).
        // We expect a particular ordering in paintDataValueTextsAndMarkers() by using elementAt( 0 ),
        // and similar things might happen elsewhere.
        labelArea.addPolygon( transform.map( QPolygon( plainRect.toRect(), true ) ) );

        // store the label geometry and auxiliary data
        cache->paintReplay.append( LabelPaintInfo( it.key(), dva, labelArea,
                                                   referencePoint, value >= 0.0, text ) );
    }
}
Example #18
0
bool QPaintEngineEx::shouldDrawCachedGlyphs(qreal pixelSize, const QTransform &m) const
{
    return (pixelSize * pixelSize * qAbs(m.determinant())) <
           QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE;
}
Example #19
0
void HairpinSegment::layout()
      {
      if (hairpin()->useTextLine()) {
            // layout as textline rather than true hairpin
            // use dynamics text style for position, so the text aligns with dynamics
            // TODO: new style setting specifically for vertical offset of textline hairpins?
            // or, use hairpinY but adjust by 0.5sp, which currently yields same vertical position as dynamics
            if (parent())
                  rypos() += score()->textStyle(TextStyleType::DYNAMICS).offset(spatium()).y();
            TextLineSegment::layout();
            return;
            }

      QTransform t;
      qreal _spatium = spatium();
      qreal h1 = hairpin()->hairpinHeight().val() * spatium() * .5;
      qreal h2 = hairpin()->hairpinContHeight().val() * spatium() * .5;

      qreal len;
      qreal x = pos2().x();
      if (x < _spatium)             // minimum size of hairpin
            x = _spatium;
      qreal y = pos2().y();
      len     = sqrt(x * x + y * y);
      t.rotateRadians(asin(y/len));

      drawCircledTip =  hairpin()->hairpinCircledTip();
      circledTipRadius = 0;
      if( drawCircledTip )
        circledTipRadius  = 0.6 * _spatium * .5;
      if (hairpin()->hairpinType() == Hairpin::Type::CRESCENDO) {
            // crescendo
            switch (spannerSegmentType()) {
                  case SpannerSegmentType::SINGLE:
                  case SpannerSegmentType::BEGIN:
                        l1.setLine(.0 + circledTipRadius*2, .0, len, h1);
                        l2.setLine(.0 + circledTipRadius*2, .0, len, -h1);
                        circledTip.setX( 0 + circledTipRadius );
                        circledTip.setY( 0 );
                        break;
                  case SpannerSegmentType::MIDDLE:
                  case SpannerSegmentType::END:
                        drawCircledTip = false;
                        l1.setLine(.0,  h2, len, h1);
                        l2.setLine(.0, -h2, len, -h1);
                        break;
                  }
            }
      else {
            // decrescendo
            switch(spannerSegmentType()) {
                  case SpannerSegmentType::SINGLE:
                  case SpannerSegmentType::END:
                        l1.setLine(.0,  h1, len - circledTipRadius*2, 0.0);
                        l2.setLine(.0, -h1, len - circledTipRadius*2, 0.0);
                        circledTip.setX( len - circledTipRadius );
                        circledTip.setY( 0 );
                        break;
                  case SpannerSegmentType::BEGIN:
                  case SpannerSegmentType::MIDDLE:
                        drawCircledTip = false;
                        l1.setLine(.0,  h1, len, + h2);
                        l2.setLine(.0, -h1, len, - h2);
                        break;
                  }
            }
// Do Coord rotation
      l1 = t.map(l1);
      l2 = t.map(l2);
      if( drawCircledTip )
        circledTip = t.map(circledTip);


      QRectF r = QRectF(l1.p1(), l1.p2()).normalized() | QRectF(l2.p1(), l2.p2()).normalized();
      qreal w = point(score()->styleS(StyleIdx::hairpinLineWidth));
      setbbox(r.adjusted(-w*.5, -w*.5, w, w));
      if (parent())
            rypos() += score()->styleS(StyleIdx::hairpinY).val() * _spatium;
      adjustReadPos();
      }
Example #20
0
/*!
    \brief Replay all recorded painter commands

    The graphic is scaled to fit into the given rectangle

    \param painter Qt painter
    \param rect Rectangle for the scaled graphic
    \param aspectRatioMode Mode how to scale - See Qt::AspectRatioMode
 */
void QwtGraphic::render( QPainter *painter, const QRectF &rect, 
    Qt::AspectRatioMode aspectRatioMode ) const
{
    if ( isEmpty() || rect.isEmpty() )
        return;

    double sx = 1.0; 
    double sy = 1.0;

    if ( d_data->pointRect.width() > 0.0 )
        sx = rect.width() / d_data->pointRect.width();

    if ( d_data->pointRect.height() > 0.0 )
        sy = rect.height() / d_data->pointRect.height();

    const bool scalePens = 
        !d_data->renderHints.testFlag( RenderPensUnscaled );

    for ( int i = 0; i < d_data->pathInfos.size(); i++ )
    {
        const PathInfo info = d_data->pathInfos[i];

        const double ssx = info.scaleFactorX( 
            d_data->pointRect, rect, scalePens );

        if ( ssx > 0.0 )
            sx = qMin( sx, ssx );

        const double ssy = info.scaleFactorY( 
            d_data->pointRect, rect, scalePens );

        if ( ssy > 0.0 )
            sy = qMin( sy, ssy );
    }

    if ( aspectRatioMode == Qt::KeepAspectRatio )
    {
        const double s = qMin( sx, sy );
        sx = s;
        sy = s;
    }
    else if ( aspectRatioMode == Qt::KeepAspectRatioByExpanding )
    {
        const double s = qMax( sx, sy );
        sx = s;
        sy = s;
    }

    QTransform tr;
    tr.translate( rect.center().x() - 0.5 * sx * d_data->pointRect.width(),
        rect.center().y() - 0.5 * sy * d_data->pointRect.height() );
    tr.scale( sx, sy );
    tr.translate( -d_data->pointRect.x(), -d_data->pointRect.y() );

    const QTransform transform = painter->transform();

    painter->setTransform( tr, true );
    render( painter );

    painter->setTransform( transform );
}
Example #21
0
void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
    Q_D(QDeclarativeImage);
    if (d->pix.pixmap().isNull() )
        return;

    int drawWidth = width();
    int drawHeight = height();
    bool doClip = false;
    QTransform transform;
    qreal widthScale = width() / qreal(d->pix.width());
    qreal heightScale = height() / qreal(d->pix.height());

    if (width() != d->pix.width() || height() != d->pix.height()) {
        if (d->fillMode >= Tile) {
            if (d->fillMode == TileVertically) {
                transform.scale(widthScale, 1.0);
                drawWidth = d->pix.width();
            } else if (d->fillMode == TileHorizontally) {
                transform.scale(1.0, heightScale);
                drawHeight = d->pix.height();
            }
        } else {
            if (d->fillMode == PreserveAspectFit) {
                if (widthScale <= heightScale) {
                    heightScale = widthScale;
                    transform.translate(0, (height() - heightScale * d->pix.height()) / 2);
                } else if(heightScale < widthScale) {
                    widthScale = heightScale;
                    transform.translate((width() - widthScale * d->pix.width()) / 2, 0);
                }
            } else if (d->fillMode == PreserveAspectCrop) {
                if (widthScale < heightScale) {
                    widthScale = heightScale;
                    transform.translate((width() - widthScale * d->pix.width()) / 2, 0);
                } else if(heightScale < widthScale) {
                    heightScale = widthScale;
                    transform.translate(0, (height() - heightScale * d->pix.height()) / 2);
                }
            }
            transform.scale(widthScale, heightScale);
            drawWidth = d->pix.width();
            drawHeight = d->pix.height();
            doClip = clip();
        }
    }

    QTransform oldTransform;
    bool oldAA = p->testRenderHint(QPainter::Antialiasing);
    bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
    if (d->smooth)
        p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
    if (doClip) {
        p->save();
        p->setClipRect(QRectF(0, 0, d->mWidth, d->mHeight), Qt::IntersectClip);
    }
    if (d->mirror)
        transform.translate(drawWidth, 0).scale(-1.0, 1.0);
    if (!transform.isIdentity()) {
        oldTransform = p->transform();
        p->setWorldTransform(transform * oldTransform);
    }

    if (d->fillMode >= Tile)
        p->drawTiledPixmap(QRectF(0, 0, drawWidth, drawHeight), d->pix);
    else
        p->drawPixmap(QRectF(0, 0, drawWidth, drawHeight), d->pix, QRectF(0, 0, drawWidth, drawHeight));

    if (d->smooth) {
        p->setRenderHint(QPainter::Antialiasing, oldAA);
        p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
    }
    if (doClip)
        p->restore();
    if (!transform.isIdentity())
        p->setWorldTransform(oldTransform);
}
Example #22
0
static inline void qwtExecCommand( 
    QPainter *painter, const QwtPainterCommand &cmd, 
    QwtGraphic::RenderHints renderHints,
    const QTransform &transform )
{
    switch( cmd.type() )
    {
        case QwtPainterCommand::Path:
        {
            bool doMap = false;

            if ( renderHints.testFlag( QwtGraphic::RenderPensUnscaled )
                && painter->transform().isScaling() )
            {
                bool isCosmetic = painter->pen().isCosmetic();
                if ( isCosmetic && painter->pen().widthF() == 0.0 )
                {
                    QPainter::RenderHints hints = painter->renderHints();
                    if ( hints.testFlag( QPainter::NonCosmeticDefaultPen ) )
                        isCosmetic = false;
                }

                doMap = !isCosmetic;
            }

            if ( doMap )
            {
                const QTransform transform = painter->transform();

                painter->resetTransform();
                painter->drawPath( transform.map( *cmd.path() ) );

                painter->setTransform( transform );
            }
            else
            {
                painter->drawPath( *cmd.path() );
            }
            break;
        }
        case QwtPainterCommand::Pixmap:
        {
            const QwtPainterCommand::PixmapData *data = cmd.pixmapData();
            painter->drawPixmap( data->rect, data->pixmap, data->subRect );
            break;
        }
        case QwtPainterCommand::Image:
        {
            const QwtPainterCommand::ImageData *data = cmd.imageData();
            painter->drawImage( data->rect, data->image, 
                data->subRect, data->flags );
            break;
        }
        case QwtPainterCommand::State:
        {
            const QwtPainterCommand::StateData *data = cmd.stateData();

            if ( data->flags & QPaintEngine::DirtyPen ) 
                painter->setPen( data->pen );

            if ( data->flags & QPaintEngine::DirtyBrush ) 
                painter->setBrush( data->brush );

            if ( data->flags & QPaintEngine::DirtyBrushOrigin ) 
                painter->setBrushOrigin( data->brushOrigin );

            if ( data->flags & QPaintEngine::DirtyFont ) 
                painter->setFont( data->font );

            if ( data->flags & QPaintEngine::DirtyBackground ) 
            {
                painter->setBackgroundMode( data->backgroundMode );
                painter->setBackground( data->backgroundBrush );
            }

            if ( data->flags & QPaintEngine::DirtyTransform ) 
            {
                painter->setTransform( data->transform * transform );
            }

            if ( data->flags & QPaintEngine::DirtyClipEnabled ) 
                painter->setClipping( data->isClipEnabled );

            if ( data->flags & QPaintEngine::DirtyClipRegion) 
            {
                painter->setClipRegion( data->clipRegion, 
                    data->clipOperation );
            }

            if ( data->flags & QPaintEngine::DirtyClipPath ) 
            {
                painter->setClipPath( data->clipPath, data->clipOperation );
            }

            if ( data->flags & QPaintEngine::DirtyHints) 
            {
                const QPainter::RenderHints hints = data->renderHints;

                painter->setRenderHint( QPainter::Antialiasing,
                    hints.testFlag( QPainter::Antialiasing ) );

                painter->setRenderHint( QPainter::TextAntialiasing,
                    hints.testFlag( QPainter::TextAntialiasing ) );

                painter->setRenderHint( QPainter::SmoothPixmapTransform,
                    hints.testFlag( QPainter::SmoothPixmapTransform ) );

                painter->setRenderHint( QPainter::HighQualityAntialiasing,
                    hints.testFlag( QPainter::HighQualityAntialiasing ) );

                painter->setRenderHint( QPainter::NonCosmeticDefaultPen,
                    hints.testFlag( QPainter::NonCosmeticDefaultPen ) );
            }

            if ( data->flags & QPaintEngine::DirtyCompositionMode) 
                painter->setCompositionMode( data->compositionMode );

            if ( data->flags & QPaintEngine::DirtyOpacity) 
                painter->setOpacity( data->opacity );

            break;
        }
        default:
            break;
    }

}
Example #23
0
void AbstractContent::toXml(QDomElement & pe) const
{
    // Save general item properties
    pe.setTagName("abstract");
    QDomDocument doc = pe.ownerDocument();
    QDomElement domElement;
    QDomText text;
    QString valueStr;

    // Save item position and size
    QDomElement rectParent = doc.createElement("rect");
    QDomElement xElement = doc.createElement("x");
    rectParent.appendChild(xElement);
    QDomElement yElement = doc.createElement("y");
    rectParent.appendChild(yElement);
    QDomElement wElement = doc.createElement("w");
    rectParent.appendChild(wElement);
    QDomElement hElement = doc.createElement("h");
    rectParent.appendChild(hElement);

    QRectF rect = m_contentsRect;
    xElement.appendChild(doc.createTextNode(QString::number(rect.left())));
    yElement.appendChild(doc.createTextNode(QString::number(rect.top())));
    wElement.appendChild(doc.createTextNode(QString::number(rect.width())));
    hElement.appendChild(doc.createTextNode(QString::number(rect.height())));
    pe.appendChild(rectParent);

    // Save the position
    domElement= doc.createElement("pos");
    xElement = doc.createElement("x");
    yElement = doc.createElement("y");
    valueStr.setNum(pos().x());
    xElement.appendChild(doc.createTextNode(valueStr));
    valueStr.setNum(pos().y());
    yElement.appendChild(doc.createTextNode(valueStr));
    domElement.appendChild(xElement);
    domElement.appendChild(yElement);
    pe.appendChild(domElement);

    // Save the stacking position
    domElement= doc.createElement("zvalue");
    pe.appendChild(domElement);
    valueStr.setNum(zValue());
    text = doc.createTextNode(valueStr);
    domElement.appendChild(text);

    // Save the visible state
    domElement= doc.createElement("visible");
    pe.appendChild(domElement);
    valueStr.setNum(isVisible());
    text = doc.createTextNode(valueStr);
    domElement.appendChild(text);

    // Save the frame class
    valueStr.setNum(frameClass());
    domElement= doc.createElement("frame-class");
    pe.appendChild(domElement);
    text = doc.createTextNode(valueStr);
    domElement.appendChild(text);

    domElement= doc.createElement("frame-text-enabled");
    pe.appendChild(domElement);
    valueStr.setNum(frameTextEnabled());
    text = doc.createTextNode(valueStr);
    domElement.appendChild(text);

    if(frameTextEnabled()) {
        domElement= doc.createElement("frame-text");
        pe.appendChild(domElement);
        text = doc.createTextNode(frameText());
        domElement.appendChild(text);
    }

    // save transformation
    const QTransform t = transform();
    if (!t.isIdentity()) {
        domElement = doc.createElement("transformation");
        domElement.setAttribute("xRot", m_xRotationAngle);
        domElement.setAttribute("yRot", m_yRotationAngle);
        domElement.setAttribute("zRot", m_zRotationAngle);
        pe.appendChild(domElement);
    }
}
Example #24
0
void XfigPlug::processArrows(int forward_arrow, QString fArrowData, int backward_arrow, QString bArrowData, int depth, PageItem *ite)
{
	int		arrow_typeAF;			// (enumeration type)
	int		arrow_styleAF;			// (enumeration type)
	float	arrow_thicknessAF;		// (1/80 inch)
	float	arrow_widthAF;			// (Fig units)
	float	arrow_heightAF;			// (Fig units)
	int		arrow_typeAB;			// (enumeration type)
	int		arrow_styleAB;			// (enumeration type)
	float	arrow_thicknessAB;		// (1/80 inch)
	float	arrow_widthAB;			// (Fig units)
	float	arrow_heightAB;			// (Fig units)
	FPointArray arrow;
	int z = -1;
	PageItem::ItemType iteType;
	if (forward_arrow == 1)
	{
		arrow.resize(0);
		ScTextStream CodeAF(&fArrowData, QIODevice::ReadOnly);
		CodeAF >> arrow_typeAF >> arrow_styleAF >> arrow_thicknessAF >> arrow_widthAF >> arrow_heightAF;
		arrow_widthAF = fig2Pts(arrow_widthAF);
		arrow_heightAF = fig2Pts(arrow_heightAF);
		arrow_thicknessAF = arrow_thicknessAF / 80.0 * 72.0;
		FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
		for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
		{
			FPoint Vector = ite->PoLine.point(xx);
			if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
			{
				double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
				QTransform arrowTrans;
				if (arrow_typeAF == 0)
					arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5");
				else if (arrow_typeAF == 1)
					arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 z");
				else if (arrow_typeAF == 2)
					arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 L -0.7 0 z");
				else if (arrow_typeAF == 3)
					arrow.parseSVG("M -0.7, -0.5 L 0, 0 L -0.7, 0.5 L -1 0 z");
				arrowTrans.translate(End.x(), End.y());
				arrowTrans.rotate(r);
				arrowTrans.scale(arrow_heightAF, arrow_widthAF);
				arrow.map(arrowTrans);
				break;
			}
		}
		QString fillC = "White";
		if (arrow_styleAF == 1)
			fillC = CurrColorStroke;
		if (arrow_typeAF == 0)
		{
			fillC = CommonStrings::None;
			iteType = PageItem::PolyLine;
		}
		else
			iteType = PageItem::Polygon;
		z = m_Doc->itemAdd(iteType, PageItem::Unspecified, ite->xPos(), ite->yPos(), 10, 10, arrow_thicknessAF, fillC, CurrColorStroke, true);
		if (z >= 0)
		{
			PageItem *item = m_Doc->Items->at(z);
			item->PoLine = arrow.copy();
			item->ClipEdited = true;
			item->FrameType = 3;
			item->setFillShade(CurrFillShade);
			item->setLineShade(CurrStrokeShade);
			FPoint wh = getMaxClipF(&item->PoLine);
			item->setWidthHeight(wh.x(),wh.y());
			item->setTextFlowMode(PageItem::TextFlowDisabled);
			m_Doc->AdjustItemSize(item);
			item->setWidthHeight(qMax(item->width(), 1.0), qMax(item->height(), 1.0));
			depthMap.insert(999 - depth, currentItemNr);
			currentItemNr++;
		}
	}
Example #25
0
bool RawIOHandler::read(QImage *image)
{
    if (!d->load(device())) return false;

    QSize finalSize = d->scaledSize.isValid() ?
        d->scaledSize : d->defaultSize;

    const libraw_data_t &imgdata = d->raw->imgdata;
    libraw_processed_image_t *output;
    if (finalSize.width() < imgdata.thumbnail.twidth ||
        finalSize.height() < imgdata.thumbnail.theight) {
        qDebug() << "Using thumbnail";
        d->raw->unpack_thumb();
        output = d->raw->dcraw_make_mem_thumb();
    } else {
        qDebug() << "Decoding raw data";
        d->raw->unpack();
        d->raw->dcraw_process();
        output = d->raw->dcraw_make_mem_image();
    }

    QImage unscaled;
    uchar *pixels = 0;
    if (output->type == LIBRAW_IMAGE_JPEG) {
        unscaled.loadFromData(output->data, output->data_size, "JPEG");
        if (imgdata.sizes.flip != 0) {
            QTransform rotation;
            int angle = 0;
            if (imgdata.sizes.flip == 3) angle = 180;
            else if (imgdata.sizes.flip == 5) angle = -90;
            else if (imgdata.sizes.flip == 6) angle = 90;
            if (angle != 0) {
                rotation.rotate(angle);
                unscaled = unscaled.transformed(rotation);
            }
        }
    } else {
        int numPixels = output->width * output->height;
        int colorSize = output->bits / 8;
        int pixelSize = output->colors * colorSize;
        pixels = new uchar[numPixels * 4];
        uchar *data = output->data;
        for (int i = 0; i < numPixels; i++, data += pixelSize) {
            if (output->colors == 3) {
                pixels[i * 4] = data[2 * colorSize];
                pixels[i * 4 + 1] = data[1 * colorSize];
                pixels[i * 4 + 2] = data[0];
            } else {
                pixels[i * 4] = data[0];
                pixels[i * 4 + 1] = data[0];
                pixels[i * 4 + 2] = data[0];
            }
        }
        unscaled = QImage(pixels,
                          output->width, output->height,
                          QImage::Format_RGB32);
    }

    if (unscaled.size() != finalSize) {
        // TODO: use quality parameter to decide transformation method
        *image = unscaled.scaled(finalSize, Qt::IgnoreAspectRatio,
                                 Qt::SmoothTransformation);
    } else {
        *image = unscaled;
        if (output->type == LIBRAW_IMAGE_BITMAP) {
            // make sure that the bits are copied
            uchar *b = image->bits();
            Q_UNUSED(b);
        }
    }
    d->raw->dcraw_clear_mem(output);
    delete pixels;

    return true;
}
void QgsComposerItem::changeItemRectangle( const QPointF& currentPosition,
    const QPointF& mouseMoveStartPos,
    const QGraphicsRectItem* originalItem,
    double dx, double dy,
    QGraphicsRectItem* changeItem )
{
  Q_UNUSED( dx );
  Q_UNUSED( dy );
  if ( !changeItem || !originalItem || !mComposition )
  {
    return;
  }

  //test if change item is a composer item. If so, prefer call to  setSceneRect() instead of setTransform() and setRect()
  QgsComposerItem* changeComposerItem = dynamic_cast<QgsComposerItem *>( changeItem );

  double mx = 0.0, my = 0.0, rx = 0.0, ry = 0.0;
  QPointF snappedPosition = mComposition->snapPointToGrid( currentPosition );

  //snap to grid and align to other items
  if ( mComposition->alignmentSnap() && mCurrentMouseMoveAction != QgsComposerItem::MoveItem )
  {
    double alignX = 0;
    double alignY = 0;
    snappedPosition = mComposition->alignPos( snappedPosition, dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY );
    if ( alignX != -1 )
    {
      QGraphicsLineItem* item = hAlignSnapItem();
      item->setLine( QLineF( alignX, 0, alignX,  mComposition->paperHeight() ) );
      item->show();
    }
    else
    {
      deleteHAlignSnapItem();
    }

    if ( alignY != -1 )
    {
      QGraphicsLineItem* item = vAlignSnapItem();
      item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) );
      item->show();
    }
    else
    {
      deleteVAlignSnapItem();
    }
  }

  double diffX = 0;
  double diffY = 0;

  switch ( mCurrentMouseMoveAction )
  {
      //vertical resize
    case QgsComposerItem::ResizeUp:
      diffY = snappedPosition.y() - originalItem->transform().dy();
      mx = 0; my = diffY; rx = 0; ry = -diffY;
      break;

    case QgsComposerItem::ResizeDown:
      diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
      mx = 0; my = 0; rx = 0; ry = diffY;
      break;

      //horizontal resize
    case QgsComposerItem::ResizeLeft:
      diffX = snappedPosition.x() - originalItem->transform().dx();
      mx = diffX, my = 0; rx = -diffX; ry = 0;
      break;

    case QgsComposerItem::ResizeRight:
      diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
      mx = 0; my = 0; rx = diffX, ry = 0;
      break;

      //diagonal resize
    case QgsComposerItem::ResizeLeftUp:
      diffX = snappedPosition.x() - originalItem->transform().dx();
      diffY = snappedPosition.y() - originalItem->transform().dy();
      mx = diffX, my = diffY; rx = -diffX; ry = -diffY;
      break;

    case QgsComposerItem::ResizeRightDown:
      diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
      diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
      mx = 0; my = 0; rx = diffX, ry = diffY;
      break;

    case QgsComposerItem::ResizeRightUp:
      diffX = snappedPosition.x() - ( originalItem->transform().dx() + originalItem->rect().width() );
      diffY = snappedPosition.y() - originalItem->transform().dy();
      mx = 0; my = diffY, rx = diffX, ry = -diffY;
      break;

    case QgsComposerItem::ResizeLeftDown:
      diffX = snappedPosition.x() - originalItem->transform().dx();
      diffY = snappedPosition.y() - ( originalItem->transform().dy() + originalItem->rect().height() );
      mx = diffX, my = 0; rx = -diffX; ry = diffY;
      break;

    case QgsComposerItem::MoveItem:
    {
      //calculate total move difference
      double moveX = currentPosition.x() - mouseMoveStartPos.x();
      double moveY = currentPosition.y() - mouseMoveStartPos.y();

      QPointF upperLeftPoint( originalItem->transform().dx() + moveX, originalItem->transform().dy() + moveY );
      QPointF snappedLeftPoint = mComposition->snapPointToGrid( upperLeftPoint );

      if ( snappedLeftPoint != upperLeftPoint ) //don't do align snap if grid snap has been done
      {
        deleteAlignItems();
      }
      else if ( mComposition->alignmentSnap() ) //align item
      {
        double alignX = 0;
        double alignY = 0;
        snappedLeftPoint = mComposition->alignItem( dynamic_cast<const QgsComposerItem*>( originalItem ), alignX, alignY, moveX, moveY );
        if ( alignX != -1 )
        {
          QGraphicsLineItem* item = hAlignSnapItem();
          int numPages = mComposition->numPages();
          double yLineCoord = 300; //default in case there is no single page
          if ( numPages > 0 )
          {
            yLineCoord = mComposition->paperHeight() * numPages + mComposition->spaceBetweenPages() * ( numPages - 1 );
          }
          item->setLine( QLineF( alignX, 0, alignX,  yLineCoord ) );
          item->show();
        }
        else
        {
          deleteHAlignSnapItem();
        }
        if ( alignY != -1 )
        {
          QGraphicsLineItem* item = vAlignSnapItem();
          item->setLine( QLineF( 0, alignY, mComposition->paperWidth(), alignY ) );
          item->show();
        }
        else
        {
          deleteVAlignSnapItem();
        }
      }
      double moveRectX = snappedLeftPoint.x() - originalItem->transform().dx();
      double moveRectY = snappedLeftPoint.y() - originalItem->transform().dy();

      if ( !changeComposerItem )
      {
        QTransform moveTransform;
        moveTransform.translate( originalItem->transform().dx() + moveRectX, originalItem->transform().dy() + moveRectY );
        changeItem->setTransform( moveTransform );
      }
      else  //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group)
      {
        changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + moveRectX,
                                          originalItem->transform().dy() + moveRectY,
                                          originalItem->rect().width(), originalItem->rect().height() ) );
        changeComposerItem->updateItem();
      }
    }
    return;
    case QgsComposerItem::NoAction:
      break;
  }

  if ( !changeComposerItem )
  {
    QTransform itemTransform;
    itemTransform.translate( originalItem->transform().dx() + mx, originalItem->transform().dy() + my );
    changeItem->setTransform( itemTransform );
    QRectF itemRect( 0, 0, originalItem->rect().width() + rx,  originalItem->rect().height() + ry );
    changeItem->setRect( itemRect );
  }
  else //for composer items, we prefer setSceneRect as subclasses can implement custom behaviour (e.g. item group)
  {
    changeComposerItem->setSceneRect( QRectF( originalItem->transform().dx() + mx, originalItem->transform().dy() + my,
                                      originalItem->rect().width() + rx, originalItem->rect().height() + ry ) );
    changeComposerItem->updateItem();
  }
}
Example #27
0
bool PathAlongPathPlugin::run(ScribusDoc* doc, const QString&)
{
	firstUpdate = true;
	m_doc = doc;
	originalPathG.clear();
	originalRotG.clear();
	originalXPosG.clear();
	originalYPosG.clear();
	patternItemG.clear();
	if (m_doc == nullptr)
		m_doc = ScCore->primaryMainWindow()->doc;
	if (m_doc->m_Selection->count() > 1)
	{
		if ((m_doc->m_Selection->itemAt(0)->isGroup()) || (m_doc->m_Selection->itemAt(1)->isGroup()))
		{
			selOffs = 0;
			selCount = m_doc->m_Selection->count() - 1;
			if (!m_doc->m_Selection->itemAt(0)->isGroup())
			{
				pathItem = m_doc->m_Selection->itemAt(0);
				selOffs = 1;
			}
			else
				pathItem = m_doc->m_Selection->itemAt(selCount);
			effectPath = pathItem->PoLine.copy();
			QTransform mp;
			mp.rotate(pathItem->rotation());
			effectPath.map(mp);
			PageItem* bxi = m_doc->m_Selection->itemAt(selOffs);
			bxi->asGroupFrame()->adjustXYPosition();
			originalPathG.append(bxi->PoLine.copy());
			originalXPosG.append(bxi->xPos());
			originalYPosG.append(bxi->yPos());
			originalXPosGi.append(bxi->gXpos);
			originalYPosGi.append(bxi->gYpos);
			originalRotG.append(bxi->rotation());
			originalWidth.append(bxi->width());
			originalHeight.append(bxi->height());
			originalWidthG.append(bxi->groupWidth);
			originalHeightG.append(bxi->groupHeight);
			patternItemG.append(bxi);
			QList<PageItem*> bxiL = bxi->getAllChildren();
			for (int bx = 0; bx < bxiL.count(); ++bx)
			{
				PageItem* cIte = bxiL.at(bx);
				originalPathG.append(cIte->PoLine.copy());
				originalXPosG.append(cIte->xPos());
				originalYPosG.append(cIte->yPos());
				originalWidth.append(cIte->width());
				originalHeight.append(cIte->height());
				originalWidthG.append(cIte->groupWidth);
				originalHeightG.append(cIte->groupHeight);
				originalXPosGi.append(cIte->gXpos);
				originalYPosGi.append(cIte->gYpos);
				originalRotG.append(cIte->rotation());
				patternItemG.append(cIte);
			}
			QPainterPath tmpPath = effectPath.toQPainterPath(false);
			PathDialog *dia = new PathDialog(m_doc->scMW(), m_doc->unitIndex(), tmpPath.length(), true);
			connect(dia, SIGNAL(updateValues(int, double, double, double, int)), this, SLOT(updateEffectG(int, double, double, double, int)));
			if (dia->exec())
			{
				updateEffectG(dia->effectType, dia->offset, dia->offsetY, dia->gap, dia->rotate);
				m_doc->changed();
				if (bxi->isGroup())
				{
					m_doc->resizeGroupToContents(bxi);
					bxi->SetRectFrame();
					m_doc->view()->DrawNew();
				}
			}
			else
			{
				updateEffectG(-1, dia->offset, dia->offsetY, dia->gap, dia->rotate);
				m_doc->view()->DrawNew();
			}
			delete dia;
		}
		else
		{
void QgsComposerItem::move( double dx, double dy )
{
  QTransform t = transform();
  QRectF newSceneRect( t.dx() + dx, t.dy() + dy, rect().width(), rect().height() );
  setSceneRect( newSceneRect );
}
Example #29
0
void FancyTabProxyStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *p, const QWidget *widget) const
{

    const QStyleOptionTabV3 *v3Opt = qstyleoption_cast<const QStyleOptionTabV3*>(option);

    if (element != CE_TabBarTab || !v3Opt) {
        QProxyStyle::drawControl(element, option, p, widget);
        return;
    }

    const QRect rect = v3Opt->rect;
    const bool selected = v3Opt->state  &State_Selected;
    const bool verticalTabs = v3Opt->shape == QTabBar::RoundedWest;
    const QString text = v3Opt->text;

    QTransform m;
    if (verticalTabs) {
        m = QTransform::fromTranslate(rect.left(), rect.bottom());
        m.rotate(-90);
    } else {
        m = QTransform::fromTranslate(rect.left(), rect.top());
    }

    const QRect draw_rect(QPoint(0, 0), m.mapRect(rect).size());

    if (!selected && GtkStyle::isActive()) {
        p->fillRect(option->rect, option->palette.background());
    }

    p->save();
    p->setTransform(m);

    QRect iconRect(QPoint(8, 0), v3Opt->iconSize);
    QRect textRect(iconRect.topRight() + QPoint(4, 0), draw_rect.size());
    textRect.setRight(draw_rect.width());
    iconRect.translate(0, (draw_rect.height() - iconRect.height()) / 2);

    QStyleOptionViewItemV4 styleOpt;
    styleOpt.palette=option->palette;
    styleOpt.rect=draw_rect;
    if (QStyleOptionTab::Beginning==v3Opt->position) {
        styleOpt.rect.adjust(0, 0, -1, 0);
    }
    styleOpt.state=option->state;
    styleOpt.state&=~(QStyle::State_Selected|QStyle::State_MouseOver);
    styleOpt.state|=QStyle::State_Selected|QStyle::State_Enabled;
    styleOpt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
    styleOpt.showDecorationSelected=true;
    bool drawBgnd=true;
    int fader = 1;

    if (!selected && drawBgnd) {
        const QString faderKey = "tab_" + text + "_fader";
        const QString animationKey = "tab_" + text + "_animation";

        const QString tab_hover = widget->property("tab_hover").toString();
        fader=widget->property(faderKey.toUtf8().constData()).toInt();
        QPropertyAnimation *animation = widget->property(animationKey.toUtf8().constData()).value<QPropertyAnimation*>();

        if (!animation) {
            QWidget* mut_widget = const_cast<QWidget*>(widget);
            fader = 0;
            mut_widget->setProperty(faderKey.toUtf8().constData(), fader);
            animation = new QPropertyAnimation(mut_widget, faderKey.toUtf8(), mut_widget);
            connect(animation, SIGNAL(valueChanged(QVariant)), mut_widget, SLOT(update()));
            mut_widget->setProperty(animationKey.toUtf8().constData(), QVariant::fromValue(animation));
        }

        if (text == tab_hover) {
            if (animation->state() != QAbstractAnimation::Running && fader != 40) {
                animation->stop();
                animation->setDuration(80);
                animation->setEndValue(50);
                animation->start();
            }
        } else {
            if (animation->state() != QAbstractAnimation::Running && fader != 0) {
                animation->stop();
                animation->setDuration(160);
                animation->setEndValue(0);
                animation->start();
            }
        }

        if (fader<1) {
            drawBgnd=false;
        } else {
            QColor col(styleOpt.palette.highlight().color());
            col.setAlpha(fader);
            styleOpt.palette.setColor(styleOpt.palette.currentColorGroup(), QPalette::Highlight, col);
        }
    }

    if (drawBgnd) {
        if (!selected && GtkStyle::isActive()) {
            GtkStyle::drawSelection(styleOpt, p, (fader*1.0)/150.0);
        } else {
            #ifdef Q_OS_MAC
            OSXStyle::self()->drawSelection(styleOpt, p, selected ? 1.0 : (fader*1.0)/150.0);
            #else
            #ifdef Q_OS_WIN
            if (QPalette::Active!=styleOpt.palette.currentColorGroup()) {
                styleOpt.palette.setColor(QPalette::Highlight, styleOpt.palette.color(QPalette::Window).darker(110));
            }
            #endif
            QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &styleOpt, p, 0);
            #endif
        }
    }

    int textFlags = Qt::AlignTop | Qt::AlignVCenter;
    #ifdef Q_OS_MAC
    p->setPen(selected && option->state&State_Active
              ? OSXStyle::self()->viewPalette().highlightedText().color() : OSXStyle::self()->viewPalette().foreground().color());
    #else
    p->setPen(selected && option->state&State_Active
              ? QApplication::palette().highlightedText().color() : QApplication::palette().foreground().color());
    #endif

    drawIcon(v3Opt->icon, iconRect, p, v3Opt->iconSize,
             selected && option->state&State_Active);

    QString txt=text;
    txt.replace("&", "");
    txt=p->fontMetrics().elidedText(txt, elideMode(), textRect.width());
    p->drawText(textRect.translated(0, -1), textFlags, txt);
    p->restore();
}
Example #30
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;
}