Skip to content

Commit

Permalink
[FEATURE] QgsTextRenderer class for rich text rendering
Browse files Browse the repository at this point in the history
Moves all the drawing code out of labeling into a new class
which just handles rendering text. This allows other parts
of the code to utilise all the advanced formatting options
that labeling supports, eg rendering text with shadows,
buffers and backgrounds.
  • Loading branch information
nyalldawson committed Oct 24, 2016
1 parent 074ae42 commit 0814347
Show file tree
Hide file tree
Showing 100 changed files with 2,488 additions and 897 deletions.
75 changes: 0 additions & 75 deletions python/core/qgspallabeling.sip
Expand Up @@ -649,61 +649,6 @@ class QgsLabelCandidate
double cost;
};

/** \ingroup core
* Maintains current state of more grainular and temporal values when creating/painting
* component parts of an individual label (e.g. buffer, background, shadow, etc.).
*/
class QgsLabelComponent
{
%TypeHeaderCode
#include <qgspallabeling.h>
%End

public:
QgsLabelComponent();

// methods

QString text() const;
void setText( const QString& text );

const QgsPoint& origin() const;
void setOrigin( const QgsPoint& point );

bool useOrigin() const;
void setUseOrigin( const bool use );

double rotation() const;
void setRotation( const double rotation );

double rotationOffset() const;
void setRotationOffset( const double rotation );

bool useRotation() const;
void setUseRotation( const bool use );

const QgsPoint& center() const;
void setCenter( const QgsPoint& point );

bool useCenter() const;
void setUseCenter( const bool use );

const QgsPoint& size() const;
void setSize( const QgsPoint& point );

const QgsPoint& offset() const;
void setOffset( const QgsPoint& point );

const QPicture* picture() const;
void setPicture( QPicture* picture );

double pictureBuffer() const;
void setPictureBuffer( const double buffer );

double dpiRatio() const;
void setDpiRatio( const double ratio );
};


/**
* Class that stores computed placement from labeling engine.
Expand Down Expand Up @@ -736,14 +681,6 @@ class QgsPalLabeling : QgsLabelingEngineInterface
%End

public:
enum DrawLabelType
{
LabelText,
LabelBuffer,
LabelShape,
LabelSVG,
LabelShadow
};

QgsPalLabeling();
~QgsPalLabeling();
Expand Down Expand Up @@ -830,18 +767,6 @@ class QgsPalLabeling : QgsLabelingEngineInterface
//! @note not available in python bindings
// void drawLabelCandidateRect( pal::LabelPosition* lp, QPainter* painter, const QgsMapToPixel* xform );

static void drawLabelBuffer( QgsRenderContext& context,
const QgsLabelComponent &component,
const QgsTextFormat& format );

static void drawLabelBackground( QgsRenderContext& context,
QgsLabelComponent component,
const QgsTextFormat& format );

static void drawLabelShadow( QgsRenderContext &context,
const QgsLabelComponent &component,
const QgsTextFormat& format );

//! load/save engine settings to project file
void loadEngineSettings();
void saveEngineSettings();
Expand Down
83 changes: 83 additions & 0 deletions python/core/qgstextrenderer.sip
Expand Up @@ -856,6 +856,15 @@ class QgsTextFormat
*/
QFont font() const;

/** Returns a font with the size scaled to match the format's size settings (including
* units and map unit scale) for a specified render context.
* @param context destination render context
* @returns font with scaled size
* @see font()
* @see size()
*/
QFont scaledFont( const QgsRenderContext& context ) const;

/** Sets the font used for rendering text. Note that the size of the font
* is not used, and setSize() should be called instead to explicitly set the size
* of rendered text.
Expand Down Expand Up @@ -1021,6 +1030,21 @@ class QgsTextRenderer

public:

enum TextPart
{
Text,
Buffer,
Background,
Shadow
};

enum HAlignment
{
AlignLeft,
AlignCenter,
AlignRight,
};

/** Calculates pixel size (considering output size should be in pixel or map units, scale factors and optionally oversampling)
* @param size size to convert
* @param c rendercontext
Expand All @@ -1041,4 +1065,63 @@ class QgsTextRenderer
*/
static double scaleToPixelContext( double size, const QgsRenderContext& c, QgsUnitTypes::RenderUnit unit, bool rasterfactor = false, const QgsMapUnitScale& mapUnitScale = QgsMapUnitScale() );

/** Draws text within a rectangle using the specified settings.
* @param rect destination rectangle for text
* @param rotation text rotation
* @param textLines list of lines of text to draw
* @param context render context
* @param format text format
* @param drawAsOutlines set to false to render text as text. This allows outputs to
* formats like SVG to maintain text as text objects, but at the cost of degraded
* rendering and may result in side effects like misaligned text buffers.
*/
static void drawText( const QRectF& rect, double rotation, HAlignment alignment, const QStringList& textLines,
QgsRenderContext& context, const QgsTextFormat& format,
bool drawAsOutlines = true );

/** Draws text at a point origin using the specified settings.
* @param point origin of text
* @param rotation text rotation
* @param textLines list of lines of text to draw
* @param context render context
* @param format text format
* @param drawAsOutlines set to false to render text as text. This allows outputs to
* formats like SVG to maintain text as text objects, but at the cost of degraded
* rendering and may result in side effects like misaligned text buffers.
*/
static void drawText( const QPointF& point, double rotation, HAlignment alignment, const QStringList& textLines,
QgsRenderContext& context, const QgsTextFormat& format,
bool drawAsOutlines = true );

/** Draws a single component of rendered text using the specified settings.
* @param rect destination rectangle for text
* @param rotation text rotation
* @param textLines list of lines of text to draw
* @param context render context
* @param format text format
* @param part component of text to draw
* @param drawAsOutlines set to false to render text as text. This allows outputs to
* formats like SVG to maintain text as text objects, but at the cost of degraded
* rendering and may result in side effects like misaligned text buffers.
*/
static void drawPart( const QRectF& rect, double rotation, HAlignment alignment, const QStringList& textLines,
QgsRenderContext& context, const QgsTextFormat& format,
TextPart part, bool drawAsOutlines = true );

/** Draws a single component of rendered text using the specified settings.
* @param origin origin for start of text. Y coordinate will be used as baseline.
* @param rotation text rotation
* @param textLines list of lines of text to draw
* @param context render context
* @param format text format
* @param part component of text to draw. Note that Shadow parts cannot be drawn
* individually and instead are drawn with their associated part (eg drawn together
* with the text or background parts)
* @param drawAsOutlines set to false to render text as text. This allows outputs to
* formats like SVG to maintain text as text objects, but at the cost of degraded
* rendering and may result in side effects like misaligned text buffers.
*/
static void drawPart( const QPointF& origin, double rotation, HAlignment alignment, const QStringList& textLines,
QgsRenderContext& context, const QgsTextFormat& format,
TextPart part, bool drawAsOutlines = true );
};
2 changes: 1 addition & 1 deletion src/app/qgslabelinggui.cpp
Expand Up @@ -771,7 +771,7 @@ void QgsLabelingGui::init()
mZIndexSpinBox->setValue( lyr.zIndex );

mRefFont = format.font();
mFontSizeSpinBox->setValue( format.font().pointSizeF() );
mFontSizeSpinBox->setValue( format.size() );
btnTextColor->setColor( format.color() );
mFontTranspSpinBox->setValue( 100 - 100 * format.opacity() );
comboBlendMode->setBlendMode( format.blendMode() );
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgslabelpreview.cpp
Expand Up @@ -73,9 +73,9 @@ void QgsLabelPreview::paintEvent( QPaintEvent *e )
if ( mFormat.buffer().size() != 0 )
{
mContext.setPainter( &p );
QgsLabelComponent component;
component.setText( text() );
QgsPalLabeling::drawLabelBuffer( mContext, component, mFormat );
QgsTextRenderer::Component component;
component.text = text();
QgsTextRenderer::drawBuffer( mContext, component, mFormat );
}

QPainterPath path;
Expand Down

1 comment on commit 0814347

@nirvn
Copy link
Contributor

@nirvn nirvn commented on 0814347 Oct 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouhou!

Please sign in to comment.