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 const QStringList multiLineSplit = text.split(
'\n' );
226 QFontMetricsF fontMetrics( metricsFont );
229 for (
const QString &line : multiLineSplit )
231 #if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
232 maxWidth = std::max( maxWidth, ( fontMetrics.width( line ) / FONT_WORKAROUND_SCALE ) );
234 maxWidth = std::max( maxWidth, ( fontMetrics.horizontalAdvance( line ) / FONT_WORKAROUND_SCALE ) );
242 QStringList multiLineSplit = text.split(
'\n' );
243 int lines = multiLineSplit.size();
248 QFontMetricsF fontMetrics( metricsFont );
250 double fontHeight = fontMetrics.ascent() + fontMetrics.descent();
251 double textHeight = fontMetrics.ascent() +
static_cast< double >( ( lines - 1 ) * fontHeight * multiLineHeight );
253 return textHeight / FONT_WORKAROUND_SCALE;
268 painter->setFont( textFont );
269 if ( color.isValid() )
271 painter->setPen( color );
273 double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
274 painter->scale( scaleFactor, scaleFactor );
275 painter->drawText( position * FONT_WORKAROUND_SCALE, text );
278 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 )
289 QRectF scaledRect( rect.x() * FONT_WORKAROUND_SCALE, rect.y() * FONT_WORKAROUND_SCALE,
290 rect.width() * FONT_WORKAROUND_SCALE, rect.height() * FONT_WORKAROUND_SCALE );
293 painter->setFont( textFont );
294 if ( color.isValid() )
296 painter->setPen( color );
298 double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
299 painter->scale( scaleFactor, scaleFactor );
300 painter->drawText( scaledRect, halignment | valignment | flags, text );
305 double originalWidth = originalRect.width();
306 double originalHeight = originalRect.height();
307 double boundsWidth = boundsRect.width();
308 double boundsHeight = boundsRect.height();
309 double ratioBoundsRect = boundsWidth / boundsHeight;
319 rectScale = ( ( originalWidth / originalHeight ) > ratioBoundsRect ) ? boundsWidth / originalWidth : boundsHeight / originalHeight;
323 rectScale = ( ( originalHeight / originalWidth ) > ratioBoundsRect ) ? boundsWidth / originalHeight : boundsHeight / originalWidth;
325 double rectScaledWidth = rectScale * originalWidth;
326 double rectScaledHeight = rectScale * originalHeight;
330 return QRectF( ( boundsWidth - rectScaledWidth ) / 2.0, ( boundsHeight - rectScaledHeight ) / 2.0, rectScaledWidth, rectScaledHeight );
334 return QRectF( ( boundsWidth - rectScaledHeight ) / 2.0, ( boundsHeight - rectScaledWidth ) / 2.0, rectScaledWidth, rectScaledHeight );
339 double angleRad = -clippedRotation *
M_DEG2RAD;
340 double cosAngle = std::cos( angleRad );
341 double sinAngle = std::sin( angleRad );
344 double widthBoundsRotatedRect = originalWidth * std::fabs( cosAngle ) + originalHeight * std::fabs( sinAngle );
345 double heightBoundsRotatedRect = originalHeight * std::fabs( cosAngle ) + originalWidth * std::fabs( sinAngle );
349 double ratioBoundsRotatedRect = widthBoundsRotatedRect / heightBoundsRotatedRect;
350 double rectScale = ratioBoundsRotatedRect > ratioBoundsRect ? boundsWidth / widthBoundsRotatedRect : boundsHeight / heightBoundsRotatedRect;
351 double rectScaledWidth = rectScale * originalWidth;
352 double rectScaledHeight = rectScale * originalHeight;
356 double currentCornerX = 0;
358 currentCornerX += rectScaledWidth * cosAngle;
359 minX = minX < currentCornerX ? minX : currentCornerX;
360 currentCornerX += rectScaledHeight * sinAngle;
361 minX = minX < currentCornerX ? minX : currentCornerX;
362 currentCornerX -= rectScaledWidth * cosAngle;
363 minX = minX < currentCornerX ? minX : currentCornerX;
365 double currentCornerY = 0;
367 currentCornerY -= rectScaledWidth * sinAngle;
368 minY = minY < currentCornerY ? minY : currentCornerY;
369 currentCornerY += rectScaledHeight * cosAngle;
370 minY = minY < currentCornerY ? minY : currentCornerY;
371 currentCornerY += rectScaledWidth * sinAngle;
372 minY = minY < currentCornerY ? minY : currentCornerY;
375 double offsetX = ratioBoundsRotatedRect > ratioBoundsRect ? 0 : ( boundsWidth - rectScale * widthBoundsRotatedRect ) / 2.0;
376 offsetX += std::fabs( minX );
377 double offsetY = ratioBoundsRotatedRect > ratioBoundsRect ? ( boundsHeight - rectScale * heightBoundsRotatedRect ) / 2.0 : 0;
378 offsetY += std::fabs( minY );
380 return QRectF( offsetX, offsetY, rectScaledWidth, rectScaledHeight );
385 QString s =
string.trimmed();
386 if ( s.compare( QLatin1String(
"Portrait" ), Qt::CaseInsensitive ) == 0 )
391 else if ( s.compare( QLatin1String(
"Landscape" ), Qt::CaseInsensitive ) == 0 )
410 return !
qgsDoubleNear( style->matrix.m11(), 0.0 ) ? style->matrix.m11() : style->matrix.m12();
424 const auto layers = project->
mapLayers();
425 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
427 if ( it.value()->name().compare(
string, Qt::CaseInsensitive ) == 0 )
437 double s = std::pow( 10.0, std::floor( std::log10( a ) ) ) / d;
438 return std::ceil( a / s ) * s;
444 double s = std::pow( 10.0, std::floor( std::log10( a ) ) ) / d;
445 return std::floor( a / s ) * s;
450 if ( maximumSize < minimumSize )
464 while ( lowerNiceUnitsPerSeg > maximumSize && upperNiceUnitsPerSeg < minimumSize )
472 return upperNiceUnitsPerSeg < minimumSize ? lowerNiceUnitsPerSeg : upperNiceUnitsPerSeg;
482 QList< QgsLayoutItemMap * > maps;
486 if ( map->itemClippingSettings()->isActive() && map->itemClippingSettings()->sourceItem() == item )
492 double QgsLayoutUtils::pointsToMM(
const double pointSize )
495 return ( pointSize * 0.3527 );
498 double QgsLayoutUtils::mmToPoints(
const double mmSize )
501 return ( mmSize / 0.3527 );