Skip to content

Commit

Permalink
Support for named typeface styles in adv. labeling engine
Browse files Browse the repository at this point in the history
- Support for named typeface styles (Hairline, Slanted, Bold Cond Italic, etc.)
- Named style combobox selector and PAL layer setting
- Named style assignment to preexisting PAL layer fonts
- Underline and strikeout options outside of font selection dialog
- Simple test and notification for missing fonts per layer
- Add QSplitter between preview and label options
- Large previews now viewable even on small screens
- Label previews for map units can scale to 320 pixels
- More accurate underline, strikeout and buffer previews
  • Loading branch information
dakcarto committed Aug 23, 2012
1 parent c339a57 commit eaecf0c
Show file tree
Hide file tree
Showing 6 changed files with 1,347 additions and 1,227 deletions.
171 changes: 140 additions & 31 deletions src/app/qgslabelinggui.cpp
Expand Up @@ -180,9 +180,6 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM
mBufferTranspFillChbx->setChecked( !lyr.bufferNoFill );
}

btnTextColor->setColor( lyr.textColor );
mFontTranspSpinBox->setValue( lyr.textTransp );

bool formattedNumbers = lyr.formatNumbers;
bool plusSign = lyr.plusSign;

Expand All @@ -205,9 +202,14 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM
mFontSizeUnitComboBox->setCurrentIndex( 0 );
}

QFont textFont = lyr.textFont;
updateFont( textFont );
mFontSizeSpinBox->setValue( textFont.pointSizeF() );
mRefFont = lyr.textFont;
mFontSizeSpinBox->setValue( mRefFont.pointSizeF() );
btnTextColor->setColor( lyr.textColor );
mFontTranspSpinBox->setValue( lyr.textTransp );

updateFontViaStyle( lyr.textNamedStyle );
updateFont( mRefFont );

updateUi();

updateOptions();
Expand Down Expand Up @@ -302,6 +304,7 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()

lyr.textColor = btnTextColor->color();
lyr.textFont = mRefFont;
lyr.textNamedStyle = mFontStyleComboBox->currentText();
lyr.textTransp = mFontTranspSpinBox->value();
lyr.previewBkgrdColor = mPreviewBackgroundBtn->color();
lyr.enabled = chkEnableLabeling->isChecked();
Expand Down Expand Up @@ -528,6 +531,40 @@ void QgsLabelingGui::changeTextFont()
}
}

void QgsLabelingGui::updateFontViaStyle( const QString & fontstyle )
{
QFont styledfont;
bool foundmatch = false;
if ( !fontstyle.isEmpty() )
{
styledfont = mFontDB.font( mRefFont.family(), fontstyle, mRefFont.pointSizeF() );
if ( QApplication::font().toString() != styledfont.toString() )
{
foundmatch = true;
}
}
if ( !foundmatch )
{
foreach ( const QString &style, mFontDB.styles( mRefFont.family() ) )
{
styledfont = mFontDB.font( mRefFont.family(), style, mRefFont.pointSizeF() );
styledfont = styledfont.resolve( mRefFont );
if ( mRefFont.toString() == styledfont.toString() )
{
foundmatch = true;
break;
}
}
}
if ( foundmatch )
{
styledfont.setUnderline( mRefFont.underline() );
styledfont.setStrikeOut( mRefFont.strikeOut() );
mRefFont = styledfont;
}
// if no match, style combobox will be left blank, which should not affect engine labeling
}

void QgsLabelingGui::updateFont( QFont font )
{
// update background reference font
Expand All @@ -536,62 +573,106 @@ void QgsLabelingGui::updateFont( QFont font )
mRefFont = font;
}

lblFontName->setText( QString( "%1" ).arg( font.family() ) );
// test if font is actually available
QString missingtxt = QString( "" );
bool missing = false;
if ( QApplication::font().toString() != mRefFont.toString() )
{
QFont testfont = mFontDB.font( mRefFont.family(), mFontDB.styleString( mRefFont ), mRefFont.pointSizeF() );
if ( QApplication::font().toString() == testfont.toString() )
{
missing = true;
}
}
if ( missing )
{
missingtxt = tr( " (not found!)" );
lblFontName->setStyleSheet( "color: #990000;" );
}
else
{
lblFontName->setStyleSheet( "color: #000000;" );
}

lblFontName->setText( QString( "%1%2" ).arg( mRefFont.family() ).arg( missingtxt ) );

blockFontChangeSignals( true );
populateFontStyleComboBox();
mFontUnderlineBtn->setChecked( mRefFont.underline() );
mFontStrikethroughBtn->setChecked( mRefFont.strikeOut() );
blockFontChangeSignals( false );

// update font name with font face
// QString dupFont = font.toString();
// QFont lblFont = lblFontName->font();
// lblFont.fromString( dupFont );
// lblFont.setPointSizeF( 14 );
// lblFontName->setFont(lblFont);
// font.setPixelSize( 18 );
// lblFontName->setFont( QFont( font ) );

updatePreview();
}

void QgsLabelingGui::blockFontChangeSignals( bool blk )
{
mFontStyleComboBox->blockSignals( blk );
mFontUnderlineBtn->blockSignals( blk );
mFontStrikethroughBtn->blockSignals( blk );
}

void QgsLabelingGui::updatePreview()
{
scrollPreview();
lblFontPreview->setFont( mRefFont );
QFont previewFont = lblFontPreview->font();
double fontSize = mFontSizeSpinBox->value();
double bufferSize = spinBufferSize->value();
if ( mFontSizeUnitComboBox->currentIndex() == 1 )
double bufferSize = 0.0;
QString grpboxtitle;

if ( mFontSizeUnitComboBox->currentIndex() == 1 ) // map units
{
// TODO: maybe match current map zoom level instead?
previewFont.setPointSize( mPreviewSize );
mPreviewSizeSlider->setEnabled( true );
if ( mBufferUnitComboBox->currentIndex() == 1 )
{
groupBox_mPreview->setTitle( tr( "Sample @ %1 pts (using map units)" ).arg( mPreviewSize ) );
bufferSize = ( mPreviewSize / fontSize ) * bufferSize / 2.5;
}
else
grpboxtitle = tr( "Sample @ %1 pts (using map units)" ).arg( mPreviewSize );

if ( chkBuffer->isChecked() )
{
groupBox_mPreview->setTitle( tr( "Sample @ %1 pts (using map units, STROKE IN mm)" ).arg( mPreviewSize ) );
if ( mBufferUnitComboBox->currentIndex() == 1 ) // map units
{
bufferSize = ( mPreviewSize / fontSize ) * spinBufferSize->value() / 2.5;
}
else // millimeters
{
grpboxtitle = tr( "Sample @ %1 pts (using map units, BUFFER IN MILLIMETERS)" ).arg( mPreviewSize );
bufferSize = spinBufferSize->value();
}
}
}
else
else // in points
{
previewFont.setPointSize( fontSize );
mPreviewSizeSlider->setEnabled( false );
if ( mBufferUnitComboBox->currentIndex() == 1 )
{
groupBox_mPreview->setTitle( tr( "Sample (stroke in map units, NOT SHOWN)" ) );
bufferSize = 0;
}
else
grpboxtitle = tr( "Sample" );

if ( chkBuffer->isChecked() )
{
previewFont.setPointSize( fontSize );
groupBox_mPreview->setTitle( tr( "Sample" ) );
if ( mBufferUnitComboBox->currentIndex() == 0 ) // millimeters
{
bufferSize = spinBufferSize->value();
}
else // map units
{
grpboxtitle = tr( "Sample (BUFFER NOT SHOWN, in map units)" );
}
}
}

lblFontPreview->setFont( previewFont );
groupBox_mPreview->setTitle( grpboxtitle );

QColor prevColor = btnTextColor->color();
prevColor.setAlphaF(( 100.0 - ( double )( mFontTranspSpinBox->value() ) ) / 100.0 );
lblFontPreview->setTextColor( prevColor );

bool bufferNoFill = false;
if ( chkBuffer->isChecked() )
if ( chkBuffer->isChecked() && bufferSize != 0.0 )
{
QColor buffColor = btnBufferColor->color();
buffColor.setAlphaF(( 100.0 - ( double )( mBufferTranspSpinBox->value() ) ) / 100.0 );
Expand Down Expand Up @@ -688,6 +769,16 @@ void QgsLabelingGui::updateOptions()
}
}

void QgsLabelingGui::populateFontStyleComboBox()
{
mFontStyleComboBox->clear();
foreach ( const QString &style, mFontDB.styles( mRefFont.family() ) )
{
mFontStyleComboBox->addItem( style );
}
mFontStyleComboBox->setCurrentIndex( mFontStyleComboBox->findText( mFontDB.styleString( mRefFont ) ) );
}

void QgsLabelingGui::on_mPreviewSizeSlider_valueChanged( int i )
{
mPreviewSize = i;
Expand All @@ -700,6 +791,24 @@ void QgsLabelingGui::on_mFontSizeSpinBox_valueChanged( double d )
updateFont( mRefFont );
}

void QgsLabelingGui::on_mFontStyleComboBox_currentIndexChanged( const QString & text )
{
updateFontViaStyle( text );
updateFont( mRefFont );
}

void QgsLabelingGui::on_mFontUnderlineBtn_toggled( bool ckd )
{
mRefFont.setUnderline( ckd );
updateFont( mRefFont );
}

void QgsLabelingGui::on_mFontStrikethroughBtn_toggled( bool ckd )
{
mRefFont.setStrikeOut( ckd );
updateFont( mRefFont );
}

void QgsLabelingGui::on_mFontWordSpacingSpinBox_valueChanged( double spacing )
{
mRefFont.setWordSpacing( spacing );
Expand Down
10 changes: 9 additions & 1 deletion src/app/qgslabelinggui.h
Expand Up @@ -19,6 +19,7 @@
#define QgsLabelingGUI_H

#include <QDialog>
#include <QFontDatabase>
#include <ui_qgslabelingguibase.h>

class QgsVectorLayer;
Expand Down Expand Up @@ -51,6 +52,9 @@ class QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase

void on_mPreviewSizeSlider_valueChanged( int i );
void on_mFontSizeSpinBox_valueChanged( double d );
void on_mFontStyleComboBox_currentIndexChanged( const QString & text );
void on_mFontUnderlineBtn_toggled( bool ckd );
void on_mFontStrikethroughBtn_toggled( bool ckd );
void on_mFontWordSpacingSpinBox_valueChanged( double spacing );
void on_mFontLetterSpacingSpinBox_valueChanged( double spacing );
void on_mBufferUnitComboBox_currentIndexChanged( int index );
Expand All @@ -62,6 +66,10 @@ class QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
void on_mPreviewBackgroundBtn_clicked();

protected:
void blockFontChangeSignals( bool blk );
void setPreviewBackground( QColor color );
void updateFontViaStyle( const QString & fontstyle );
void populateFontStyleComboBox();
void populatePlacementMethods();
void populateFieldNames();
void populateDataDefinedCombos( QgsPalLayerSettings& s );
Expand All @@ -74,11 +82,11 @@ class QgsLabelingGui : public QWidget, private Ui::QgsLabelingGuiBase
QgsPalLabeling* mLBL;
QgsVectorLayer* mLayer;
QgsMapCanvas* mMapCanvas;
QFontDatabase mFontDB;

// background reference font
QFont mRefFont;
int mPreviewSize;
void setPreviewBackground( QColor color );

void disableDataDefinedAlignment();
void enableDataDefinedAlignment();
Expand Down
10 changes: 8 additions & 2 deletions src/app/qgslabelpreview.cpp
Expand Up @@ -61,6 +61,12 @@ void QgsLabelPreview::paintEvent( QPaintEvent *e )
if ( mBufferSize != 0 )
QgsPalLabeling::drawLabelBuffer( &p, text(), font(), mBufferSize, mBufferColor, mBufferJoinStyle, mBufferNoFill );

p.setPen( mTextColor );
p.drawText( 0, 0, text() );
QPainterPath path;
path.addText( 0, 0, font(), text() );
p.setPen( Qt::NoPen );
p.setBrush( mTextColor );
p.drawPath( path );

// p.setPen( mTextColor );
// p.drawText( 0, 0, text() );
}
20 changes: 19 additions & 1 deletion src/core/qgspallabeling.cpp
Expand Up @@ -31,6 +31,7 @@

#include <cmath>

#include <QApplication>
#include <QByteArray>
#include <QString>
#include <QFontMetrics>
Expand Down Expand Up @@ -142,6 +143,7 @@ QgsPalLayerSettings::QgsPalLayerSettings()
placement = AroundPoint;
placementFlags = 0;
//textFont = QFont();
textNamedStyle = QString( "" );
textColor = Qt::black;
textTransp = 0;
previewBkgrdColor = Qt::white;
Expand Down Expand Up @@ -180,6 +182,7 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
placement = s.placement;
placementFlags = s.placementFlags;
textFont = s.textFont;
textNamedStyle = s.textNamedStyle;
textColor = s.textColor;
textTransp = s.textTransp;
previewBkgrdColor = s.previewBkgrdColor;
Expand Down Expand Up @@ -319,6 +322,18 @@ static void _readDataDefinedPropertyMap( QgsVectorLayer* layer, QMap< QgsPalLaye
_readDataDefinedProperty( layer, QgsPalLayerSettings::BufferTransp, propertyMap );
}

void QgsPalLayerSettings::updateFontViaStyle( const QString & fontstyle )
{
if ( !fontstyle.isEmpty() )
{
QFont styledfont = mFontDB.font( textFont.family(), fontstyle, textFont.pointSizeF() );
if ( QApplication::font().toString() != styledfont.toString() )
{
textFont = styledfont;
}
}
}

void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
{
if ( layer->customProperty( "labeling" ).toString() != QString( "pal" ) )
Expand All @@ -333,9 +348,11 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
int fontWeight = layer->customProperty( "labeling/fontWeight" ).toInt();
bool fontItalic = layer->customProperty( "labeling/fontItalic" ).toBool();
textFont = QFont( fontFamily, fontSize, fontWeight, fontItalic );
textFont.setPointSizeF( fontSize ); //double precision needed because of map units
textNamedStyle = layer->customProperty( "labeling/namedStyle", QVariant( "" ) ).toString();
updateFontViaStyle( textNamedStyle );
textFont.setUnderline( layer->customProperty( "labeling/fontUnderline" ).toBool() );
textFont.setStrikeOut( layer->customProperty( "labeling/fontStrikeout" ).toBool() );
textFont.setPointSizeF( fontSize ); //double precision needed because of map units
textColor = _readColor( layer, "labeling/textColor" );
textTransp = layer->customProperty( "labeling/textTransp" ).toInt();
previewBkgrdColor = QColor( layer->customProperty( "labeling/previewBkgrdColor", "#ffffff" ).toString() );
Expand Down Expand Up @@ -376,6 +393,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )
layer->setCustomProperty( "labeling/placementFlags", ( unsigned int )placementFlags );

layer->setCustomProperty( "labeling/fontFamily", textFont.family() );
layer->setCustomProperty( "labeling/namedStyle", textNamedStyle );
layer->setCustomProperty( "labeling/fontSize", textFont.pointSizeF() );
layer->setCustomProperty( "labeling/fontWeight", textFont.weight() );
layer->setCustomProperty( "labeling/fontItalic", textFont.italic() );
Expand Down
6 changes: 6 additions & 0 deletions src/core/qgspallabeling.h
Expand Up @@ -32,6 +32,7 @@ struct QgsDiagramLayerSettings;

#include <QString>
#include <QFont>
#include <QFontDatabase>
#include <QColor>
#include <QHash>
#include <QList>
Expand Down Expand Up @@ -118,6 +119,7 @@ class CORE_EXPORT QgsPalLayerSettings
Placement placement;
unsigned int placementFlags;
QFont textFont;
QString textNamedStyle;
QColor textColor;
int textTransp;
QColor previewBkgrdColor;
Expand Down Expand Up @@ -187,6 +189,10 @@ class CORE_EXPORT QgsPalLayerSettings
@return true if above size, false if below*/
bool checkMinimumSizeMM( const QgsRenderContext& ct, QgsGeometry* geom, double minSize ) const;
QgsExpression* expression;

QFontDatabase mFontDB;
/**Updates layer font with one of its named styles */
void updateFontViaStyle( const QString & fontstyle );
};

class CORE_EXPORT QgsLabelCandidate
Expand Down

0 comments on commit eaecf0c

Please sign in to comment.