Exemple #1
0
void QgsLayoutView::viewChanged()
{
  if ( mHorizontalRuler )
  {
    mHorizontalRuler->setSceneTransform( viewportTransform() );
  }
  if ( mVerticalRuler )
  {
    mVerticalRuler->setSceneTransform( viewportTransform() );
  }

  // determine page at center of view
  QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
  QRectF visibleRect = mapToScene( viewportRect ).boundingRect();
  QPointF centerVisible = visibleRect.center();

  if ( currentLayout() && currentLayout()->pageCollection() )
  {
    int newPage = currentLayout()->pageCollection()->pageNumberForPoint( centerVisible );
    if ( newPage != mCurrentPage )
    {
      mCurrentPage = newPage;
      emit pageChanged( mCurrentPage );
    }
  }
}
Exemple #2
0
void QgsComposerView::updateRulers()
{
  if ( mHorizontalRuler )
  {
    mHorizontalRuler->setSceneTransform( viewportTransform() );
  }
  if ( mVerticalRuler )
  {
    mVerticalRuler->setSceneTransform( viewportTransform() );
  }
}
Exemple #3
0
void
Panner::drawItems(QPainter *painter, int numItems,
                  QGraphicsItem *items[],
                  const QStyleOptionGraphicsItem options[])
{
    Profiler profiler("Panner::drawItems");

    if (m_cache.size() != viewport()->size()) {

        QGraphicsScene *s = scene();
        if (!s) return;
        PannerScene *ps = static_cast<PannerScene *>(s);

        m_cache = QPixmap(viewport()->size());
        m_cache.fill(Qt::transparent);
        QPainter cachePainter;
        cachePainter.begin(&m_cache);
        cachePainter.setTransform(viewportTransform());
        ps->drawItems(&cachePainter, numItems, items, options);
        cachePainter.end();
    }

    painter->save();
    painter->setTransform(QTransform());
    painter->drawPixmap(0, 0, m_cache);
    painter->restore();
}
Exemple #4
0
const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
{
    AffineTransform viewportTranslation(viewportTransform());
    m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
    return m_localToParentTransform;
    // If this class were ever given a localTransform(), then the above would read:
    // return viewportTransform() * localTransform() * viewportTranslation;
}
const AffineTransform& LayoutSVGResourceMarker::localToSVGParentTransform()
    const {
  m_localToParentTransform =
      AffineTransform::translation(m_viewport.x(), m_viewport.y()) *
      viewportTransform();
  return m_localToParentTransform;
  // If this class were ever given a localTransform(), then the above would
  // read:
  // return viewportTranslation * localTransform() * viewportTransform();
}
AffineTransform RenderSVGContainer::absoluteTransform() const
{
    AffineTransform ctm = RenderContainer::absoluteTransform();
    if (!parent()->isSVGContainer()) {
        SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
        ctm.scale(svg->currentScale());
        ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y());
    }
    ctm.translate(viewport().x(), viewport().y());
    return viewportTransform() * ctm;
}
AffineTransform RenderSVGResourceMarker::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
{
    // The 'origin' coordinate maps to SVGs refX/refY, given in coordinates relative to the viewport established by the marker
    FloatPoint mappedOrigin = viewportTransform().mapPoint(origin);

    AffineTransform transformation = contentTransformation;
    if (strokeWidth != -1)
        transformation.scaleNonUniform(strokeWidth, strokeWidth);

    transformation.translate(-mappedOrigin.x(), -mappedOrigin.y());
    return transformation;
}
AffineTransform LayoutSVGResourceMarker::markerTransformation(
    const FloatPoint& origin,
    float autoAngle,
    float strokeWidth) const {
  // Apply scaling according to markerUnits ('strokeWidth' or 'userSpaceOnUse'.)
  float markerScale =
      markerUnits() == SVGMarkerUnitsStrokeWidth ? strokeWidth : 1;

  AffineTransform transform;
  transform.translate(origin.x(), origin.y());
  transform.rotate(orientType() == SVGMarkerOrientAngle ? angle() : autoAngle);
  transform.scale(markerScale);

  // The 'origin' coordinate maps to SVGs refX/refY, given in coordinates
  // relative to the viewport established by the marker.
  FloatPoint mappedReferencePoint =
      viewportTransform().mapPoint(referencePoint());
  transform.translate(-mappedReferencePoint.x(), -mappedReferencePoint.y());
  return transform;
}
SVGTransformChange LayoutSVGViewportContainer::calculateLocalTransform()
{
    if (!m_needsTransformUpdate)
        return SVGTransformChange::None;

    SVGTransformChangeDetector changeDetector(m_localToParentTransform);
    m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
    m_needsTransformUpdate = false;
    return changeDetector.computeChange(m_localToParentTransform);
}
Exemple #10
0
/* The idea is to produce a transformation for this viewport which
 * will take any location in INCHES and turn it into a location on the 
 * Device in INCHES.
 * The reason for working in INCHES is because we want to be able to
 * do rotations as part of the transformation.
 * If "incremental" is true, then we just work from the "current"
 * values of the parent.  Otherwise, we have to recurse and recalculate
 * everything from scratch.
 */
void calcViewportTransform(SEXP vp, SEXP parent, Rboolean incremental,
			   pGEDevDesc dd)
{
    int i, j;
    double vpWidthCM, vpHeightCM, rotationAngle;
    double parentWidthCM, parentHeightCM;
    double xINCHES, yINCHES;
    double xadj, yadj;
    double parentAngle;
    LViewportLocation vpl;
    LViewportContext vpc, parentContext;
    R_GE_gcontext gc, parentgc;
    LTransform thisLocation, thisRotation, thisJustification, thisTransform;
    LTransform tempTransform, parentTransform, transform;
    SEXP currentWidthCM, currentHeightCM, currentRotation;
    SEXP currentTransform;
    /* This should never be true when we are doing an incremental
     * calculation
     */
    if (isNull(parent)) {
	/* We have a top-level viewport; the parent is the device
	 */
	getDeviceSize(dd, &parentWidthCM, &parentHeightCM);
	/* For a device the transform is the identity transform
	 */
	identity(parentTransform);
	/* For a device, xmin=0, ymin=0, xmax=1, ymax=1, and
	 */
	parentContext.xscalemin = 0;
	parentContext.yscalemin = 0;
	parentContext.xscalemax = 1;
	parentContext.yscalemax = 1;
	/* FIXME:  How do I figure out the device fontsize ?
	 * From ps.options etc, ... ?
	 * FIXME:  How do I figure out the device lineheight ??
	 * FIXME:  How do I figure out the device cex ??
	 * FIXME:  How do I figure out the device font ??
	 * FIXME:  How do I figure out the device fontfamily ??
	 */
	parentgc.ps = 10;
	parentgc.lineheight = 1.2;
	parentgc.cex = 1;
	parentgc.fontface = 1;
	parentgc.fontfamily[0] = '\0';
	/* The device is not rotated
	 */
	parentAngle = 0;
	fillViewportLocationFromViewport(vp, &vpl);
    } else {
	/* Get parent transform (etc ...)
	 * If necessary, recalculate the parent transform (etc ...)
	 */
	if (!incremental)
	    calcViewportTransform(parent, viewportParent(parent), 0, dd);
	/* Get information required to transform viewport location
	 */
	parentWidthCM = REAL(viewportWidthCM(parent))[0];
	parentHeightCM = REAL(viewportHeightCM(parent))[0];
	parentAngle = REAL(viewportRotation(parent))[0];
	for (i=0; i<3; i++)
	    for (j=0; j<3; j++)
		parentTransform[i][j] = 
		    REAL(viewportTransform(parent))[i +3*j];
	fillViewportContextFromViewport(parent, &parentContext);
	/* 
	 * Don't get gcontext from parent because the most recent
	 * previous gpar setting may have come from a gTree
	 * So we look at this viewport's parentgpar slot instead
	 * 
	 * WAS gcontextFromViewport(parent, &parentgc);
	 */
	gcontextFromgpar(viewportParentGPar(vp), 0, &parentgc, dd);
	/* In order for the vp to get its vpl from a layout
	 * it must have specified a layout.pos and the parent
	 * must have a layout
	 * FIXME:  Actually, in addition, layout.pos.row and
	 * layout.pos.col must be valid for the layout
	 */
	if ((isNull(viewportLayoutPosRow(vp)) && 
	     isNull(viewportLayoutPosCol(vp))) ||
	    isNull(viewportLayout(parent)))
	    fillViewportLocationFromViewport(vp, &vpl);
	else if (checkPosRowPosCol(vp, parent))
	    calcViewportLocationFromLayout(viewportLayoutPosRow(vp),
					   viewportLayoutPosCol(vp),
					   parent,
					   &vpl);
    }
    /* NOTE that we are not doing a transformLocn here because
     * we just want locations and dimensions (in INCHES) relative to 
     * the parent, NOT relative to the device.
     */
    /* First, convert the location of the viewport into CM
     */
    xINCHES = transformXtoINCHES(vpl.x, 0, parentContext, &parentgc,
				 parentWidthCM, parentHeightCM, 
				 dd);
    yINCHES = transformYtoINCHES(vpl.y, 0, parentContext, &parentgc,
				 parentWidthCM, parentHeightCM, 
				 dd);
    /* Calculate the width and height of the viewport in CM too
     * so that any viewports within this one can do transformations
     */
    vpWidthCM = transformWidthtoINCHES(vpl.width, 0, parentContext, &parentgc,
				       parentWidthCM, parentHeightCM,
				       dd)*2.54;
    vpHeightCM = transformHeighttoINCHES(vpl.height, 0, parentContext, 
					 &parentgc,
					 parentWidthCM, 
					 parentHeightCM, 
					 dd)*2.54;
    /* Fall out if location or size are non-finite
     */
    if (!R_FINITE(xINCHES) || 
	!R_FINITE(yINCHES) || 
	!R_FINITE(vpWidthCM) || 
	!R_FINITE(vpHeightCM))
	error(_("Non-finite location and/or size for viewport"));
    /* Determine justification required
     */
    justification(vpWidthCM, vpHeightCM, vpl.hjust, vpl.vjust,
		  &xadj, &yadj);
    /* Next, produce the transformation to add the location of
     * the viewport to the location.
     */
    /* Produce transform for this viewport
     */
    translation(xINCHES, yINCHES, thisLocation);
    if (viewportAngle(vp) != 0)
	rotation(viewportAngle(vp), thisRotation);
    else
	identity(thisRotation);
    translation(xadj/2.54, yadj/2.54, thisJustification);
    /* Position relative to origin of rotation THEN rotate.
     */
    multiply(thisJustification, thisRotation, tempTransform);
    /* Translate to bottom-left corner.
     */
    multiply(tempTransform, thisLocation, thisTransform);
    /* Combine with parent's transform
     */
    multiply(thisTransform, parentTransform, transform);
    /* Sum up the rotation angles
     */
    rotationAngle = parentAngle + viewportAngle(vp);
    /* Finally, allocate the rows and columns for this viewport's
     * layout if it has one
     */
    if (!isNull(viewportLayout(vp))) {
	fillViewportContextFromViewport(vp, &vpc);
	gcontextFromViewport(vp, &gc, dd);
	calcViewportLayout(vp, vpWidthCM, vpHeightCM, vpc, &gc, dd);
    }
    /* Record all of the answers in the viewport
     * (the layout calculations are done within calcViewportLayout)
     */
    PROTECT(currentWidthCM = ScalarReal(vpWidthCM));
    PROTECT(currentHeightCM = ScalarReal(vpHeightCM));
    PROTECT(currentRotation = ScalarReal(rotationAngle));
    PROTECT(currentTransform = allocMatrix(REALSXP, 3, 3));
    for (i=0; i<3; i++)
	for (j=0; j<3; j++)
	    REAL(currentTransform)[i + 3*j] = transform[i][j];
    SET_VECTOR_ELT(vp, PVP_WIDTHCM, currentWidthCM);
    SET_VECTOR_ELT(vp, PVP_HEIGHTCM, currentHeightCM);
    SET_VECTOR_ELT(vp, PVP_ROTATION, currentRotation);
    SET_VECTOR_ELT(vp, PVP_TRANS, currentTransform);
    UNPROTECT(4);
}
bool RenderSVGViewportContainer::calculateLocalTransform() 
{
    m_didTransformToRootUpdate = m_needsTransformUpdate || SVGRenderSupport::transformToRootChanged(parent());
    if (!m_needsTransformUpdate)
        return false;
    
    m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
    m_needsTransformUpdate = false;
    return true;
}
void RenderSVGViewportContainer::applyAdditionalTransforms(PaintInfo& paintInfo)
{
    paintInfo.context->concatCTM(viewportTransform());
    RenderSVGContainer::applyAdditionalTransforms(paintInfo);
}
TransformationMatrix RenderSVGViewportContainer::absoluteTransform() const
{
    TransformationMatrix ctm = RenderObject::absoluteTransform();
    ctm.translate(viewport().x(), viewport().y());
    return viewportTransform() * ctm;
}
Exemple #14
0
void
UBBoardView::tabletEvent (QTabletEvent * event)
{
  if (!mUseHighResTabletEvent)
    {
      event->setAccepted (false);
      return;
    }

  UBDrawingController *dc = UBDrawingController::drawingController ();

  QPointF tabletPos = UBGeometryUtils::pointConstrainedInRect (event->hiResGlobalPos ()
                                                               - mapToGlobal (QPoint (0, 0)), rect ());

  UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool ();

  if (event->type () == QEvent::TabletPress || event->type () == QEvent::TabletEnterProximity)
    {
      if (event->pointerType () == QTabletEvent::Eraser)
        {
          dc->setStylusTool (UBStylusTool::Eraser);
          mUsingTabletEraser = true;
        }
      else
        {
          if (mUsingTabletEraser && currentTool == UBStylusTool::Eraser)
            {
              dc->setStylusTool (dc->latestDrawingTool ());
            }

          mUsingTabletEraser = false;
        }
    }

  // if event are not Pen events, we drop the tablet stuff and route everything through mouse event
  if (currentTool != UBStylusTool::Pen
      && currentTool != UBStylusTool::Line
      && currentTool != UBStylusTool::Marker
      && !mMarkerPressureSensitive)
    {
      event->setAccepted (false);
      return;
    }

  QPointF scenePos = viewportTransform ().inverted ().map (tabletPos);

  qreal pressure = 1.0;
  if (((currentTool == UBStylusTool::Pen || currentTool == UBStylusTool::Line)
       && mPenPressureSensitive)
      || (currentTool == UBStylusTool::Marker && mMarkerPressureSensitive))
    {
      pressure = event->pressure ();
    }

  bool acceptEvent = true;

  switch (event->type ())
    {
    case QEvent::TabletPress:
      {
        mTabletStylusIsPressed = true;

        scene ()->inputDevicePress (scenePos, pressure);

        break;
      }
    case QEvent::TabletMove:
      {
        if (mTabletStylusIsPressed)
          {
            scene ()->inputDeviceMove (scenePos, pressure);
          }

        acceptEvent = false; // rerouted to mouse move

        break;

      }
    case QEvent::TabletRelease:
      {
        UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool ();
        scene ()->setToolCursor (currentTool);
        setToolCursor (currentTool);

        scene ()->inputDeviceRelease ();

        mPendingStylusReleaseEvent = false;

        mTabletStylusIsPressed = false;
        mMouseButtonIsPressed = false;

        break;
      }
    default:
      {
        //NOOP - avoid compiler warning
      }
    }

  // ignore mouse press and mouse move tablet event so that it is rerouted to mouse events,
  // documented in QTabletEvent Class Reference:
  /* The event handler QWidget::tabletEvent() receives all three types of tablet events.
     Qt will first send a tabletEvent then, if it is not accepted, it will send a mouse event. */
  //
  // This is a workaround to the fact that tablet event are not delivered to child widget (like palettes)
  //

  event->setAccepted (acceptEvent);

}
void RenderSVGContainer::paint(PaintInfo& paintInfo, int parentX, int parentY)
{
    if (paintInfo.context->paintingDisabled())
        return;

    // This should only exist for <svg> renderers
    if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) 
        paintBoxDecorations(paintInfo, m_x + parentX, m_y + parentY);

    if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
        paintOutline(paintInfo.context, parentX, parentY, width(), height(), style());
    
    if (paintInfo.phase != PaintPhaseForeground || !drawsContents())
        return;

    const SVGRenderStyle* svgStyle = style()->svgStyle();
    AtomicString filterId(SVGURIReference::getTarget(svgStyle->filter()));

#if ENABLE(SVG_EXPERIMENTAL_FEATURES) 
    SVGResourceFilter* filter = getFilterById(document(), filterId);
#endif

    if (!firstChild()
#if ENABLE(SVG_EXPERIMENTAL_FEATURES) 
        && !filter
#endif
        )
        return; // Spec: groups w/o children still may render filter content.
    
    paintInfo.context->save();

    if (!parent()->isSVGContainer()) {
        // Translate from parent offsets (html renderers) to a relative transform (svg renderers)
        IntPoint origin;
        origin.move(parentX, parentY);
        origin.move(m_x, m_y);
        origin.move(borderLeft(), borderTop());
        origin.move(paddingLeft(), paddingTop());
        if (origin.x() || origin.y()) {
            paintInfo.context->concatCTM(AffineTransform().translate(origin.x(), origin.y()));
            paintInfo.rect.move(-origin.x(), -origin.y());
        }
        parentX = parentY = 0;
        SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
        paintInfo.context->concatCTM(AffineTransform().scale(svg->currentScale()));
    } else {
        // Only the root <svg> element should need any translations using the HTML/CSS system
        // parentX, parentY are also non-zero for first-level kids of these
        // CSS-transformed <svg> root-elements (due to RenderBox::paint) for any other element
        // they should be 0.   m_x, m_y should always be 0 for non-root svg containers
        ASSERT(m_x == 0);
        ASSERT(m_y == 0);
    }

    if (!viewport().isEmpty()) {
        if (style()->overflowX() != OVISIBLE)
            paintInfo.context->clip(enclosingIntRect(viewport())); // FIXME: Eventually we'll want float-precision clipping

        paintInfo.context->concatCTM(AffineTransform().translate(viewport().x(), viewport().y()));
    }
    if (!localTransform().isIdentity())
        paintInfo.context->concatCTM(localTransform());
    if (!parent()->isSVGContainer()) {
        SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
        paintInfo.context->concatCTM(AffineTransform().translate(svg->currentTranslate().x(), svg->currentTranslate().y()));
    }

    FloatRect strokeBBox = relativeBBox(true);

    SVGElement* svgElement = static_cast<SVGElement*>(element());
    ASSERT(svgElement && svgElement->document() && svgElement->isStyled());

    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
 
    AtomicString clipperId(SVGURIReference::getTarget(svgStyle->clipPath()));
    AtomicString maskerId(SVGURIReference::getTarget(svgStyle->maskElement()));

    SVGResourceClipper* clipper = getClipperById(document(), clipperId);
    SVGResourceMasker* masker = getMaskerById(document(), maskerId);

    if (clipper) {
        clipper->addClient(styledElement);
        clipper->applyClip(paintInfo.context, strokeBBox);
    } else if (!clipperId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(clipperId, styledElement);

    if (masker) {
        masker->addClient(styledElement);
        masker->applyMask(paintInfo.context, strokeBBox);
    } else if (!maskerId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);

    float opacity = style()->opacity();
    if (opacity < 1.0f) {
        paintInfo.context->clip(enclosingIntRect(strokeBBox));
        paintInfo.context->beginTransparencyLayer(opacity);
    }

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    if (filter)
        filter->prepareFilter(paintInfo.context, strokeBBox);
    else if (!filterId.isEmpty())
        svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
#endif

    if (!viewBox().isEmpty())
        paintInfo.context->concatCTM(viewportTransform());

    RenderContainer::paint(paintInfo, 0, 0);

#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
    if (filter)
        filter->applyFilter(paintInfo.context, strokeBBox);
#endif

    if (opacity < 1.0f)
        paintInfo.context->endTransparencyLayer();

    paintInfo.context->restore();
}