Skip to content
Permalink
Browse files
Expose percentage as unit option for point/line pattern fill offset
and displacement widgets
  • Loading branch information
nyalldawson committed Oct 27, 2021
1 parent 6c95845 commit a0b87530d41601866ed89cdb4adb89e14111e2b9
Showing with 50 additions and 29 deletions.
  1. +45 −24 src/core/symbology/qgsfillsymbollayer.cpp
  2. +5 −5 src/gui/symbology/qgssymbollayerwidget.cpp
@@ -2580,7 +2580,7 @@ void QgsLinePatternFillSymbolLayer::setOutputUnit( QgsUnitTypes::RenderUnit unit
QgsUnitTypes::RenderUnit QgsLinePatternFillSymbolLayer::outputUnit() const
{
QgsUnitTypes::RenderUnit unit = QgsImageFillSymbolLayer::outputUnit();
if ( mDistanceUnit != unit || mLineWidthUnit != unit || mOffsetUnit != unit )
if ( mDistanceUnit != unit || mLineWidthUnit != unit || ( mOffsetUnit != unit && mOffsetUnit != QgsUnitTypes::RenderPercentage ) )
{
return QgsUnitTypes::RenderUnknownUnit;
}
@@ -2750,7 +2750,8 @@ void QgsLinePatternFillSymbolLayer::applyPattern( const QgsSymbolRenderContext &
const QgsRenderContext &ctx = context.renderContext();
//double strokePixelWidth = lineWidth * QgsSymbolLayerUtils::pixelSizeScaleFactor( ctx, mLineWidthUnit, mLineWidthMapUnitScale );
double outputPixelDist = ctx.convertToPainterUnits( distance, mDistanceUnit, mDistanceMapUnitScale );
double outputPixelOffset = ctx.convertToPainterUnits( mOffset, mOffsetUnit, mOffsetMapUnitScale );
double outputPixelOffset = mOffsetUnit == QgsUnitTypes::RenderPercentage ? outputPixelDist * mOffset / 100
: ctx.convertToPainterUnits( mOffset, mOffsetUnit, mOffsetMapUnitScale );

// NOTE: this may need to be modified if we ever change from a forced rasterized/brush approach,
// because potentially we may want to allow vector based line pattern fills where the first line
@@ -3081,12 +3082,8 @@ void QgsLinePatternFillSymbolLayer::renderPolygon( const QPolygonF &points, cons
const double outputPixelDistance = context.renderContext().convertToPainterUnits( distance, mDistanceUnit, mDistanceMapUnitScale );

double offset = mOffset;
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyLineDistance ) )
{
context.setOriginalValueVariable( mDistance );
distance = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyLineDistance, context.renderContext().expressionContext(), mDistance );
}
double outputPixelOffset = context.renderContext().convertToPainterUnits( offset, mOffsetUnit, mOffsetMapUnitScale );
double outputPixelOffset = mOffsetUnit == QgsUnitTypes::RenderPercentage ? outputPixelDistance * offset / 100
: context.renderContext().convertToPainterUnits( offset, mOffsetUnit, mOffsetMapUnitScale );

// fix truncated pattern with larger offsets
outputPixelOffset = std::fmod( outputPixelOffset, outputPixelDistance );
@@ -3450,11 +3447,15 @@ void QgsPointPatternFillSymbolLayer::setOutputUnit( QgsUnitTypes::RenderUnit uni
QgsImageFillSymbolLayer::setOutputUnit( unit );
mDistanceXUnit = unit;
mDistanceYUnit = unit;
mDisplacementXUnit = unit;
mDisplacementYUnit = unit;
mOffsetXUnit = unit;
mOffsetYUnit = unit;
// don't change "percentage" units -- since they adapt directly to whatever other unit is set
if ( mDisplacementXUnit != QgsUnitTypes::RenderPercentage )
mDisplacementXUnit = unit;
if ( mDisplacementYUnit != QgsUnitTypes::RenderPercentage )
mDisplacementYUnit = unit;
if ( mOffsetXUnit != QgsUnitTypes::RenderPercentage )
mOffsetXUnit = unit;
if ( mOffsetYUnit != QgsUnitTypes::RenderPercentage )
mOffsetYUnit = unit;
if ( mRandomDeviationXUnit != QgsUnitTypes::RenderPercentage )
mRandomDeviationXUnit = unit;
if ( mRandomDeviationYUnit != QgsUnitTypes::RenderPercentage )
@@ -3471,10 +3472,10 @@ QgsUnitTypes::RenderUnit QgsPointPatternFillSymbolLayer::outputUnit() const
QgsUnitTypes::RenderUnit unit = QgsImageFillSymbolLayer::outputUnit();
if ( mDistanceXUnit != unit ||
mDistanceYUnit != unit ||
mDisplacementXUnit != unit ||
mDisplacementYUnit != unit ||
mOffsetXUnit != unit ||
mOffsetYUnit != unit ||
( mDisplacementXUnit != QgsUnitTypes::RenderPercentage && mDisplacementXUnit != unit ) ||
( mDisplacementYUnit != QgsUnitTypes::RenderPercentage && mDisplacementYUnit != unit ) ||
( mOffsetXUnit != QgsUnitTypes::RenderPercentage && mOffsetXUnit != unit ) ||
( mOffsetYUnit != QgsUnitTypes::RenderPercentage && mOffsetYUnit != unit ) ||
( mRandomDeviationXUnit != QgsUnitTypes::RenderPercentage && mRandomDeviationXUnit != unit ) ||
( mRandomDeviationYUnit != QgsUnitTypes::RenderPercentage && mRandomDeviationYUnit != unit ) )
{
@@ -3679,8 +3680,12 @@ void QgsPointPatternFillSymbolLayer::applyPattern( const QgsSymbolRenderContext
double width = ctx.convertToPainterUnits( distanceX, mDistanceXUnit, mDistanceXMapUnitScale ) * 2.0;
double height = ctx.convertToPainterUnits( distanceY, mDistanceYUnit, mDisplacementYMapUnitScale ) * 2.0;

double widthOffset = std::fmod( ctx.convertToPainterUnits( offsetX, mOffsetXUnit, mOffsetXMapUnitScale ), width );
double heightOffset = std::fmod( ctx.convertToPainterUnits( offsetY, mOffsetYUnit, mOffsetYMapUnitScale ), height );
double widthOffset = std::fmod(
mOffsetXUnit == QgsUnitTypes::RenderPercentage ? ( width * offsetX / 200 ) : ctx.convertToPainterUnits( offsetX, mOffsetXUnit, mOffsetXMapUnitScale ),
width );
double heightOffset = std::fmod(
mOffsetYUnit == QgsUnitTypes::RenderPercentage ? ( height * offsetY / 200 ) : ctx.convertToPainterUnits( offsetY, mOffsetYUnit, mOffsetYMapUnitScale ),
height );

if ( width > 10000 || height > 10000 ) //protect symbol layer from eating too much memory
{
@@ -3729,8 +3734,12 @@ void QgsPointPatternFillSymbolLayer::applyPattern( const QgsSymbolRenderContext
}

//render displaced points
double displacementPixelX = ctx.convertToPainterUnits( displacementX, mDisplacementXUnit, mDisplacementXMapUnitScale );
double displacementPixelY = ctx.convertToPainterUnits( displacementY, mDisplacementYUnit, mDisplacementYMapUnitScale );
double displacementPixelX = mDisplacementXUnit == QgsUnitTypes::RenderPercentage
? ( width * displacementX / 200 )
: ctx.convertToPainterUnits( displacementX, mDisplacementXUnit, mDisplacementXMapUnitScale );
double displacementPixelY = mDisplacementYUnit == QgsUnitTypes::RenderPercentage
? ( height * displacementY / 200 )
: ctx.convertToPainterUnits( displacementY, mDisplacementYUnit, mDisplacementYMapUnitScale );
for ( double currentX = -width; currentX <= width * 2.0; currentX += width )
{
for ( double currentY = -height / 2.0; currentY <= height * 2.0; currentY += height )
@@ -3857,31 +3866,43 @@ void QgsPointPatternFillSymbolLayer::renderPolygon( const QPolygonF &points, con
context.setOriginalValueVariable( mOffsetX );
offsetX = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyOffsetX, context.renderContext().expressionContext(), mOffsetX );
}
const double widthOffset = std::fmod( context.renderContext().convertToPainterUnits( offsetX, mOffsetXUnit, mOffsetXMapUnitScale ), width );
const double widthOffset = std::fmod(
mOffsetXUnit == QgsUnitTypes::RenderPercentage
? ( offsetX * width / 100 )
: context.renderContext().convertToPainterUnits( offsetX, mOffsetXUnit, mOffsetXMapUnitScale ),
width );

double offsetY = mOffsetY;
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyOffsetY ) )
{
context.setOriginalValueVariable( mOffsetY );
offsetY = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyOffsetY, context.renderContext().expressionContext(), mOffsetY );
}
const double heightOffset = std::fmod( context.renderContext().convertToPainterUnits( offsetY, mOffsetYUnit, mOffsetYMapUnitScale ), height );
const double heightOffset = std::fmod(
mOffsetYUnit == QgsUnitTypes::RenderPercentage
? ( offsetY * height / 100 )
: context.renderContext().convertToPainterUnits( offsetY, mOffsetYUnit, mOffsetYMapUnitScale ),
height );

double displacementX = mDisplacementX;
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyDisplacementX ) )
{
context.setOriginalValueVariable( mDisplacementX );
displacementX = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyDisplacementX, context.renderContext().expressionContext(), mDisplacementX );
}
const double displacementPixelX = context.renderContext().convertToPainterUnits( displacementX, mDisplacementXUnit, mDisplacementXMapUnitScale );
const double displacementPixelX = mDisplacementXUnit == QgsUnitTypes::RenderPercentage
? ( displacementX * width / 100 )
: context.renderContext().convertToPainterUnits( displacementX, mDisplacementXUnit, mDisplacementXMapUnitScale );

double displacementY = mDisplacementY;
if ( mDataDefinedProperties.isActive( QgsSymbolLayer::PropertyDisplacementY ) )
{
context.setOriginalValueVariable( mDisplacementY );
displacementY = mDataDefinedProperties.valueAsDouble( QgsSymbolLayer::PropertyDisplacementY, context.renderContext().expressionContext(), mDisplacementY );
}
const double displacementPixelY = context.renderContext().convertToPainterUnits( displacementY, mDisplacementYUnit, mDisplacementYMapUnitScale );
const double displacementPixelY = mDisplacementYUnit == QgsUnitTypes::RenderPercentage
? ( displacementY * height / 100 )
: context.renderContext().convertToPainterUnits( displacementY, mDisplacementYUnit, mDisplacementYMapUnitScale );

p->setPen( QPen( Qt::NoPen ) );

@@ -3081,7 +3081,7 @@ QgsLinePatternFillSymbolLayerWidget::QgsLinePatternFillSymbolLayerWidget( QgsVec
mDistanceUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
mOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches << QgsUnitTypes::RenderPercentage );
mOffsetSpinBox->setClearValue( 0 );
mAngleSpinBox->setClearValue( 0 );

@@ -3221,13 +3221,13 @@ QgsPointPatternFillSymbolLayerWidget::QgsPointPatternFillSymbolLayerWidget( QgsV
mVerticalDistanceUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
mHorizontalDisplacementUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches << QgsUnitTypes::RenderPercentage );
mVerticalDisplacementUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches << QgsUnitTypes::RenderPercentage );
mHorizontalOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches << QgsUnitTypes::RenderPercentage );
mVerticalOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches << QgsUnitTypes::RenderPercentage );

mClipModeComboBox->addItem( tr( "Clip to Shape" ), static_cast< int >( Qgis::MarkerClipMode::Shape ) );
mClipModeComboBox->addItem( tr( "Marker Centroid Within Shape" ), static_cast< int >( Qgis::MarkerClipMode::CentroidWithin ) );

0 comments on commit a0b8753

Please sign in to comment.