23 #include "qgssettings.h" 
   25 #include <QStyleOptionGraphicsItem> 
   30 #define M_DEG2RAD 0.0174532925 
   35   double rotToRad = 
angle * M_PI / 180.0;
 
   37   xRot = x * std::cos( rotToRad ) - y * std::sin( rotToRad );
 
   38   yRot = x * std::sin( rotToRad ) + y * std::cos( rotToRad );
 
   45   double clippedAngle = 
angle;
 
   46   if ( clippedAngle >= 360.0 || clippedAngle <= -360.0 )
 
   48     clippedAngle = std::fmod( clippedAngle, 360.0 );
 
   50   if ( !allowNegative && clippedAngle < 0.0 )
 
   52     clippedAngle += 360.0;
 
   63   if ( clippedAngle >= 22.5 && clippedAngle < 67.5 )
 
   67   else if ( clippedAngle >= 67.5 && clippedAngle < 112.5 )
 
   71   else if ( clippedAngle >= 112.5 && clippedAngle < 157.5 )
 
   75   else if ( clippedAngle >= 157.5 && clippedAngle < 202.5 )
 
   79   else if ( clippedAngle >= 202.5 && clippedAngle < 247.5 )
 
   83   else if ( clippedAngle >= 247.5 && clippedAngle < 292.5 )
 
   87   else if ( clippedAngle >= 292.5 && clippedAngle < 337.5 )
 
  103     if ( dpi < 0 && painter && painter->device() )
 
  105       context.
setScaleFactor( painter->device()->logicalDpiX() / 25.4 );
 
  122       dpi = ( painter && painter->device() ) ? painter->device()->logicalDpiX() : 88;
 
  124     double dotsPerMM = dpi / 25.4;
 
  128     QSizeF mapSizeLayoutUnits = map->rect().size();
 
  157   double left = 
relativePosition( rectToResize.left(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
 
  158   double right = 
relativePosition( rectToResize.right(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
 
  159   double top = 
relativePosition( rectToResize.top(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
 
  160   double bottom = 
relativePosition( rectToResize.bottom(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
 
  162   rectToResize.setRect( left, top, right - left, bottom - top );
 
  168   double m = ( afterMax - afterMin ) / ( beforeMax - beforeMin );
 
  169   double c = afterMin - ( beforeMin * m );
 
  172   return m * position + 
c;
 
  178   QFont scaledFont = font;
 
  179   double pixelSize = pointsToMM( scaledFont.pointSizeF() ) * FONT_WORKAROUND_SCALE + 0.5;
 
  180   scaledFont.setPixelSize( pixelSize );
 
  189   QFontMetricsF fontMetrics( metricsFont );
 
  190   return ( fontMetrics.ascent() / FONT_WORKAROUND_SCALE );
 
  198   QFontMetricsF fontMetrics( metricsFont );
 
  199   return ( fontMetrics.descent() / FONT_WORKAROUND_SCALE );
 
  208   QFontMetricsF fontMetrics( metricsFont );
 
  209   return ( fontMetrics.height() / FONT_WORKAROUND_SCALE );
 
  218   QFontMetricsF fontMetrics( metricsFont );
 
  219   return ( fontMetrics.boundingRect( character ).height() / FONT_WORKAROUND_SCALE );
 
  227   const QStringList multiLineSplit = text.split( 
'\n' );
 
  229   QFontMetricsF fontMetrics( metricsFont );
 
  232   for ( 
const QString &line : multiLineSplit )
 
  234     maxWidth = std::max( maxWidth, ( fontMetrics.horizontalAdvance( line ) / FONT_WORKAROUND_SCALE ) );
 
  241   QStringList multiLineSplit = text.split( 
'\n' );
 
  242   int lines = multiLineSplit.size();
 
  247   QFontMetricsF fontMetrics( metricsFont );
 
  249   double fontHeight = fontMetrics.ascent() + fontMetrics.descent(); 
 
  250   double textHeight = fontMetrics.ascent() + 
static_cast< double >( ( lines - 1 ) * fontHeight * multiLineHeight );
 
  252   return textHeight / FONT_WORKAROUND_SCALE;
 
  267   painter->setFont( textFont );
 
  268   if ( color.isValid() )
 
  270     painter->setPen( color );
 
  272   double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
 
  273   painter->scale( scaleFactor, scaleFactor );
 
  274   painter->drawText( position * FONT_WORKAROUND_SCALE, text );
 
  277 void QgsLayoutUtils::drawText( QPainter *painter, 
const QRectF &rect, 
const QString &text, 
const QFont &font, 
const QColor &color, 
const Qt::AlignmentFlag halignment, 
const Qt::AlignmentFlag valignment, 
const int flags )
 
  288   QRectF scaledRect( rect.x() * FONT_WORKAROUND_SCALE, rect.y() * FONT_WORKAROUND_SCALE,
 
  289                      rect.width() * FONT_WORKAROUND_SCALE, rect.height() * FONT_WORKAROUND_SCALE );
 
  292   painter->setFont( textFont );
 
  293   if ( color.isValid() )
 
  295     painter->setPen( color );
 
  297   double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
 
  298   painter->scale( scaleFactor, scaleFactor );
 
  299   painter->drawText( scaledRect, halignment | valignment | flags, text );
 
  304   double originalWidth = originalRect.width();
 
  305   double originalHeight = originalRect.height();
 
  306   double boundsWidth = boundsRect.width();
 
  307   double boundsHeight = boundsRect.height();
 
  308   double ratioBoundsRect = boundsWidth / boundsHeight;
 
  318       rectScale = ( ( originalWidth / originalHeight ) > ratioBoundsRect ) ? boundsWidth / originalWidth : boundsHeight / originalHeight;
 
  322       rectScale = ( ( originalHeight / originalWidth ) > ratioBoundsRect ) ? boundsWidth / originalHeight : boundsHeight / originalWidth;
 
  324     double rectScaledWidth = rectScale * originalWidth;
 
  325     double rectScaledHeight = rectScale * originalHeight;
 
  329       return QRectF( ( boundsWidth - rectScaledWidth ) / 2.0, ( boundsHeight - rectScaledHeight ) / 2.0, rectScaledWidth, rectScaledHeight );
 
  333       return QRectF( ( boundsWidth - rectScaledHeight ) / 2.0, ( boundsHeight - rectScaledWidth ) / 2.0, rectScaledWidth, rectScaledHeight );
 
  338   double angleRad = -clippedRotation * 
M_DEG2RAD;
 
  339   double cosAngle = std::cos( angleRad );
 
  340   double sinAngle = std::sin( angleRad );
 
  343   double widthBoundsRotatedRect = originalWidth * std::fabs( cosAngle ) + originalHeight * std::fabs( sinAngle );
 
  344   double heightBoundsRotatedRect = originalHeight * std::fabs( cosAngle ) + originalWidth * std::fabs( sinAngle );
 
  348   double ratioBoundsRotatedRect = widthBoundsRotatedRect / heightBoundsRotatedRect;
 
  349   double rectScale = ratioBoundsRotatedRect > ratioBoundsRect ? boundsWidth / widthBoundsRotatedRect : boundsHeight / heightBoundsRotatedRect;
 
  350   double rectScaledWidth = rectScale * originalWidth;
 
  351   double rectScaledHeight = rectScale * originalHeight;
 
  355   double currentCornerX = 0;
 
  357   currentCornerX += rectScaledWidth * cosAngle;
 
  358   minX = minX < currentCornerX ? minX : currentCornerX;
 
  359   currentCornerX += rectScaledHeight * sinAngle;
 
  360   minX = minX < currentCornerX ? minX : currentCornerX;
 
  361   currentCornerX -= rectScaledWidth * cosAngle;
 
  362   minX = minX < currentCornerX ? minX : currentCornerX;
 
  364   double currentCornerY = 0;
 
  366   currentCornerY -= rectScaledWidth * sinAngle;
 
  367   minY = minY < currentCornerY ? minY : currentCornerY;
 
  368   currentCornerY += rectScaledHeight * cosAngle;
 
  369   minY = minY < currentCornerY ? minY : currentCornerY;
 
  370   currentCornerY += rectScaledWidth * sinAngle;
 
  371   minY = minY < currentCornerY ? minY : currentCornerY;
 
  374   double offsetX = ratioBoundsRotatedRect > ratioBoundsRect ? 0 : ( boundsWidth - rectScale * widthBoundsRotatedRect ) / 2.0;
 
  375   offsetX += std::fabs( minX );
 
  376   double offsetY = ratioBoundsRotatedRect > ratioBoundsRect ? ( boundsHeight - rectScale * heightBoundsRotatedRect ) / 2.0 : 0;
 
  377   offsetY += std::fabs( minY );
 
  379   return QRectF( offsetX, offsetY, rectScaledWidth, rectScaledHeight );
 
  384   QString s = 
string.trimmed();
 
  385   if ( s.compare( QLatin1String( 
"Portrait" ), Qt::CaseInsensitive ) == 0 )
 
  390   else if ( s.compare( QLatin1String( 
"Landscape" ), Qt::CaseInsensitive ) == 0 )
 
  401 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
  410   return !
qgsDoubleNear( style->matrix.m11(), 0.0 ) ? style->matrix.m11() : style->matrix.m12();
 
  419   return style->levelOfDetailFromTransform( painter->worldTransform() );
 
  433   const auto layers = project->
mapLayers();
 
  434   for ( 
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
 
  436     if ( it.value()->name().compare( 
string, Qt::CaseInsensitive ) == 0 )
 
  446   double s = std::pow( 10.0, std::floor( std::log10( a ) ) ) / d;
 
  447   return std::ceil( a / s ) * s;
 
  453   double s = std::pow( 10.0, std::floor( std::log10( a ) ) ) / d;
 
  454   return std::floor( a / s ) * s;
 
  459   if ( maximumSize < minimumSize )
 
  473     while ( lowerNiceUnitsPerSeg > maximumSize && upperNiceUnitsPerSeg < minimumSize )
 
  481     return upperNiceUnitsPerSeg < minimumSize ? lowerNiceUnitsPerSeg : upperNiceUnitsPerSeg;
 
  491   QList< QgsLayoutItemMap * > maps;
 
  495     if ( map->itemClippingSettings()->isActive() && map->itemClippingSettings()->sourceItem() == item )
 
  501 double QgsLayoutUtils::pointsToMM( 
const double pointSize )
 
  504   return ( pointSize * 0.3527 );
 
  507 double QgsLayoutUtils::mmToPoints( 
const double mmSize )
 
  510   return ( mmSize / 0.3527 );
 
  515   QVector< double > mapScales;
 
  520   if ( !hasProjectScales || mapScales.isEmpty() )
 
  523     QgsSettings settings;
 
  525     const QStringList scales = scalesStr.split( 
',' );
 
  526     for ( 
const QString &scale : scales )
 
  528       QStringList parts( scale.split( 
':' ) );
 
  529       if ( parts.size() == 2 )
 
  531         mapScales.push_back( parts[1].toDouble() );
 
static QString defaultProjectScales()
A string with default project scales.
Layout graphical items for displaying a map.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
QgsRectangle extent() const
Returns the current map extent.
Orientation
Page orientation.
@ Landscape
Landscape orientation.
@ Portrait
Portrait orientation.
Base class for graphical items within a QgsLayout.
@ FlagProvidesClipPath
Item can act as a clipping path provider (see clipPath())
virtual Flags itemFlags() const
Returns the item's flags, which indicate how the item behaves.
const QgsLayout * layout() const
Returns the layout the object is attached to.
QgsRenderContext::Flags renderContextFlags() const
Returns the combination of render context flags matched to the layout context's settings.
QgsRenderContext::TextRenderFormat textRenderFormat() const
Returns the text render format, which dictates how text is rendered (e.g.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
static QVector< double > predefinedScales(const QgsLayout *layout)
Returns a list of predefined scales associated with a layout.
static double fontHeightMM(const QFont &font)
Calculate a font height in millimeters, including workarounds for QT font rendering issues.
static double relativePosition(double position, double beforeMin, double beforeMax, double afterMin, double afterMax)
Returns a scaled position given a before and after range.
static double fontDescentMM(const QFont &font)
Calculate a font descent in millimeters, including workarounds for QT font rendering issues.
static double fontAscentMM(const QFont &font)
Calculates a font ascent in millimeters, including workarounds for QT font rendering issues.
static QRectF largestRotatedRectWithinBounds(const QRectF &originalRect, const QRectF &boundsRect, double rotation)
Calculates the largest scaled version of originalRect which fits within boundsRect,...
static QFont scaledFontPixelSize(const QFont &font)
Returns a font where size is set in points and the size has been upscaled with FONT_WORKAROUND_SCALE ...
static QgsRenderContext createRenderContextForMap(QgsLayoutItemMap *map, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout map and painter destination.
static bool itemIsAClippingSource(const QgsLayoutItem *item)
Returns true if an item is a clipping item for another layout item.
static double snappedAngle(double angle)
Snaps an angle (in degrees) to its closest 45 degree angle.
static double textHeightMM(const QFont &font, const QString &text, double multiLineHeight=1.0)
Calculate a font height in millimeters for a text string, including workarounds for QT font rendering...
static QgsLayoutItemPage::Orientation decodePaperOrientation(const QString &string, bool &ok)
Decodes a string representing a paper orientation and returns the decoded orientation.
static void rotate(double angle, double &x, double &y)
Rotates a point / vector around the origin.
static double fontHeightCharacterMM(const QFont &font, QChar character)
Calculate a font height in millimeters of a single character, including workarounds for QT font rende...
static double normalizedAngle(double angle, bool allowNegative=false)
Ensures that an angle (in degrees) is in the range 0 <= angle < 360.
static void drawText(QPainter *painter, QPointF position, const QString &text, const QFont &font, const QColor &color=QColor())
Draws text on a painter at a specific position, taking care of layout specific issues (calculation to...
static double textWidthMM(const QFont &font, const QString &text)
Calculate a font width in millimeters for a text string, including workarounds for QT font rendering ...
static double calculatePrettySize(double minimumSize, double maximumSize)
Calculates a "pretty" size which falls between the range [minimumSize, maximumSize].
static QgsMapLayer * mapLayerFromString(const QString &string, QgsProject *project)
Resolves a string into a map layer from a given project.
static Q_DECL_DEPRECATED double scaleFactorFromItemStyle(const QStyleOptionGraphicsItem *style)
Extracts the scale factor from an item style.
static void relativeResizeRect(QRectF &rectToResize, const QRectF &boundsBefore, const QRectF &boundsAfter)
Resizes a QRectF relative to a resized bounding rectangle.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
void layoutItems(QList< T * > &itemList) const
Returns a list of layout items of a specific type.
QgsLayoutItemMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the layout is expo...
QgsLayoutMeasurement convertFromLayoutUnits(double length, QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit.
QgsProject * project() const
The project associated with the layout.
Base class for all map layer types.
The QgsMapSettings class contains configuration for rendering of the map.
bool useProjectScales() const
Returns true if project mapScales() are enabled.
QVector< double > mapScales() const
Returns the list of custom project map scales.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
A rectangle specified with double values.
Contains information about the context of a rendering operation.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
void setTextRenderFormat(TextRenderFormat format)
Sets the text render format, which dictates how text is rendered (e.g.
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
void setFlags(QgsRenderContext::Flags flags)
Set combination of flags that will be used for rendering.
Scoped object for saving and restoring a QPainter object's state.
@ LayoutMillimeters
Millimeters.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
double prevNiceNumber(double a, double d=1)
double nextNiceNumber(double a, double d=1)