Marble

VisiblePlacemark.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2006-2007 Torsten Rahn <tackat@kde.org>
4// SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
5//
6
7#include "VisiblePlacemark.h"
8
9#include "MarbleDebug.h"
10#include "RemoteIconLoader.h"
11
12#include "GeoDataPlacemark.h"
13#include "GeoDataStyle.h"
14#include "GeoDataIconStyle.h"
15#include "GeoDataLabelStyle.h"
16#include "PlacemarkLayer.h"
17
18#include <QApplication>
19#include <QPainter>
20#include <QPainterPath>
21#include <QPalette>
22#include <QPixmapCache>
23
24using namespace Marble;
25
26VisiblePlacemark::VisiblePlacemark( const GeoDataPlacemark *placemark, const GeoDataCoordinates &coordinates, const GeoDataStyle::ConstPtr &style )
27 : m_placemark( placemark ),
28 m_selected( false ),
29 m_labelDirty(true),
30 m_style(style),
31 m_coordinates(coordinates)
32{
33 const RemoteIconLoader *remoteLoader = style->iconStyle().remoteIconLoader();
34 QObject::connect( remoteLoader, SIGNAL(iconReady()),
35 this, SLOT(setSymbolPixmap()) );
36
37 setSymbolPixmap();
38}
39
41{
42 return m_placemark;
43}
44
46{
47 if (!m_symbolId.isEmpty() && m_symbolPixmap.isNull()) {
48 if ( !QPixmapCache::find( m_symbolId, &m_symbolPixmap ) ) {
49 m_symbolPixmap = QPixmap::fromImage(m_style->iconStyle().scaledIcon());
50 QPixmapCache::insert( m_symbolId, m_symbolPixmap);
51 }
52 }
53 return m_symbolPixmap;
54}
55
57{
58 return m_symbolId;
59}
60
62{
63 return m_selected;
64}
65
66void VisiblePlacemark::setSelected( bool selected )
67{
68 if (selected != m_selected) {
69 m_selected = selected;
70 m_labelDirty = true;
71 }
72}
73
75{
76 return m_symbolPosition;
77}
78
80{
81 const QSize iconSize = m_style->iconStyle().scaledIcon().size();
82
83 GeoDataHotSpot::Units xunits;
84 GeoDataHotSpot::Units yunits;
85 QPointF pixelHotSpot = m_style->iconStyle().hotSpot( xunits, yunits );
86
87 switch ( xunits ) {
88 case GeoDataHotSpot::Fraction:
89 pixelHotSpot.setX( iconSize.width() * pixelHotSpot.x() );
90 break;
91 case GeoDataHotSpot::Pixels:
92 /* nothing to do */
93 break;
94 case GeoDataHotSpot::InsetPixels:
95 pixelHotSpot.setX( iconSize.width() - pixelHotSpot.x() );
96 break;
97 }
98
99 switch ( yunits ) {
100 case GeoDataHotSpot::Fraction:
101 pixelHotSpot.setY( iconSize.height() * ( 1.0 - pixelHotSpot.y() ) );
102 break;
103 case GeoDataHotSpot::Pixels:
104 /* nothing to do */
105 break;
106 case GeoDataHotSpot::InsetPixels:
107 pixelHotSpot.setY( iconSize.height() - pixelHotSpot.y() );
108 break;
109 }
110
111 return pixelHotSpot;
112}
113
115{
116 m_symbolPosition = position;
117}
118
120{
121 if (m_labelDirty) {
122 drawLabelPixmap();
123 }
124
125 return m_labelPixmap;
126}
127
128void VisiblePlacemark::setSymbolPixmap()
129{
130 if (m_style) {
131 m_symbolId = m_style->iconStyle().iconPath() + QString::number(m_style->iconStyle().scale());
132 if (m_style->iconStyle().iconPath().isEmpty()) {
133 m_symbolId.clear();
134 m_symbolPixmap = QPixmap::fromImage(m_style->iconStyle().scaledIcon());
135 }
136 emit updateNeeded();
137 }
138 else {
139 mDebug() << "Style pointer is Null";
140 }
141}
142
144{
145 return m_labelRect;
146}
147
149{
150 m_labelRect = labelRect;
151}
152
153void VisiblePlacemark::setStyle(const GeoDataStyle::ConstPtr &style)
154{
155 m_style = style;
156 m_labelDirty = true;
157 setSymbolPixmap();
158}
159
160GeoDataStyle::ConstPtr VisiblePlacemark::style() const
161{
162 return m_style;
163}
164
165QRectF VisiblePlacemark::symbolRect() const
166{
167 return QRectF(m_symbolPosition, m_symbolPixmap.size());
168}
169
170QRectF VisiblePlacemark::boundingBox() const
171{
172 return m_labelRect.isEmpty() ? symbolRect() : m_labelRect.united(symbolRect());
173}
174
175const GeoDataCoordinates &VisiblePlacemark::coordinates() const
176{
177 return m_coordinates;
178}
179
180void VisiblePlacemark::drawLabelPixmap()
181{
182 m_labelDirty = false;
183 QString labelName = m_placemark->displayName();
184 if ( labelName.isEmpty() || m_style->labelStyle().color() == QColor(Qt::transparent) ) {
185 m_labelPixmap = QPixmap();
186 return;
187 }
188
189 QFont labelFont = m_style->labelStyle().scaledFont();
190 QColor labelColor = m_style->labelStyle().color();
191
192 LabelStyle labelStyle = Normal;
193 if ( m_selected ) {
194 labelStyle = Selected;
195 } else if ( m_style->labelStyle().glow() ) {
196 labelStyle = Glow;
197 }
198
200
201 int textWidth;
202 if ( m_style->labelStyle().glow() ) {
203 labelFont.setWeight( 75 ); // Needed to calculate the correct pixmap size;
204 textWidth = ( QFontMetrics( labelFont ).horizontalAdvance( labelName )
205 + qRound( 2 * s_labelOutlineWidth ) );
206 } else {
207 textWidth = ( QFontMetrics( labelFont ).horizontalAdvance( labelName ) );
208 }
209
210 m_labelPixmap = QPixmap( QSize( textWidth, textHeight ) );
211 m_labelPixmap.fill( Qt::transparent );
212
213 QPainter labelPainter( &m_labelPixmap );
214
215 drawLabelText( labelPainter, labelName, labelFont, labelStyle, labelColor );
216}
217
218void VisiblePlacemark::drawLabelText(QPainter &labelPainter, const QString &text,
219 const QFont &labelFont, LabelStyle labelStyle, const QColor &color )
220{
221 QFont font = labelFont;
223 int fontAscent = metrics.ascent();
224
225 switch ( labelStyle ) {
226 case Selected: {
227 labelPainter.setPen( color );
228 labelPainter.setFont( font );
229 QRect textRect( 0, 0, metrics.horizontalAdvance( text ), metrics.height() );
230 labelPainter.fillRect( textRect, QApplication::palette().highlight() );
231 labelPainter.setPen( QPen( QApplication::palette().highlightedText(), 1 ) );
232 labelPainter.drawText( 0, fontAscent, text );
233 break;
234 }
235 case Glow: {
236 font.setWeight( 75 );
237 fontAscent = QFontMetrics( font ).ascent();
238
239 QPen outlinepen( (color.red() + color.green() + color.blue())/3 < 160 ? Qt::white : Qt::black);
240 outlinepen.setWidthF( s_labelOutlineWidth );
241 QBrush outlinebrush( color );
242
244
245 const QPointF baseline( s_labelOutlineWidth / 2.0, fontAscent );
246 outlinepath.addText( baseline, font, text );
247 labelPainter.setRenderHint( QPainter::Antialiasing, true );
248 labelPainter.setPen( outlinepen );
249 labelPainter.setBrush( outlinebrush );
250 labelPainter.drawPath( outlinepath );
251 labelPainter.setPen( Qt::NoPen );
252 labelPainter.drawPath( outlinepath );
253 labelPainter.setRenderHint( QPainter::Antialiasing, false );
254 break;
255 }
256 default: {
257 labelPainter.setPen( color );
258 labelPainter.setFont( font );
259 labelPainter.drawText( 0, fontAscent, text );
260 }
261 }
262}
263
264#include "moc_VisiblePlacemark.cpp"
A 3d point representation.
a class representing a point of interest on the map
QString displayName() const
displays the name of a place in the locale language of the user
const QPointF & symbolPosition() const
Returns the position of the place mark symbol on the map.
const QPixmap & labelPixmap()
Returns the pixmap of the place mark name label.
const QString & symbolId() const
Returns the id for the place mark symbol.
void setSelected(bool selected)
Sets the state of the place mark.
const GeoDataPlacemark * placemark() const
Returns the index of the place mark model which is associated with this visible place mark.
const QPointF hotSpot() const
Returns the top left corner of the place mark symbol's hot spot.
void setLabelRect(const QRectF &area)
Sets the area covered by the place mark name label on the map.
bool selected() const
Returns the state of the place mark.
void setSymbolPosition(const QPointF &position)
Sets the position of the place mark symbol on the map.
const QPixmap & symbolPixmap() const
Returns the pixmap of the place mark symbol.
const QRectF & labelRect() const
Returns the area covered by the place mark name label on the map.
Binds a QML item to a specific geodetic location in screen coordinates.
int blue() const const
int green() const const
int red() const const
void setWeight(Weight weight)
int ascent() const const
int height() const const
int horizontalAdvance(QChar ch) const const
QPalette palette()
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
void fill(const QColor &color)
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
bool isNull() const const
QSize size() const const
bool find(const Key &key, QPixmap *pixmap)
Key insert(const QPixmap &pixmap)
bool isEmpty() const const
int height() const const
int width() const const
void clear()
bool isEmpty() const const
QString number(double n, char format, int precision)
transparent
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:18 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.