VisibleSelection PendingSelection::calcVisibleSelectionAlgorithm() const { using PositionType = typename Strategy::PositionType; PositionType start = Strategy::selectionStart(m_selection); PositionType end = Strategy::selectionEnd(m_selection); SelectionType selectionType = VisibleSelection::selectionType(start, end); TextAffinity affinity = m_selection.affinity(); bool paintBlockCursor = m_shouldShowBlockCursor && selectionType == SelectionType::CaretSelection && !isLogicalEndOfLine(VisiblePosition(end, affinity)); VisibleSelection selection; if (enclosingTextFormControl(start.computeContainerNode())) { // TODO(yosin) We should use |PositionMoveType::Character| to avoid // ending paint at middle of character. PositionType endPosition = paintBlockCursor ? nextPositionOf(Strategy::selectionExtent(m_selection), PositionMoveType::CodePoint) : end; selection.setWithoutValidation(start, endPosition); return selection; } VisiblePosition visibleStart = VisiblePosition(start, selectionType == SelectionType::RangeSelection ? TextAffinity::Downstream : affinity); if (paintBlockCursor) { VisiblePosition visibleExtent(end, affinity); visibleExtent = visibleExtent.next(CanSkipOverEditingBoundary); return VisibleSelection(visibleStart, visibleExtent); } VisiblePosition visibleEnd(end, selectionType == SelectionType::RangeSelection ? TextAffinity::Upstream : affinity); return VisibleSelection(visibleStart, visibleEnd); }
void QgsMapSettings::setMagnificationFactor( double factor ) { double ratio = mMagnificationFactor / factor; mMagnificationFactor = factor; double rot = rotation(); setRotation( 0.0 ); QgsRectangle ext = visibleExtent(); ext.scale( ratio ); mRotation = rot; mExtent = ext; mDpi = outputDpi() / ratio; updateDerived(); }
void QgsMapSettings::setMagnificationFactor( double factor ) { double ratio = mMagnificationFactor / factor; mMagnificationFactor = factor; double rot = rotation(); setRotation( 0.0 ); QgsRectangle ext = visibleExtent(); ext.scale( ratio ); mRotation = rot; mExtent = ext; mDpi = mDpi / ratio; QgsDebugMsg( QStringLiteral( "Magnification factor: %1 dpi: %2 ratio: %3" ).arg( factor ).arg( mDpi ).arg( ratio ) ); updateDerived(); }
void QgsMapSettings::updateDerived() { QgsRectangle extent = mExtent; if ( extent.isEmpty() || !extent.isFinite() ) { mValid = false; return; } // Don't allow zooms where the current extent is so small that it // can't be accurately represented using a double (which is what // currentExtent uses). Excluding 0 avoids a divide by zero and an // infinite loop when rendering to a new canvas. Excluding extents // greater than 1 avoids doing unnecessary calculations. // The scheme is to compare the width against the mean x coordinate // (and height against mean y coordinate) and only allow zooms where // the ratio indicates that there is more than about 12 significant // figures (there are about 16 significant figures in a double). if ( extent.width() > 0 && extent.height() > 0 && extent.width() < 1 && extent.height() < 1 ) { // Use abs() on the extent to avoid the case where the extent is // symmetrical about 0. double xMean = ( qAbs( extent.xMinimum() ) + qAbs( extent.xMaximum() ) ) * 0.5; double yMean = ( qAbs( extent.yMinimum() ) + qAbs( extent.yMaximum() ) ) * 0.5; double xRange = extent.width() / xMean; double yRange = extent.height() / yMean; static const double minProportion = 1e-12; if ( xRange < minProportion || yRange < minProportion ) { mValid = false; return; } } double myHeight = mSize.height(); double myWidth = mSize.width(); if ( !myWidth || !myHeight ) { mValid = false; return; } // calculate the translation and scaling parameters double mapUnitsPerPixelY = mExtent.height() / myHeight; double mapUnitsPerPixelX = mExtent.width() / myWidth; mMapUnitsPerPixel = mapUnitsPerPixelY > mapUnitsPerPixelX ? mapUnitsPerPixelY : mapUnitsPerPixelX; // calculate the actual extent of the mapCanvas double dxmin = mExtent.xMinimum(), dxmax = mExtent.xMaximum(), dymin = mExtent.yMinimum(), dymax = mExtent.yMaximum(), whitespace; if ( mapUnitsPerPixelY > mapUnitsPerPixelX ) { whitespace = (( myWidth * mMapUnitsPerPixel ) - mExtent.width() ) * 0.5; dxmin -= whitespace; dxmax += whitespace; } else { whitespace = (( myHeight * mMapUnitsPerPixel ) - mExtent.height() ) * 0.5; dymin -= whitespace; dymax += whitespace; } mVisibleExtent.set( dxmin, dymin, dxmax, dymax ); // update the scale mScaleCalculator.setDpi( mDpi ); mScale = mScaleCalculator.calculate( mVisibleExtent, mSize.width() ); mMapToPixel.setParameters( mapUnitsPerPixel(), visibleExtent().center().x(), visibleExtent().center().y(), outputSize().width(), outputSize().height(), mRotation ); #if 1 // set visible extent taking rotation in consideration if ( mRotation ) { QgsPoint p1 = mMapToPixel.toMapCoordinates( QPoint( 0, 0 ) ); QgsPoint p2 = mMapToPixel.toMapCoordinates( QPoint( 0, myHeight ) ); QgsPoint p3 = mMapToPixel.toMapCoordinates( QPoint( myWidth, 0 ) ); QgsPoint p4 = mMapToPixel.toMapCoordinates( QPoint( myWidth, myHeight ) ); dxmin = std::min( p1.x(), std::min( p2.x(), std::min( p3.x(), p4.x() ) ) ); dymin = std::min( p1.y(), std::min( p2.y(), std::min( p3.y(), p4.y() ) ) ); dxmax = std::max( p1.x(), std::max( p2.x(), std::max( p3.x(), p4.x() ) ) ); dymax = std::max( p1.y(), std::max( p2.y(), std::max( p3.y(), p4.y() ) ) ); mVisibleExtent.set( dxmin, dymin, dxmax, dymax ); } #endif QgsDebugMsg( QString( "Map units per pixel (x,y) : %1, %2" ).arg( qgsDoubleToString( mapUnitsPerPixelX ), qgsDoubleToString( mapUnitsPerPixelY ) ) ); QgsDebugMsg( QString( "Pixmap dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mSize.width() ), qgsDoubleToString( mSize.height() ) ) ); QgsDebugMsg( QString( "Extent dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mExtent.width() ), qgsDoubleToString( mExtent.height() ) ) ); QgsDebugMsg( mExtent.toString() ); QgsDebugMsg( QString( "Adjusted map units per pixel (x,y) : %1, %2" ).arg( qgsDoubleToString( mVisibleExtent.width() / myWidth ), qgsDoubleToString( mVisibleExtent.height() / myHeight ) ) ); QgsDebugMsg( QString( "Recalced pixmap dimensions (x,y) : %1, %2" ).arg( qgsDoubleToString( mVisibleExtent.width() / mMapUnitsPerPixel ), qgsDoubleToString( mVisibleExtent.height() / mMapUnitsPerPixel ) ) ); QgsDebugMsg( QString( "Scale (assuming meters as map units) = 1:%1" ).arg( qgsDoubleToString( mScale ) ) ); QgsDebugMsg( QString( "Rotation: %1 degrees" ).arg( mRotation ) ); mValid = true; }