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 ); } } }
void QgsComposerView::updateRulers() { if ( mHorizontalRuler ) { mHorizontalRuler->setSceneTransform( viewportTransform() ); } if ( mVerticalRuler ) { mVerticalRuler->setSceneTransform( viewportTransform() ); } }
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(); }
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); }
/* 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; }
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(); }