Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] Added font marker symbol layer
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12794 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Jan 18, 2010
1 parent 869735a commit 886e591
Show file tree
Hide file tree
Showing 12 changed files with 625 additions and 3 deletions.
82 changes: 82 additions & 0 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Expand Up @@ -467,3 +467,85 @@ QString QgsSvgMarkerSymbolLayerV2::symbolPathToName( QString path )

return path;
}


//////////

QgsFontMarkerSymbolLayerV2::QgsFontMarkerSymbolLayerV2( QString fontFamily, QChar chr, double pointSize, QColor color, double angle )
{
mFontFamily = fontFamily;
mChr = chr;
mColor = color;
mAngle = angle;
mSize = pointSize;
}

QgsSymbolLayerV2* QgsFontMarkerSymbolLayerV2::create( const QgsStringMap& props )
{
QString fontFamily = DEFAULT_FONTMARKER_FONT;
QChar chr = DEFAULT_FONTMARKER_CHR;
double pointSize = DEFAULT_FONTMARKER_SIZE;
QColor color = DEFAULT_FONTMARKER_COLOR;
double angle = DEFAULT_FONTMARKER_ANGLE;

if ( props.contains( "font" ) )
fontFamily = props["font"];
if ( props.contains( "chr" ) && props["chr"].length() > 0 )
chr = props["chr"].at( 0 );
if ( props.contains( "size" ) )
pointSize = props["size"].toDouble();
if ( props.contains( "color" ) )
color = QgsSymbolLayerV2Utils::decodeColor( props["color"] );
if ( props.contains( "angle" ) )
angle = props["angle"].toDouble();

return new QgsFontMarkerSymbolLayerV2( fontFamily, chr, pointSize, color, angle );
}

QString QgsFontMarkerSymbolLayerV2::layerType() const
{
return "FontMarker";
}

void QgsFontMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
{
mFont = QFont( mFontFamily, MM2POINT( mSize ) );
QFontMetrics fm( mFont );
mChrOffset = QPointF( fm.width( mChr ) / 2, -fm.ascent() / 2 );
}

void QgsFontMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
{
}

void QgsFontMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context )
{
QPainter* p = context.renderContext().painter();
p->setPen( mColor );
p->setFont( mFont );

if ( mAngle != 0 )
{
p->save();
p->rotate( mAngle );
}
p->drawText( point - mChrOffset, mChr );
if ( mAngle != 0 )
p->restore();
}

QgsStringMap QgsFontMarkerSymbolLayerV2::properties() const
{
QgsStringMap props;
props["font"] = mFontFamily;
props["chr"] = mChr;
props["size"] = QString::number( mSize );
props["color"] = QgsSymbolLayerV2Utils::encodeColor( mColor );
props["angle"] = QString::number( mAngle );
return props;
}

QgsSymbolLayerV2* QgsFontMarkerSymbolLayerV2::clone() const
{
return new QgsFontMarkerSymbolLayerV2( mFontFamily, mChr, mSize, mColor, mAngle );
}
58 changes: 58 additions & 0 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.h
Expand Up @@ -14,6 +14,7 @@
#include <QBrush>
#include <QPicture>
#include <QPolygonF>
#include <QFont>

class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
{
Expand Down Expand Up @@ -111,4 +112,61 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
QPicture mPicture;
};


//////////

#define POINT2MM(x) ( (x) * 25.4 / 72 ) // point is 1/72 of inch
#define MM2POINT(x) ( (x) * 72 / 25.4 )

#define DEFAULT_FONTMARKER_FONT "Dingbats"
#define DEFAULT_FONTMARKER_CHR QChar('A')
#define DEFAULT_FONTMARKER_SIZE POINT2MM(12)
#define DEFAULT_FONTMARKER_COLOR QColor(Qt::black)
#define DEFAULT_FONTMARKER_ANGLE 0

class CORE_EXPORT QgsFontMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
{
public:
QgsFontMarkerSymbolLayerV2( QString fontFamily = DEFAULT_FONTMARKER_FONT,
QChar chr = DEFAULT_FONTMARKER_CHR,
double pointSize = DEFAULT_FONTMARKER_SIZE,
QColor color = DEFAULT_FONTMARKER_COLOR,
double angle = DEFAULT_FONTMARKER_ANGLE );

// static stuff

static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );

// implemented from base classes

QString layerType() const;

void startRender( QgsSymbolV2RenderContext& context );

void stopRender( QgsSymbolV2RenderContext& context );

void renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context );

QgsStringMap properties() const;

QgsSymbolLayerV2* clone() const;

// new methods

QString fontFamily() const { return mFontFamily; }
void setFontFamily( QString family ) { mFontFamily = family; }

QChar character() const { return mChr; }
void setCharacter( QChar ch ) { mChr = ch; }

protected:

QString mFontFamily;
QChar mChr;

QPointF mChrOffset;
QFont mFont;
};


#endif
3 changes: 2 additions & 1 deletion src/core/symbology-ng/qgssymbollayerv2registry.cpp
Expand Up @@ -21,10 +21,11 @@ QgsSymbolLayerV2Registry::QgsSymbolLayerV2Registry()
QgsSimpleMarkerSymbolLayerV2::create ) );
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SvgMarker", QgsSymbolV2::Marker,
QgsSvgMarkerSymbolLayerV2::create ) );
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "FontMarker", QgsSymbolV2::Marker,
QgsFontMarkerSymbolLayerV2::create ) );

addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SimpleFill", QgsSymbolV2::Fill,
QgsSimpleFillSymbolLayerV2::create ) );

addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SVGFill", QgsSymbolV2::Fill, QgsSVGFillSymbolLayer::create ) );
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology-ng/qgssymbolv2.cpp
Expand Up @@ -180,7 +180,7 @@ QImage QgsSymbolV2::bigSymbolPreviewImage()

if ( mType == QgsSymbolV2::Marker )
{
p.setPen( QPen( QColor( 230, 230, 230 ) ) );
p.setPen( QPen( Qt::gray ) );
p.drawLine( 0, 50, 100, 50 );
p.drawLine( 50, 0, 50, 100 );
}
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -17,6 +17,7 @@ symbology-ng/qgssymbolv2selectordialog.cpp
symbology-ng/qgsvectorgradientcolorrampv2dialog.cpp
symbology-ng/qgsvectorrandomcolorrampv2dialog.cpp
symbology-ng/qgsvectorcolorbrewercolorrampv2dialog.cpp
symbology-ng/characterwidget.cpp

qgisgui.cpp
qgisinterface.cpp
Expand Down Expand Up @@ -64,6 +65,7 @@ symbology-ng/qgssymbolv2selectordialog.h
symbology-ng/qgsvectorgradientcolorrampv2dialog.h
symbology-ng/qgsvectorrandomcolorrampv2dialog.h
symbology-ng/qgsvectorcolorbrewercolorrampv2dialog.h
symbology-ng/characterwidget.h

qgscomposerview.h
qgsdetaileditemdelegate.h
Expand Down
183 changes: 183 additions & 0 deletions src/gui/symbology-ng/characterwidget.cpp
@@ -0,0 +1,183 @@
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui>

#include "characterwidget.h"

//! [0]
CharacterWidget::CharacterWidget( QWidget *parent )
: QWidget( parent )
{
squareSize = 24;
columns = 16;
lastKey = -1;
setMouseTracking( true );
}
//! [0]

//! [1]
void CharacterWidget::updateFont( const QFont &font )
{
displayFont.setFamily( font.family() );
squareSize = qMax( 24, QFontMetrics( displayFont ).xHeight() * 3 );
adjustSize();
update();
}
//! [1]

//! [2]
void CharacterWidget::updateSize( double fontSize )
{
displayFont.setPointSizeF( fontSize );
squareSize = qMax( 24, QFontMetrics( displayFont ).xHeight() * 3 );
adjustSize();
update();
}
//! [2]

void CharacterWidget::updateStyle( const QString &fontStyle )
{
QFontDatabase fontDatabase;
const QFont::StyleStrategy oldStrategy = displayFont.styleStrategy();
displayFont = fontDatabase.font( displayFont.family(), fontStyle, displayFont.pointSize() );
displayFont.setStyleStrategy( oldStrategy );
squareSize = qMax( 24, QFontMetrics( displayFont ).xHeight() * 3 );
adjustSize();
update();
}

void CharacterWidget::updateFontMerging( bool enable )
{
if ( enable )
displayFont.setStyleStrategy( QFont::PreferDefault );
else
displayFont.setStyleStrategy( QFont::NoFontMerging );
adjustSize();
update();
}

//! [3]
QSize CharacterWidget::sizeHint() const
{
return QSize( columns*squareSize, ( 65536 / columns )*squareSize );
}
//! [3]

//! [4]
void CharacterWidget::mouseMoveEvent( QMouseEvent *event )
{
QPoint widgetPosition = mapFromGlobal( event->globalPos() );
uint key = ( widgetPosition.y() / squareSize ) * columns + widgetPosition.x() / squareSize;

QString text = QString::fromLatin1( "<p>Character: <span style=\"font-size: 24pt; font-family: %1\">" ).arg( displayFont.family() )
+ QChar( key )
+ QString::fromLatin1( "</span><p>Value: 0x" )
+ QString::number( key, 16 );
QToolTip::showText( event->globalPos(), text, this );
}
//! [4]

//! [5]
void CharacterWidget::mousePressEvent( QMouseEvent *event )
{
if ( event->button() == Qt::LeftButton )
{
lastKey = ( event->y() / squareSize ) * columns + event->x() / squareSize;
if ( QChar( lastKey ).category() != QChar::NoCategory )
emit characterSelected( QChar( lastKey ) );
update();
}
else
QWidget::mousePressEvent( event );
}
//! [5]

//! [6]
void CharacterWidget::paintEvent( QPaintEvent *event )
{
QPainter painter( this );
painter.fillRect( event->rect(), QBrush( Qt::white ) );
painter.setFont( displayFont );
//! [6]

//! [7]
QRect redrawRect = event->rect();
int beginRow = redrawRect.top() / squareSize;
int endRow = redrawRect.bottom() / squareSize;
int beginColumn = redrawRect.left() / squareSize;
int endColumn = redrawRect.right() / squareSize;
//! [7]

//! [8]
painter.setPen( QPen( Qt::gray ) );
for ( int row = beginRow; row <= endRow; ++row )
{
for ( int column = beginColumn; column <= endColumn; ++column )
{
painter.drawRect( column*squareSize, row*squareSize, squareSize, squareSize );
}
//! [8] //! [9]
}
//! [9]

//! [10]
QFontMetrics fontMetrics( displayFont );
painter.setPen( QPen( Qt::black ) );
for ( int row = beginRow; row <= endRow; ++row )
{

for ( int column = beginColumn; column <= endColumn; ++column )
{

int key = row * columns + column;
painter.setClipRect( column*squareSize, row*squareSize, squareSize, squareSize );

if ( key == lastKey )
painter.fillRect( column*squareSize + 1, row*squareSize + 1, squareSize, squareSize, QBrush( Qt::red ) );

painter.drawText( column*squareSize + ( squareSize / 2 ) - fontMetrics.width( QChar( key ) ) / 2,
row*squareSize + 4 + fontMetrics.ascent(),
QString( QChar( key ) ) );
}
}
}
//! [10]

0 comments on commit 886e591

Please sign in to comment.