Skip to content

Commit

Permalink
Output units for svg fill
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Mar 13, 2013
1 parent 4c49cf3 commit 52611c1
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 42 deletions.
60 changes: 50 additions & 10 deletions src/core/symbology-ng/qgsfillsymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::createFromSld( QDomElement &elemen

//QgsImageFillSymbolLayer

QgsImageFillSymbolLayer::QgsImageFillSymbolLayer(): mOutlineWidth( 0.0 ), mOutline( 0 )
QgsImageFillSymbolLayer::QgsImageFillSymbolLayer(): mOutlineWidth( 0.0 ), mOutlineWidthUnit( QgsSymbolV2::MM ), mOutline( 0 )
{
setSubSymbol( new QgsLineSymbolV2() );
}
Expand Down Expand Up @@ -327,7 +327,8 @@ bool QgsImageFillSymbolLayer::setSubSymbol( QgsSymbolV2* symbol )

//QgsSVGFillSymbolLayer

QgsSVGFillSymbolLayer::QgsSVGFillSymbolLayer( const QString& svgFilePath, double width, double angle ): QgsImageFillSymbolLayer(), mPatternWidth( width )
QgsSVGFillSymbolLayer::QgsSVGFillSymbolLayer( const QString& svgFilePath, double width, double angle ): QgsImageFillSymbolLayer(), mPatternWidth( width ),
mPatternWidthUnit( QgsSymbolV2::MM ), mSvgOutlineWidthUnit( QgsSymbolV2::MM )
{
setSvgFilePath( svgFilePath );
mOutlineWidth = 0.3;
Expand All @@ -353,6 +354,23 @@ QgsSVGFillSymbolLayer::~QgsSVGFillSymbolLayer()
delete mSvgPattern;
}

void QgsSVGFillSymbolLayer::setOutputUnit( QgsSymbolV2::OutputUnit unit )
{
mPatternWidthUnit = unit;
mSvgOutlineWidthUnit = unit;
mOutlineWidthUnit = unit;
}

QgsSymbolV2::OutputUnit QgsSVGFillSymbolLayer::outputUnit() const
{
QgsSymbolV2::OutputUnit unit = mPatternWidthUnit;
if ( mSvgOutlineWidthUnit != unit || mOutlineWidthUnit != unit )
{
return QgsSymbolV2::Mixed;
}
return unit;
}

void QgsSVGFillSymbolLayer::setSvgFilePath( const QString& svgPath )
{
mSvgData = QgsSvgCache::instance()->getImageData( svgPath );
Expand Down Expand Up @@ -412,6 +430,19 @@ QgsSymbolLayerV2* QgsSVGFillSymbolLayer::create( const QgsStringMap& properties
symbolLayer->setSvgOutlineWidth( properties["svgOutlineWidth"].toDouble() );
}

//units
if ( properties.contains( "pattern_width_unit" ) )
{
symbolLayer->setPatternWidthUnit( QgsSymbolLayerV2Utils::decodeOutputUnit( properties["pattern_width_unit"] ) );
}
if ( properties.contains( "svg_outline_width_unit" ) )
{
symbolLayer->setSvgOutlineWidthUnit( QgsSymbolLayerV2Utils::decodeOutputUnit( properties["svg_outline_width_unit"] ) );
}
if ( properties.contains( "outline_width_unit" ) )
{
symbolLayer->setOutlineWidthUnit( QgsSymbolLayerV2Utils::decodeOutputUnit( properties["outline_width_unit"] ) );
}

return symbolLayer;
}
Expand All @@ -430,7 +461,7 @@ void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )

delete mSvgPattern;
mSvgPattern = 0;
double size = context.outputPixelSize( mPatternWidth );
double size = mPatternWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mPatternWidthUnit );

//don't render pattern if symbol size is below one or above 10,000 pixels
if (( int )size < 1.0 || 10000.0 < size )
Expand All @@ -440,13 +471,14 @@ void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
}
else
{
double outlineWidth = mSvgOutlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mSvgOutlineWidthUnit );
bool fitsInCache = true;
const QImage& patternImage = QgsSvgCache::instance()->svgAsImage( mSvgFilePath, size, mSvgFillColor, mSvgOutlineColor, mSvgOutlineWidth,
const QImage& patternImage = QgsSvgCache::instance()->svgAsImage( mSvgFilePath, size, mSvgFillColor, mSvgOutlineColor, outlineWidth,
context.renderContext().scaleFactor(), context.renderContext().rasterScaleFactor(), fitsInCache );

if ( !fitsInCache )
{
const QPicture& patternPict = QgsSvgCache::instance()->svgAsPicture( mSvgFilePath, size, mSvgFillColor, mSvgOutlineColor, mSvgOutlineWidth,
const QPicture& patternPict = QgsSvgCache::instance()->svgAsPicture( mSvgFilePath, size, mSvgFillColor, mSvgOutlineColor, outlineWidth,
context.renderContext().scaleFactor(), 1.0 );
double hwRatio = 1.0;
if ( patternPict.width() > 0 )
Expand Down Expand Up @@ -509,25 +541,33 @@ QgsStringMap QgsSVGFillSymbolLayer::properties() const
map.insert( "svgOutlineColor", mSvgOutlineColor.name() );
map.insert( "svgOutlineWidth", QString::number( mSvgOutlineWidth ) );

//units
map["pattern_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mPatternWidthUnit );
map["svg_outline_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mSvgOutlineWidthUnit );
map["outline_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOutlineWidthUnit );

return map;
}

QgsSymbolLayerV2* QgsSVGFillSymbolLayer::clone() const
{
QgsSymbolLayerV2* clonedLayer = 0;
QgsSVGFillSymbolLayer* clonedLayer = 0;
if ( !mSvgFilePath.isEmpty() )
{
clonedLayer = new QgsSVGFillSymbolLayer( mSvgFilePath, mPatternWidth, mAngle );
QgsSVGFillSymbolLayer* sl = static_cast<QgsSVGFillSymbolLayer*>( clonedLayer );
sl->setSvgFillColor( mSvgFillColor );
sl->setSvgOutlineColor( mSvgOutlineColor );
sl->setSvgOutlineWidth( mSvgOutlineWidth );
clonedLayer->setSvgFillColor( mSvgFillColor );
clonedLayer->setSvgOutlineColor( mSvgOutlineColor );
clonedLayer->setSvgOutlineWidth( mSvgOutlineWidth );
}
else
{
clonedLayer = new QgsSVGFillSymbolLayer( mSvgData, mPatternWidth, mAngle );
}

clonedLayer->setPatternWidthUnit( mPatternWidthUnit );
clonedLayer->setSvgOutlineWidthUnit( mSvgOutlineWidthUnit );
clonedLayer->setOutlineWidthUnit( mOutlineWidthUnit );

if ( mOutline )
{
clonedLayer->setSubSymbol( mOutline->clone() );
Expand Down
19 changes: 18 additions & 1 deletion src/core/symbology-ng/qgsfillsymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,16 @@ class CORE_EXPORT QgsImageFillSymbolLayer: public QgsFillSymbolLayerV2
virtual QgsSymbolV2* subSymbol() { return mOutline; }
virtual bool setSubSymbol( QgsSymbolV2* symbol );

void setOutlineWidthUnit( QgsSymbolV2::OutputUnit unit ) { mOutlineWidthUnit = unit; }
QgsSymbolV2::OutputUnit outlineWidthUnit() const { return mOutlineWidthUnit; }

protected:
QBrush mBrush;

/**Outline width*/
double mOutlineWidth;
QgsSymbolV2::OutputUnit mOutlineWidthUnit;

/**Custom outline*/
QgsLineSymbolV2* mOutline;
};
Expand Down Expand Up @@ -156,9 +161,20 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
void setSvgOutlineWidth( double w ) { mSvgOutlineWidth = w; }
double svgOutlineWidth() const { return mSvgOutlineWidth; }

void setPatternWidthUnit( QgsSymbolV2::OutputUnit unit ) { mPatternWidthUnit = unit; }
QgsSymbolV2::OutputUnit patternWidthUnit() const { return mPatternWidthUnit; }

void setSvgOutlineWidthUnit( QgsSymbolV2::OutputUnit unit ) { mSvgOutlineWidthUnit = unit; }
QgsSymbolV2::OutputUnit svgOutlineWidthUnit() const { return mSvgOutlineWidthUnit; }

void setOutputUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit outputUnit() const;

protected:
/**Width of the pattern (in QgsSymbolV2 output units)*/
/**Width of the pattern (in output units)*/
double mPatternWidth;
QgsSymbolV2::OutputUnit mPatternWidthUnit;

/**SVG data*/
QByteArray mSvgData;
/**Path to the svg file (or empty if constructed directly from data)*/
Expand All @@ -174,6 +190,7 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
QColor mSvgFillColor;
QColor mSvgOutlineColor;
double mSvgOutlineWidth;
QgsSymbolV2::OutputUnit mSvgOutlineWidthUnit;

private:
/**Helper function that gets the view box from the byte array*/
Expand Down
24 changes: 24 additions & 0 deletions src/gui/symbology-ng/qgssymbollayerv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1103,6 +1103,12 @@ void QgsSVGFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer )
mTextureWidthSpinBox->setValue( width );
mSVGLineEdit->setText( mLayer->svgFilePath() );
mRotationSpinBox->setValue( mLayer->angle() );
mTextureWidthUnitComboBox->blockSignals( true );
mTextureWidthUnitComboBox->setCurrentIndex( mLayer->patternWidthUnit() );
mTextureWidthUnitComboBox->blockSignals( false );
mSvgOutlineWidthUnitComboBox->blockSignals( true );
mSvgOutlineWidthUnitComboBox->setCurrentIndex( mLayer->svgOutlineWidthUnit() );
mSvgOutlineWidthUnitComboBox->blockSignals( false );
}
updateParamGui();
}
Expand Down Expand Up @@ -1274,6 +1280,24 @@ void QgsSVGFillSymbolLayerWidget::on_mBorderWidthSpinBox_valueChanged( double d
}
}

void QgsSVGFillSymbolLayerWidget::on_mTextureWidthUnitComboBox_currentIndexChanged( int index )
{
if ( mLayer )
{
mLayer->setPatternWidthUnit(( QgsSymbolV2::OutputUnit ) index );
emit changed();
}
}

void QgsSVGFillSymbolLayerWidget::on_mSvgOutlineWidthUnitComboBox_currentIndexChanged( int index )
{
if ( mLayer )
{
mLayer->setSvgOutlineWidthUnit(( QgsSymbolV2::OutputUnit ) index );
emit changed();
}
}

/////////////

QgsLinePatternFillSymbolLayerWidget::QgsLinePatternFillSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent ):
Expand Down
2 changes: 2 additions & 0 deletions src/gui/symbology-ng/qgssymbollayerv2widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ class GUI_EXPORT QgsSVGFillSymbolLayerWidget : public QgsSymbolLayerV2Widget, pr
void on_mChangeColorButton_clicked();
void on_mChangeBorderColorButton_clicked();
void on_mBorderWidthSpinBox_valueChanged( double d );
void on_mTextureWidthUnitComboBox_currentIndexChanged( int index );
void on_mSvgOutlineWidthUnitComboBox_currentIndexChanged( int index );
};

//////////
Expand Down
104 changes: 73 additions & 31 deletions src/ui/symbollayer/widget_svgfill.ui
Original file line number Diff line number Diff line change
Expand Up @@ -19,76 +19,118 @@
</property>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="mTextureWidthSpinBox">
<property name="decimals">
<number>5</number>
</property>
<property name="maximum">
<double>99999999.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="mBorderColorLabel">
<property name="text">
<string>Border color</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="mColorLabel">
<item row="5" column="0">
<widget class="QLabel" name="mBorderWidthLabel">
<property name="text">
<string>Color</string>
<string>Border width</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="mBorderWidthSpinBox">
<property name="decimals">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QgsColorButtonV2" name="mChangeBorderColorButton">
<widget class="QgsColorButtonV2" name="mChangeColorButton">
<property name="text">
<string>Change</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="mRotationSpinBox">
<property name="maximum">
<double>360.000000000000000</double>
<item row="1" column="0">
<widget class="QLabel" name="mTextureWidthUnitLabel">
<property name="text">
<string>Texture width unit</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mTextureWidthLabel">
<item row="4" column="1">
<widget class="QgsColorButtonV2" name="mChangeBorderColorButton">
<property name="text">
<string>Texture width</string>
<string>Change</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QgsColorButtonV2" name="mChangeColorButton">
<item row="2" column="0">
<widget class="QLabel" name="mRotationLabel">
<property name="text">
<string>Change</string>
<string>Rotation</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="mBorderWidthSpinBox">
<property name="decimals">
<number>5</number>
<item row="3" column="0">
<widget class="QLabel" name="mColorLabel">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mRotationLabel">
<item row="0" column="0">
<widget class="QLabel" name="mTextureWidthLabel">
<property name="text">
<string>Rotation</string>
<string>Texture width</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="mTextureWidthSpinBox">
<property name="decimals">
<number>5</number>
</property>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="mRotationSpinBox">
<property name="maximum">
<double>99999999.000000000000000</double>
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="mBorderWidthLabel">
<item row="1" column="1">
<widget class="QComboBox" name="mTextureWidthUnitComboBox">
<item>
<property name="text">
<string>Millimeter</string>
</property>
</item>
<item>
<property name="text">
<string>Map unit</string>
</property>
</item>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="mSvgOutlineWidthUnitComboBox">
<item>
<property name="text">
<string>Millimeter</string>
</property>
</item>
<item>
<property name="text">
<string>Map unit</string>
</property>
</item>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="mSvgOutlineWidthUnitLabel">
<property name="text">
<string>Border width</string>
<string>Border width unit</string>
</property>
</widget>
</item>
Expand Down

0 comments on commit 52611c1

Please sign in to comment.