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 "GeoDataIconStyle.h"
13#include "GeoDataLabelStyle.h"
14#include "GeoDataPlacemark.h"
15#include "GeoDataStyle.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 connect(remoteLoader, &RemoteIconLoader::iconReady, this, &VisiblePlacemark::setSymbolPixmap);
35
36 setSymbolPixmap();
37}
38
40{
41 return m_placemark;
42}
43
45{
46 if (!m_symbolId.isEmpty() && m_symbolPixmap.isNull()) {
47 if (!QPixmapCache::find(m_symbolId, &m_symbolPixmap)) {
48 m_symbolPixmap = QPixmap::fromImage(m_style->iconStyle().scaledIcon());
49 QPixmapCache::insert(m_symbolId, m_symbolPixmap);
50 }
51 }
52 return m_symbolPixmap;
53}
54
56{
57 return m_symbolId;
58}
59
61{
62 return m_selected;
63}
64
66{
67 if (selected != m_selected) {
68 m_selected = selected;
69 m_labelDirty = true;
70 }
71}
72
74{
75 return m_symbolPosition;
76}
77
79{
80 const QSize iconSize = m_style->iconStyle().scaledIcon().size();
81
82 GeoDataHotSpot::Units xunits;
83 GeoDataHotSpot::Units yunits;
84 QPointF pixelHotSpot = m_style->iconStyle().hotSpot(xunits, yunits);
85
86 switch (xunits) {
87 case GeoDataHotSpot::Fraction:
88 pixelHotSpot.setX(iconSize.width() * pixelHotSpot.x());
89 break;
90 case GeoDataHotSpot::Pixels:
91 /* nothing to do */
92 break;
93 case GeoDataHotSpot::InsetPixels:
94 pixelHotSpot.setX(iconSize.width() - pixelHotSpot.x());
95 break;
96 }
97
98 switch (yunits) {
99 case GeoDataHotSpot::Fraction:
100 pixelHotSpot.setY(iconSize.height() * (1.0 - pixelHotSpot.y()));
101 break;
102 case GeoDataHotSpot::Pixels:
103 /* nothing to do */
104 break;
105 case GeoDataHotSpot::InsetPixels:
106 pixelHotSpot.setY(iconSize.height() - pixelHotSpot.y());
107 break;
108 }
109
110 return pixelHotSpot;
111}
112
114{
115 m_symbolPosition = position;
116}
117
119{
120 if (m_labelDirty) {
121 drawLabelPixmap();
122 }
123
124 return m_labelPixmap;
125}
126
127void VisiblePlacemark::setSymbolPixmap()
128{
129 if (m_style) {
130 m_symbolId = m_style->iconStyle().iconPath() + QString::number(m_style->iconStyle().scale());
131 if (m_style->iconStyle().iconPath().isEmpty()) {
132 m_symbolId.clear();
133 m_symbolPixmap = QPixmap::fromImage(m_style->iconStyle().scaledIcon());
134 }
135 Q_EMIT updateNeeded();
136 } else {
137 mDebug() << "Style pointer is Null";
138 }
139}
140
142{
143 return m_labelRect;
144}
145
147{
148 m_labelRect = labelRect;
149}
150
151void VisiblePlacemark::setStyle(const GeoDataStyle::ConstPtr &style)
152{
153 m_style = style;
154 m_labelDirty = true;
155 setSymbolPixmap();
156}
157
158GeoDataStyle::ConstPtr VisiblePlacemark::style() const
159{
160 return m_style;
161}
162
163QRectF VisiblePlacemark::symbolRect() const
164{
165 return QRectF(m_symbolPosition, m_symbolPixmap.size());
166}
167
168QRectF VisiblePlacemark::boundingBox() const
169{
170 return m_labelRect.isEmpty() ? symbolRect() : m_labelRect.united(symbolRect());
171}
172
173const GeoDataCoordinates &VisiblePlacemark::coordinates() const
174{
175 return m_coordinates;
176}
177
178void VisiblePlacemark::drawLabelPixmap()
179{
180 m_labelDirty = false;
181 QString labelName = m_placemark->displayName();
182 if (labelName.isEmpty() || m_style->labelStyle().color() == QColor(Qt::transparent)) {
183 m_labelPixmap = QPixmap();
184 return;
185 }
186
187 QFont labelFont = m_style->labelStyle().scaledFont();
188 QColor labelColor = m_style->labelStyle().color();
189
190 LabelStyle labelStyle = Normal;
191 if (m_selected) {
192 labelStyle = Selected;
193 } else if (m_style->labelStyle().glow()) {
194 labelStyle = Glow;
195 }
196
197 int textHeight = QFontMetrics(labelFont).height();
198
199 int textWidth;
200 if (m_style->labelStyle().glow()) {
201 labelFont.setWeight(QFont::Bold); // Needed to calculate the correct pixmap size;
202 textWidth = (QFontMetrics(labelFont).horizontalAdvance(labelName) + qRound(2 * s_labelOutlineWidth));
203 } else {
204 textWidth = (QFontMetrics(labelFont).horizontalAdvance(labelName));
205 }
206
207 m_labelPixmap = QPixmap(QSize(textWidth, textHeight));
208 m_labelPixmap.fill(Qt::transparent);
209
210 QPainter labelPainter(&m_labelPixmap);
211
212 drawLabelText(labelPainter, labelName, labelFont, labelStyle, labelColor);
213}
214
215void VisiblePlacemark::drawLabelText(QPainter &labelPainter, const QString &text, const QFont &labelFont, LabelStyle labelStyle, const QColor &color)
216{
217 QFont font = labelFont;
218 QFontMetrics metrics = QFontMetrics(font);
219 int fontAscent = metrics.ascent();
220
221 switch (labelStyle) {
222 case Selected: {
223 labelPainter.setPen(color);
224 labelPainter.setFont(font);
225 QRect textRect(0, 0, metrics.horizontalAdvance(text), metrics.height());
226 labelPainter.fillRect(textRect, QApplication::palette().highlight());
227 labelPainter.setPen(QPen(QApplication::palette().highlightedText(), 1));
228 labelPainter.drawText(0, fontAscent, text);
229 break;
230 }
231 case Glow: {
233 fontAscent = QFontMetrics(font).ascent();
234
235 QPen outlinepen((color.red() + color.green() + color.blue()) / 3 < 160 ? Qt::white : Qt::black);
236 outlinepen.setWidthF(s_labelOutlineWidth);
237 QBrush outlinebrush(color);
238
239 QPainterPath outlinepath;
240
241 const QPointF baseline(s_labelOutlineWidth / 2.0, fontAscent);
242 outlinepath.addText(baseline, font, text);
243 labelPainter.setRenderHint(QPainter::Antialiasing, true);
244 labelPainter.setPen(outlinepen);
245 labelPainter.setBrush(outlinebrush);
246 labelPainter.drawPath(outlinepath);
247 labelPainter.setPen(Qt::NoPen);
248 labelPainter.drawPath(outlinepath);
249 labelPainter.setRenderHint(QPainter::Antialiasing, false);
250 break;
251 }
252 default: {
253 labelPainter.setPen(color);
254 labelPainter.setFont(font);
255 labelPainter.drawText(0, fontAscent, text);
256 }
257 }
258}
259
260#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()
Q_EMITQ_EMIT
void drawPath(const QPainterPath &path)
void drawText(const QPoint &position, const QString &text)
void fillRect(const QRect &rectangle, QGradient::Preset preset)
void setBrush(Qt::BrushStyle style)
void setFont(const QFont &font)
void setPen(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
void addText(const QPointF &point, const QFont &font, const QString &text)
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)
void setX(qreal x)
void setY(qreal y)
qreal x() const const
qreal y() const const
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
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:37:04 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.