22 #include <QStyleOptionGraphicsItem> 27 #define M_DEG2RAD 0.0174532925 32 double rotToRad = angle * M_PI / 180.0;
34 xRot = x * std::cos( rotToRad ) - y * std::sin( rotToRad );
35 yRot = x * std::sin( rotToRad ) + y * std::cos( rotToRad );
42 double clippedAngle =
angle;
43 if ( clippedAngle >= 360.0 || clippedAngle <= -360.0 )
45 clippedAngle = std::fmod( clippedAngle, 360.0 );
47 if ( !allowNegative && clippedAngle < 0.0 )
49 clippedAngle += 360.0;
60 if ( clippedAngle >= 22.5 && clippedAngle < 67.5 )
64 else if ( clippedAngle >= 67.5 && clippedAngle < 112.5 )
68 else if ( clippedAngle >= 112.5 && clippedAngle < 157.5 )
72 else if ( clippedAngle >= 157.5 && clippedAngle < 202.5 )
76 else if ( clippedAngle >= 202.5 && clippedAngle < 247.5 )
80 else if ( clippedAngle >= 247.5 && clippedAngle < 292.5 )
84 else if ( clippedAngle >= 292.5 && clippedAngle < 337.5 )
100 if ( dpi < 0 && painter && painter->device() )
102 context.
setScaleFactor( painter->device()->logicalDpiX() / 25.4 );
119 dpi = ( painter && painter->device() ) ? painter->device()->logicalDpiX() : 88;
121 double dotsPerMM = dpi / 25.4;
125 QSizeF mapSizeLayoutUnits = map->rect().size();
149 double left =
relativePosition( rectToResize.left(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
150 double right =
relativePosition( rectToResize.right(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
151 double top =
relativePosition( rectToResize.top(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
152 double bottom =
relativePosition( rectToResize.bottom(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
154 rectToResize.setRect( left, top, right - left, bottom - top );
160 double m = ( afterMax - afterMin ) / ( beforeMax - beforeMin );
161 double c = afterMin - ( beforeMin * m );
164 return m * position +
c;
170 QFont scaledFont = font;
171 double pixelSize = pointsToMM( scaledFont.pointSizeF() ) * FONT_WORKAROUND_SCALE + 0.5;
172 scaledFont.setPixelSize( pixelSize );
181 QFontMetricsF fontMetrics( metricsFont );
182 return ( fontMetrics.ascent() / FONT_WORKAROUND_SCALE );
190 QFontMetricsF fontMetrics( metricsFont );
191 return ( fontMetrics.descent() / FONT_WORKAROUND_SCALE );
200 QFontMetricsF fontMetrics( metricsFont );
201 return ( fontMetrics.height() / FONT_WORKAROUND_SCALE );
210 QFontMetricsF fontMetrics( metricsFont );
211 return ( fontMetrics.boundingRect( character ).height() / FONT_WORKAROUND_SCALE );
219 QFontMetricsF fontMetrics( metricsFont );
220 return ( fontMetrics.width( text ) / FONT_WORKAROUND_SCALE );
225 QStringList multiLineSplit = text.split(
'\n' );
226 int lines = multiLineSplit.size();
231 QFontMetricsF fontMetrics( metricsFont );
233 double fontHeight = fontMetrics.ascent() + fontMetrics.descent();
234 double textHeight = fontMetrics.ascent() +
static_cast< double >( ( lines - 1 ) * fontHeight * multiLineHeight );
236 return textHeight / FONT_WORKAROUND_SCALE;
251 painter->setFont( textFont );
252 if ( color.isValid() )
254 painter->setPen( color );
256 double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
257 painter->scale( scaleFactor, scaleFactor );
258 painter->drawText( position * FONT_WORKAROUND_SCALE, text );
262 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 )
273 QRectF scaledRect( rect.x() * FONT_WORKAROUND_SCALE, rect.y() * FONT_WORKAROUND_SCALE,
274 rect.width() * FONT_WORKAROUND_SCALE, rect.height() * FONT_WORKAROUND_SCALE );
277 painter->setFont( textFont );
278 if ( color.isValid() )
280 painter->setPen( color );
282 double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
283 painter->scale( scaleFactor, scaleFactor );
284 painter->drawText( scaledRect, halignment | valignment | flags, text );
290 double originalWidth = originalRect.width();
291 double originalHeight = originalRect.height();
292 double boundsWidth = boundsRect.width();
293 double boundsHeight = boundsRect.height();
294 double ratioBoundsRect = boundsWidth / boundsHeight;
304 rectScale = ( ( originalWidth / originalHeight ) > ratioBoundsRect ) ? boundsWidth / originalWidth : boundsHeight / originalHeight;
308 rectScale = ( ( originalHeight / originalWidth ) > ratioBoundsRect ) ? boundsWidth / originalHeight : boundsHeight / originalWidth;
310 double rectScaledWidth = rectScale * originalWidth;
311 double rectScaledHeight = rectScale * originalHeight;
315 return QRectF( ( boundsWidth - rectScaledWidth ) / 2.0, ( boundsHeight - rectScaledHeight ) / 2.0, rectScaledWidth, rectScaledHeight );
319 return QRectF( ( boundsWidth - rectScaledHeight ) / 2.0, ( boundsHeight - rectScaledWidth ) / 2.0, rectScaledWidth, rectScaledHeight );
324 double angleRad = -clippedRotation *
M_DEG2RAD;
325 double cosAngle = std::cos( angleRad );
326 double sinAngle = std::sin( angleRad );
329 double widthBoundsRotatedRect = originalWidth * std::fabs( cosAngle ) + originalHeight * std::fabs( sinAngle );
330 double heightBoundsRotatedRect = originalHeight * std::fabs( cosAngle ) + originalWidth * std::fabs( sinAngle );
334 double ratioBoundsRotatedRect = widthBoundsRotatedRect / heightBoundsRotatedRect;
335 double rectScale = ratioBoundsRotatedRect > ratioBoundsRect ? boundsWidth / widthBoundsRotatedRect : boundsHeight / heightBoundsRotatedRect;
336 double rectScaledWidth = rectScale * originalWidth;
337 double rectScaledHeight = rectScale * originalHeight;
341 double currentCornerX = 0;
343 currentCornerX += rectScaledWidth * cosAngle;
344 minX = minX < currentCornerX ? minX : currentCornerX;
345 currentCornerX += rectScaledHeight * sinAngle;
346 minX = minX < currentCornerX ? minX : currentCornerX;
347 currentCornerX -= rectScaledWidth * cosAngle;
348 minX = minX < currentCornerX ? minX : currentCornerX;
350 double currentCornerY = 0;
352 currentCornerY -= rectScaledWidth * sinAngle;
353 minY = minY < currentCornerY ? minY : currentCornerY;
354 currentCornerY += rectScaledHeight * cosAngle;
355 minY = minY < currentCornerY ? minY : currentCornerY;
356 currentCornerY += rectScaledWidth * sinAngle;
357 minY = minY < currentCornerY ? minY : currentCornerY;
360 double offsetX = ratioBoundsRotatedRect > ratioBoundsRect ? 0 : ( boundsWidth - rectScale * widthBoundsRotatedRect ) / 2.0;
361 offsetX += std::fabs( minX );
362 double offsetY = ratioBoundsRotatedRect > ratioBoundsRect ? ( boundsHeight - rectScale * heightBoundsRotatedRect ) / 2.0 : 0;
363 offsetY += std::fabs( minY );
365 return QRectF( offsetX, offsetY, rectScaledWidth, rectScaledHeight );
370 QString s =
string.trimmed();
371 if ( s.compare( QLatin1String(
"Portrait" ), Qt::CaseInsensitive ) == 0 )
376 else if ( s.compare( QLatin1String(
"Landscape" ), Qt::CaseInsensitive ) == 0 )
395 return !
qgsDoubleNear( style->matrix.m11(), 0.0 ) ? style->matrix.m11() : style->matrix.m12();
409 const auto layers = project->
mapLayers();
410 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
412 if ( it.value()->name().compare(
string, Qt::CaseInsensitive ) == 0 )
419 double QgsLayoutUtils::pointsToMM(
const double pointSize )
422 return ( pointSize * 0.3527 );
425 double QgsLayoutUtils::mmToPoints(
const double mmSize )
428 return ( mmSize / 0.3527 );
static double snappedAngle(double angle)
Snaps an angle (in degrees) to its closest 45 degree angle.
static double scaleFactorFromItemStyle(const QStyleOptionGraphicsItem *style)
Extracts the scale factor from an item style.
A rectangle specified with double values.
Base class for all map layer types.
void setFlags(QgsRenderContext::Flags flags)
Set combination of flags that will be used for rendering.
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 relativePosition(double position, double beforeMin, double beforeMax, double afterMin, double afterMax)
Returns a scaled position given a before and after range.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all registered layers by layer ID.
static double fontDescentMM(const QFont &font)
Calculate a font descent in millimeters, including workarounds for QT font rendering issues...
QgsLayoutRenderContext & renderContext()
Returns a reference to the layout's render context, which stores information relating to the current ...
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)
The QgsMapSettings class contains configuration for rendering of the map.
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
QgsRectangle extent() const
Returns the current map extent.
Layout graphical items for displaying a map.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
const QgsLayout * layout() const
Returns the layout the object is attached to.
static QgsRenderContext createRenderContextForMap(QgsLayoutItemMap *map, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout map and painter destination.
QgsRenderContext::Flags renderContextFlags() const
Returns the combination of render context flags matched to the layout context's settings.
static QgsRenderContext createRenderContextForLayout(QgsLayout *layout, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout and painter destination.
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 ...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
Reads and writes project states.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
static QgsMapLayer * mapLayerFromString(const QString &string, QgsProject *project)
Resolves a string into a map layer from a given project.
static void rotate(double angle, double &x, double &y)
Rotates a point / vector around the origin.
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 fontHeightMM(const QFont &font)
Calculate a font height in millimeters, including workarounds for QT font rendering issues...
QgsLayoutItemMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the layout is expo...
Contains information about the context of a rendering operation.
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 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, when it is rotated by the a specified rotation amount.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
Orientation
Page orientiation.
QgsLayoutMeasurement convertFromLayoutUnits(double length, QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit...
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
static void relativeResizeRect(QRectF &rectToResize, const QRectF &boundsBefore, const QRectF &boundsAfter)
Resizes a QRectF relative to a resized bounding rectangle.
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 double normalizedAngle(double angle, bool allowNegative=false)
Ensures that an angle (in degrees) is in the range 0 <= angle < 360.
static QgsLayoutItemPage::Orientation decodePaperOrientation(const QString &string, bool &ok)
Decodes a string representing a paper orientation and returns the decoded orientation.