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();
154 double left =
relativePosition( rectToResize.left(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
155 double right =
relativePosition( rectToResize.right(), boundsBefore.left(), boundsBefore.right(), boundsAfter.left(), boundsAfter.right() );
156 double top =
relativePosition( rectToResize.top(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
157 double bottom =
relativePosition( rectToResize.bottom(), boundsBefore.top(), boundsBefore.bottom(), boundsAfter.top(), boundsAfter.bottom() );
159 rectToResize.setRect( left, top, right - left, bottom - top );
165 double m = ( afterMax - afterMin ) / ( beforeMax - beforeMin );
166 double c = afterMin - ( beforeMin * m );
169 return m * position +
c;
175 QFont scaledFont = font;
176 double pixelSize = pointsToMM( scaledFont.pointSizeF() ) * FONT_WORKAROUND_SCALE + 0.5;
177 scaledFont.setPixelSize( pixelSize );
186 QFontMetricsF fontMetrics( metricsFont );
187 return ( fontMetrics.ascent() / FONT_WORKAROUND_SCALE );
195 QFontMetricsF fontMetrics( metricsFont );
196 return ( fontMetrics.descent() / FONT_WORKAROUND_SCALE );
205 QFontMetricsF fontMetrics( metricsFont );
206 return ( fontMetrics.height() / FONT_WORKAROUND_SCALE );
215 QFontMetricsF fontMetrics( metricsFont );
216 return ( fontMetrics.boundingRect( character ).height() / FONT_WORKAROUND_SCALE );
224 QFontMetricsF fontMetrics( metricsFont );
225 return ( fontMetrics.width( text ) / FONT_WORKAROUND_SCALE );
230 QStringList multiLineSplit = text.split(
'\n' );
231 int lines = multiLineSplit.size();
236 QFontMetricsF fontMetrics( metricsFont );
238 double fontHeight = fontMetrics.ascent() + fontMetrics.descent();
239 double textHeight = fontMetrics.ascent() +
static_cast< double >( ( lines - 1 ) * fontHeight * multiLineHeight );
241 return textHeight / FONT_WORKAROUND_SCALE;
256 painter->setFont( textFont );
257 if ( color.isValid() )
259 painter->setPen( color );
261 double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
262 painter->scale( scaleFactor, scaleFactor );
263 painter->drawText( position * FONT_WORKAROUND_SCALE, text );
267 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 )
278 QRectF scaledRect( rect.x() * FONT_WORKAROUND_SCALE, rect.y() * FONT_WORKAROUND_SCALE,
279 rect.width() * FONT_WORKAROUND_SCALE, rect.height() * FONT_WORKAROUND_SCALE );
282 painter->setFont( textFont );
283 if ( color.isValid() )
285 painter->setPen( color );
287 double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
288 painter->scale( scaleFactor, scaleFactor );
289 painter->drawText( scaledRect, halignment | valignment | flags, text );
295 double originalWidth = originalRect.width();
296 double originalHeight = originalRect.height();
297 double boundsWidth = boundsRect.width();
298 double boundsHeight = boundsRect.height();
299 double ratioBoundsRect = boundsWidth / boundsHeight;
309 rectScale = ( ( originalWidth / originalHeight ) > ratioBoundsRect ) ? boundsWidth / originalWidth : boundsHeight / originalHeight;
313 rectScale = ( ( originalHeight / originalWidth ) > ratioBoundsRect ) ? boundsWidth / originalHeight : boundsHeight / originalWidth;
315 double rectScaledWidth = rectScale * originalWidth;
316 double rectScaledHeight = rectScale * originalHeight;
320 return QRectF( ( boundsWidth - rectScaledWidth ) / 2.0, ( boundsHeight - rectScaledHeight ) / 2.0, rectScaledWidth, rectScaledHeight );
324 return QRectF( ( boundsWidth - rectScaledHeight ) / 2.0, ( boundsHeight - rectScaledWidth ) / 2.0, rectScaledWidth, rectScaledHeight );
329 double angleRad = -clippedRotation *
M_DEG2RAD;
330 double cosAngle = std::cos( angleRad );
331 double sinAngle = std::sin( angleRad );
334 double widthBoundsRotatedRect = originalWidth * std::fabs( cosAngle ) + originalHeight * std::fabs( sinAngle );
335 double heightBoundsRotatedRect = originalHeight * std::fabs( cosAngle ) + originalWidth * std::fabs( sinAngle );
339 double ratioBoundsRotatedRect = widthBoundsRotatedRect / heightBoundsRotatedRect;
340 double rectScale = ratioBoundsRotatedRect > ratioBoundsRect ? boundsWidth / widthBoundsRotatedRect : boundsHeight / heightBoundsRotatedRect;
341 double rectScaledWidth = rectScale * originalWidth;
342 double rectScaledHeight = rectScale * originalHeight;
346 double currentCornerX = 0;
348 currentCornerX += rectScaledWidth * cosAngle;
349 minX = minX < currentCornerX ? minX : currentCornerX;
350 currentCornerX += rectScaledHeight * sinAngle;
351 minX = minX < currentCornerX ? minX : currentCornerX;
352 currentCornerX -= rectScaledWidth * cosAngle;
353 minX = minX < currentCornerX ? minX : currentCornerX;
355 double currentCornerY = 0;
357 currentCornerY -= rectScaledWidth * sinAngle;
358 minY = minY < currentCornerY ? minY : currentCornerY;
359 currentCornerY += rectScaledHeight * cosAngle;
360 minY = minY < currentCornerY ? minY : currentCornerY;
361 currentCornerY += rectScaledWidth * sinAngle;
362 minY = minY < currentCornerY ? minY : currentCornerY;
365 double offsetX = ratioBoundsRotatedRect > ratioBoundsRect ? 0 : ( boundsWidth - rectScale * widthBoundsRotatedRect ) / 2.0;
366 offsetX += std::fabs( minX );
367 double offsetY = ratioBoundsRotatedRect > ratioBoundsRect ? ( boundsHeight - rectScale * heightBoundsRotatedRect ) / 2.0 : 0;
368 offsetY += std::fabs( minY );
370 return QRectF( offsetX, offsetY, rectScaledWidth, rectScaledHeight );
375 QString s =
string.trimmed();
376 if ( s.compare( QLatin1String(
"Portrait" ), Qt::CaseInsensitive ) == 0 )
381 else if ( s.compare( QLatin1String(
"Landscape" ), Qt::CaseInsensitive ) == 0 )
400 return !
qgsDoubleNear( style->matrix.m11(), 0.0 ) ? style->matrix.m11() : style->matrix.m12();
414 const auto layers = project->
mapLayers();
415 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
417 if ( it.value()->name().compare(
string, Qt::CaseInsensitive ) == 0 )
424 double QgsLayoutUtils::pointsToMM(
const double pointSize )
427 return ( pointSize * 0.3527 );
430 double QgsLayoutUtils::mmToPoints(
const double mmSize )
433 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.
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Returns map settings that will be used for drawing of the map.
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.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsLayoutMeasurement convertFromLayoutUnits(double length, QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit...
QgsRenderContext::TextRenderFormat textRenderFormat() const
Returns the text render format, which dictates how text is rendered (e.g.
QgsLayoutItemMap * referenceMap() const
Returns the map item which will be used to generate corresponding world files when the layout is expo...
static double fontDescentMM(const QFont &font)
Calculate a font descent in millimeters, including workarounds for QT font rendering issues...
void setTextRenderFormat(TextRenderFormat format)
Sets the text render format, which dictates how text is rendered (e.g.
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
QgsRenderContext::Flags renderContextFlags() const
Returns the combination of render context flags matched to the layout context's settings.
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.
static QgsRenderContext createRenderContextForMap(QgsLayoutItemMap *map, QPainter *painter, double dpi=-1)
Creates a render context suitable for the specified layout map and painter destination.
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.
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...
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
static double fontHeightMM(const QFont &font)
Calculate a font height in millimeters, including workarounds for QT font rendering issues...
QgsRectangle extent() const
Returns the current map extent.
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...
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
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.
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...
const QgsLayout * layout() const
Returns the layout the object is attached to.
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.
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all registered layers by layer ID.