/usr/include/qgis/qgspalgeometry.h is in libqgis-dev 2.8.6+dfsg-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | #ifndef QGSPALGEOMETRY_H
#define QGSPALGEOMETRY_H
#include "qgsgeometry.h"
#include <pal/feature.h>
#include <pal/palgeometry.h>
#include <QTextBoundaryFinder>
using namespace pal;
class QgsPalGeometry : public PalGeometry
{
public:
QgsPalGeometry( QgsFeatureId id, QString text, GEOSGeometry* g,
qreal ltrSpacing = 0.0, qreal wordSpacing = 0.0, bool curvedLabeling = false )
: mG( g )
, mText( text )
, mId( id )
, mInfo( NULL )
, mIsDiagram( false )
, mIsPinned( false )
, mFontMetrics( NULL )
, mLetterSpacing( ltrSpacing )
, mWordSpacing( wordSpacing )
, mCurvedLabeling( curvedLabeling )
{
mStrId = FID_TO_STRING( mId ).toAscii();
mDefinedFont = QFont();
}
~QgsPalGeometry()
{
if ( mG )
GEOSGeom_destroy_r( QgsGeometry::getGEOSHandler(), mG );
delete mInfo;
delete mFontMetrics;
}
// getGeosGeometry + releaseGeosGeometry is called twice: once when adding, second time when labeling
const GEOSGeometry* getGeosGeometry() override
{
return mG;
}
void releaseGeosGeometry( const GEOSGeometry* /*geom*/ ) override
{
// nothing here - we'll delete the geometry in destructor
}
const char* strId() { return mStrId.data(); }
QString text() { return mText; }
/** Returns the text component corresponding to a specified label part
* @param partId Set to -1 for labels which are not broken into parts (eg, non-curved labels), or the required
* part index for labels which are broken into parts (curved labels)
* @note added in QGIS 2.10
*/
QString text( int partId ) const
{
if ( partId == -1 )
return mText;
else
return mClusters.at( partId );
}
pal::LabelInfo* info( QFontMetricsF* fm, const QgsMapToPixel* xform, double fontScale, double maxinangle, double maxoutangle )
{
if ( mInfo )
return mInfo;
mFontMetrics = new QFontMetricsF( *fm ); // duplicate metrics for when drawing label
// max angle between curved label characters (20.0/-20.0 was default in QGIS <= 1.8)
if ( maxinangle < 20.0 )
maxinangle = 20.0;
if ( 60.0 < maxinangle )
maxinangle = 60.0;
if ( maxoutangle > -20.0 )
maxoutangle = -20.0;
if ( -95.0 > maxoutangle )
maxoutangle = -95.0;
// create label info!
double mapScale = xform->mapUnitsPerPixel();
double labelHeight = mapScale * fm->height() / fontScale;
// mLetterSpacing/mWordSpacing = 0.0 is default for non-curved labels
// (non-curved spacings handled by Qt in QgsPalLayerSettings/QgsPalLabeling)
qreal charWidth;
qreal wordSpaceFix;
//split string by valid grapheme boundaries - required for certain scripts (see #6883)
QTextBoundaryFinder boundaryFinder( QTextBoundaryFinder::Grapheme, mText );
int currentBoundary = -1;
int previousBoundary = 0;
while (( currentBoundary = boundaryFinder.toNextBoundary() ) > 0 )
{
mClusters << mText.mid( previousBoundary, currentBoundary - previousBoundary );
previousBoundary = currentBoundary;
}
mInfo = new pal::LabelInfo( mClusters.count(), labelHeight, maxinangle, maxoutangle );
for ( int i = 0; i < mClusters.count(); i++ )
{
//doesn't appear to be used anywhere:
//mInfo->char_info[i].chr = textClusters[i].unicode();
// reconstruct how Qt creates word spacing, then adjust per individual stored character
// this will allow PAL to create each candidate width = character width + correct spacing
charWidth = fm->width( mClusters[i] );
if ( mCurvedLabeling )
{
wordSpaceFix = qreal( 0.0 );
if ( mClusters[i] == QString( " " ) )
{
// word spacing only gets added once at end of consecutive run of spaces, see QTextEngine::shapeText()
int nxt = i + 1;
wordSpaceFix = ( nxt < mClusters.count() && mClusters[nxt] != QString( " " ) ) ? mWordSpacing : qreal( 0.0 );
}
// this workaround only works for clusters with a single character. Not sure how it should be handled
// with multi-character clusters.
if ( mClusters[i].length() == 1 &&
!qgsDoubleNear( fm->width( QString( mClusters[i].at( 0 ) ) ), fm->width( mClusters[i].at( 0 ) ) + mLetterSpacing ) )
{
// word spacing applied when it shouldn't be
wordSpaceFix -= mWordSpacing;
}
charWidth = fm->width( QString( mClusters[i] ) ) + wordSpaceFix;
}
double labelWidth = mapScale * charWidth / fontScale;
mInfo->char_info[i].width = labelWidth;
}
return mInfo;
}
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& dataDefinedValues() const { return mDataDefinedValues; }
void addDataDefinedValue( QgsPalLayerSettings::DataDefinedProperties p, QVariant v ) { mDataDefinedValues.insert( p, v ); }
void setIsDiagram( bool d ) { mIsDiagram = d; }
bool isDiagram() const { return mIsDiagram; }
void setIsPinned( bool f ) { mIsPinned = f; }
bool isPinned() const { return mIsPinned; }
void setDefinedFont( QFont f ) { mDefinedFont = QFont( f ); }
QFont definedFont() { return mDefinedFont; }
QFontMetricsF* getLabelFontMetrics() { return mFontMetrics; }
void setDiagramAttributes( const QgsAttributes& attrs ) { mDiagramAttributes = attrs; }
const QgsAttributes& diagramAttributes() { return mDiagramAttributes; }
void feature( QgsFeature& feature )
{
feature.setFeatureId( mId );
feature.setAttributes( mDiagramAttributes );
feature.setValid( true );
}
void setDxfLayer( QString dxfLayer ) { mDxfLayer = dxfLayer; }
QString dxfLayer() const { return mDxfLayer; }
protected:
GEOSGeometry* mG;
QString mText;
QStringList mClusters;
QByteArray mStrId;
QgsFeatureId mId;
LabelInfo* mInfo;
bool mIsDiagram;
bool mIsPinned;
QFont mDefinedFont;
QFontMetricsF* mFontMetrics;
qreal mLetterSpacing; // for use with curved labels
qreal mWordSpacing; // for use with curved labels
bool mCurvedLabeling; // whether the geometry is to be used for curved labeling placement
/** Stores attribute values for data defined properties*/
QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant > mDataDefinedValues;
/** Stores attribute values for diagram rendering*/
QgsAttributes mDiagramAttributes;
QString mDxfLayer;
};
#endif //QGSPALGEOMETRY_H
|