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();
398 double QgsLayoutUtils::pointsToMM(
const double pointSize )
401 return ( pointSize * 0.3527 );
404 double QgsLayoutUtils::mmToPoints(
const double mmSize )
407 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.
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 ...
QgsMapSettings mapSettings(const QgsRectangle &extent, QSizeF size, double dpi, bool includeLayerSettings) const
Return map settings that will be used for drawing of the map.
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 ...
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
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.
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.
Base class for layouts, which can contain items such as maps, labels, scalebars, etc.
static void rotate(double angle, double &x, double &y)
Rotates a point / vector around the origin.
static double normalizedAngle(const double angle, const 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 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 relativePosition(const double position, const double beforeMin, const double beforeMax, const double afterMin, const double afterMax)
Returns a scaled position given a before and after range.
static double fontAscentMM(const QFont &font)
Calculates a font ascent in millimeters, including workarounds for QT font rendering issues...
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
QgsLayoutMeasurement convertFromLayoutUnits(const double length, const QgsUnitTypes::LayoutUnit unit) const
Converts a length measurement from the layout's native units to a specified target unit...
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...
static QRectF largestRotatedRectWithinBounds(const QRectF &originalRect, const QRectF &boundsRect, const double rotation)
Calculates the largest scaled version of originalRect which fits within boundsRect, when it is rotated by the a specified rotation amount.
static QgsLayoutItemPage::Orientation decodePaperOrientation(const QString &string, bool &ok)
Decodes a string representing a paper orientation and returns the decoded orientation.