From bff27df10c5683189ee2c63ff53eaca1601fd793 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20T=C5=AFma?= Date: Thu, 21 Dec 2023 01:13:36 +0100 Subject: [PATCH] Fixed race conditions on local static data --- gpxsee.pro | 2 ++ src/map/ENC/rastertile.cpp | 78 ++++++++-------------------------------------- src/map/ENC/rastertile.h | 20 +++++++----- src/map/ENC/style.cpp | 28 +++++++++++++++++ src/map/ENC/style.h | 8 +++++ src/map/IMG/rastertile.cpp | 71 +++++++++++------------------------------ src/map/IMG/rastertile.h | 6 ++-- src/map/IMG/style.cpp | 30 ++++++++++++++++++ src/map/IMG/style.h | 5 +++ src/map/encatlas.cpp | 3 +- src/map/encmap.cpp | 7 +++-- src/map/encstyle.cpp | 7 +++++ src/map/encstyle.h | 12 +++++++ 13 files changed, 145 insertions(+), 132 deletions(-) create mode 100644 src/map/encstyle.cpp create mode 100644 src/map/encstyle.h diff --git a/gpxsee.pro b/gpxsee.pro index b99a0040..1ac4044e 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -134,6 +134,7 @@ HEADERS += src/common/config.h \ src/map/encjob.h \ src/map/encmap.h \ src/map/ENC/iso8211.h \ + src/map/encstyle.h \ src/map/gemfmap.h \ src/map/gmifile.h \ src/map/oruxmap.h \ @@ -349,6 +350,7 @@ SOURCES += src/main.cpp \ src/map/encatlas.cpp \ src/map/encmap.cpp \ src/map/ENC/iso8211.cpp \ + src/map/encstyle.cpp \ src/map/gemfmap.cpp \ src/map/gmifile.cpp \ src/map/oruxmap.cpp \ diff --git a/src/map/ENC/rastertile.cpp b/src/map/ENC/rastertile.cpp index 4145c09e..86182dcf 100644 --- a/src/map/ENC/rastertile.cpp +++ b/src/map/ENC/rastertile.cpp @@ -17,51 +17,6 @@ typedef QSet PointSet; static const float C1 = 0.866025f; /* sqrt(3)/2 */ static const QColor haloColor(Qt::white); -static QFont pixelSizeFont(int pixelSize) -{ - QFont f; - f.setPixelSize(pixelSize); - return f; -} - -static QFont *font(Style::FontSize size) -{ - /* The fonts must be initialized on first usage (after the QGuiApplication - instance is created) */ - static QFont large = pixelSizeFont(16); - static QFont normal = pixelSizeFont(12); - static QFont small = pixelSizeFont(10); - - switch (size) { - case Style::None: - return 0; - case Style::Large: - return &large; - case Style::Small: - return &small; - default: - return &normal; - } -} - -static const QImage *light() -{ - static QImage img(":/marine/light.png"); - return &img; -} - -static const QImage *signal() -{ - static QImage img(":/marine/fog-signal.png"); - return &img; -} - -static const Style& style() -{ - static Style s; - return s; -} - static double area(const QVector &polygon) { double area = 0; @@ -223,14 +178,12 @@ void RasterTile::drawArrows(QPainter *painter, void RasterTile::drawPolygons(QPainter *painter, const QList &polygons) { - const Style &s = style(); - - for (int n = 0; n < s.drawOrder().size(); n++) { + for (int n = 0; n < _style->drawOrder().size(); n++) { for (int i = 0; i < polygons.size(); i++) { const MapData::Poly &poly = polygons.at(i); - if (poly.type() != s.drawOrder().at(n)) + if (poly.type() != _style->drawOrder().at(n)) continue; - const Style::Polygon &style = s.polygon(poly.type()); + const Style::Polygon &style = _style->polygon(poly.type()); if (!style.img().isNull()) { for (int i = 0; i < poly.path().size(); i++) @@ -257,13 +210,11 @@ void RasterTile::drawPolygons(QPainter *painter, void RasterTile::drawLines(QPainter *painter, const QList &lines) { - const Style &s = style(); - painter->setBrush(Qt::NoBrush); for (int i = 0; i < lines.size(); i++) { const MapData::Line &line = lines.at(i); - const Style::Line &style = s.line(line.type()); + const Style::Line &style = _style->line(line.type()); if (!style.img().isNull()) { BitmapLine::draw(painter, polyline(line.path()), style.img()); @@ -284,8 +235,6 @@ void RasterTile::drawTextItems(QPainter *painter, void RasterTile::processPolygons(const QList &polygons, QList &textItems) { - const Style &s = style(); - for (int i = 0; i < polygons.size(); i++) { const MapData::Poly &poly = polygons.at(i); uint type = poly.type()>>16; @@ -293,7 +242,7 @@ void RasterTile::processPolygons(const QList &polygons, if (!(type == HRBFAC || type == I_TRNBSN || poly.type() == SUBTYPE(I_BERTHS, 6))) continue; - const Style::Point &style = s.point(poly.type()); + const Style::Point &style = _style->point(poly.type()); const QImage *img = style.img().isNull() ? 0 : &style.img(); if (!img) continue; @@ -311,7 +260,6 @@ void RasterTile::processPolygons(const QList &polygons, void RasterTile::processPoints(QList &points, QList &textItems, QList &lights) { - const Style &s = style(); PointSet lightsSet, signalsSet; int i; @@ -332,12 +280,12 @@ void RasterTile::processPoints(QList &points, for ( ; i < points.size(); i++) { const MapData::Point &point = points.at(i); QPoint pos(ll2xy(point.pos()).toPoint()); - const Style::Point &style = s.point(point.type()); + const Style::Point &style = _style->point(point.type()); const QString *label = point.label().isEmpty() ? 0 : &(point.label()); const QImage *img = style.img().isNull() ? 0 : &style.img(); const QFont *fnt = showLabel(img, _zoomRange, _zoom, point.type()) - ? font(style.textFontSize()) : 0; + ? _style->font(style.textFontSize()) : 0; const QColor *color = &style.textColor(); const QColor *hColor = style.haloColor().isValid() ? &style.haloColor() : 0; @@ -351,9 +299,11 @@ void RasterTile::processPoints(QList &points, if (item->isValid() && !item->collides(textItems)) { textItems.append(item); if (lightsSet.contains(point.pos())) - lights.append(new TextPointItem(pos, 0, 0, light(), 0, 0, 0, 0)); + lights.append(new TextPointItem(pos, 0, 0, _style->light(), 0, + 0, 0, 0)); if (signalsSet.contains(point.pos())) - lights.append(new TextPointItem(pos, 0, 0, signal(), 0, 0, 0, 0)); + lights.append(new TextPointItem(pos, 0, 0, _style->signal(), 0, + 0, 0, 0)); } else delete item; } @@ -362,18 +312,16 @@ void RasterTile::processPoints(QList &points, void RasterTile::processLines(const QList &lines, QList &textItems) { - const Style &s = style(); - for (int i = 0; i < lines.size(); i++) { const MapData::Line &line = lines.at(i); - const Style::Line &style = s.line(line.type()); + const Style::Line &style = _style->line(line.type()); if (style.img().isNull() && style.pen() == Qt::NoPen) continue; if (line.label().isEmpty() || style.textFontSize() == Style::None) continue; - const QFont *fnt = font(style.textFontSize()); + const QFont *fnt = _style->font(style.textFontSize()); const QColor *color = &style.textColor(); TextPathItem *item = new TextPathItem(polyline(line.path()), diff --git a/src/map/ENC/rastertile.h b/src/map/ENC/rastertile.h index 1e027cee..07bdb9c5 100644 --- a/src/map/ENC/rastertile.h +++ b/src/map/ENC/rastertile.h @@ -7,6 +7,7 @@ #include "map/transform.h" #include "map/textpointitem.h" #include "mapdata.h" +#include "style.h" #include "atlasdata.h" class TextItem; @@ -17,15 +18,17 @@ class RasterTile { public: RasterTile(const Projection &proj, const Transform &transform, - const MapData *data, int zoom, const Range &zoomRange, const QRect &rect, - qreal ratio) : _proj(proj), _transform(transform), _map(data), _atlas(0), - _zoom(zoom), _zoomRange(zoomRange), _rect(rect), _ratio(ratio), - _pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {} + const Style *style, const MapData *data, int zoom, const Range &zoomRange, + const QRect &rect, qreal ratio) : _proj(proj), _transform(transform), + _style(style), _map(data), _atlas(0), _zoom(zoom), _zoomRange(zoomRange), + _rect(rect), _ratio(ratio), _pixmap(rect.width() * ratio, rect.height() + * ratio), _valid(false) {} RasterTile(const Projection &proj, const Transform &transform, - AtlasData *data, int zoom, const Range &zoomRange, const QRect &rect, - qreal ratio) : _proj(proj), _transform(transform), _map(0), _atlas(data), - _zoom(zoom), _zoomRange(zoomRange), _rect(rect), _ratio(ratio), - _pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {} + const Style *style, AtlasData *data, int zoom, const Range &zoomRange, + const QRect &rect, qreal ratio) : _proj(proj), _transform(transform), + _style(style), _map(0), _atlas(data), _zoom(zoom), _zoomRange(zoomRange), + _rect(rect), _ratio(ratio), _pixmap(rect.width() * ratio, rect.height() + * ratio), _valid(false) {} int zoom() const {return _zoom;} QPoint xy() const {return _rect.topLeft();} @@ -61,6 +64,7 @@ private: Projection _proj; Transform _transform; + const Style *_style; const MapData *_map; AtlasData *_atlas; int _zoom; diff --git a/src/map/ENC/style.cpp b/src/map/ENC/style.cpp index f74d0de3..a9f0d2c8 100644 --- a/src/map/ENC/style.cpp +++ b/src/map/ENC/style.cpp @@ -14,6 +14,13 @@ static QImage railroad() return img; } +static QFont pixelSizeFont(int pixelSize) +{ + QFont f; + f.setPixelSize(pixelSize); + return f; +} + void Style::polygonStyle() { _polygons[TYPE(M_COVR)] = Polygon(QBrush("#ffffff")); @@ -321,6 +328,13 @@ void Style::pointStyle() Style::Style() { + _light = QImage(":/marine/light.png"); + _signal = QImage(":/marine/fog-signal.png"); + + _large = pixelSizeFont(16); + _normal = pixelSizeFont(12); + _small = pixelSizeFont(10); + polygonStyle(); lineStyle(); pointStyle(); @@ -349,3 +363,17 @@ const Style::Point &Style::point(uint type) const QMap::const_iterator it = _points.find(type); return (it == _points.constEnd()) ? null : *it; } + +const QFont *Style::font(Style::FontSize size) const +{ + switch (size) { + case Style::None: + return 0; + case Style::Large: + return &_large; + case Style::Small: + return &_small; + default: + return &_normal; + } +} diff --git a/src/map/ENC/style.h b/src/map/ENC/style.h index f36373b6..642e89f9 100644 --- a/src/map/ENC/style.h +++ b/src/map/ENC/style.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "objects.h" @@ -96,6 +97,10 @@ public: const Point &point(uint type) const; const QVector &drawOrder() const {return _drawOrder;} + const QFont *font(Style::FontSize size) const; + const QImage *light() const {return &_light;} + const QImage *signal() const {return &_signal;} + private: void polygonStyle(); void lineStyle(); @@ -105,6 +110,9 @@ private: QMap _polygons; QMap _points; QVector _drawOrder; + + QFont _small, _normal, _large; + QImage _light, _signal; }; } diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp index 481b98a0..3c7bb86a 100644 --- a/src/map/IMG/rastertile.cpp +++ b/src/map/IMG/rastertile.cpp @@ -28,57 +28,6 @@ static const QColor shieldBgColor1("#dd3e3e"); static const QColor shieldBgColor2("#379947"); static const QColor shieldBgColor3("#4a7fc1"); -static QFont pixelSizeFont(int pixelSize) -{ - QFont f; - f.setPixelSize(pixelSize); - return f; -} - -static QFont *font(Style::FontSize size, Style::FontSize defaultSize - = Style::Normal) -{ - /* The fonts must be initialized on first usage (after the QGuiApplication - instance is created) */ - static QFont large = pixelSizeFont(16); - static QFont normal = pixelSizeFont(14); - static QFont small = pixelSizeFont(12); - static QFont extraSmall = pixelSizeFont(10); - - switch (size) { - case Style::None: - return 0; - case Style::Large: - return &large; - case Style::Normal: - return &normal; - case Style::Small: - return &small; - case Style::ExtraSmall: - return &extraSmall; - default: - return font(defaultSize); - } -} - -static QFont *poiFont(Style::FontSize size = Style::Normal, int zoom = -1, - bool extended = false) -{ - static QFont poi = pixelSizeFont(10); - - if (zoom > 25) - size = Style::Normal; - else if (extended) - size = Style::None; - - switch (size) { - case Style::None: - return 0; - default: - return &poi; - } -} - static const QColor *shieldBgColor(Shield::Type type) { switch (type) { @@ -152,6 +101,21 @@ static bool rectNearPolygon(const QPolygonF &polygon, const QRectF &rect) || polygon.containsPoint(rect.bottomRight(), Qt::OddEvenFill))); } +const QFont *RasterTile::poiFont(Style::FontSize size, int zoom, bool extended) +{ + if (zoom > 25) + size = Style::Normal; + else if (extended) + size = Style::None; + + switch (size) { + case Style::None: + return 0; + default: + return _data->style()->font(Style::ExtraSmall); + } +} + void RasterTile::ll2xy(QList &polys) { for (int i = 0; i < polys.size(); i++) { @@ -324,7 +288,8 @@ void RasterTile::processStreetNames(const QList &lines, if (style.img().isNull() && style.foreground() == Qt::NoPen) continue; - const QFont *fnt = font(style.textFontSize(), Style::Small); + const QFont *fnt = _data->style()->font(style.textFontSize(), + Style::Small); const QColor *color = style.textColor().isValid() ? &style.textColor() : 0; const QColor *hColor = Style::isContourLine(poly.type) ? 0 : &haloColor; @@ -435,7 +400,7 @@ void RasterTile::processPoints(QList &points, const QImage *img = style.img().isNull() ? 0 : &style.img(); const QFont *fnt = poi ? poiFont(style.textFontSize(), _zoom, point.classLabel) - : font(style.textFontSize()); + : _data->style()->font(style.textFontSize()); const QColor *color = style.textColor().isValid() ? &style.textColor() : &textColor; const QColor *hcolor = Style::isDepthPoint(point.type) diff --git a/src/map/IMG/rastertile.h b/src/map/IMG/rastertile.h index 0b611559..1c977497 100644 --- a/src/map/IMG/rastertile.h +++ b/src/map/IMG/rastertile.h @@ -5,6 +5,7 @@ #include "mapdata.h" #include "map/projection.h" #include "map/transform.h" +#include "style.h" class QPainter; class IMGMap; @@ -12,8 +13,6 @@ class TextItem; namespace IMG { -class Style; - class RasterTile { public: @@ -53,6 +52,9 @@ private: void processStreetNames(const QList &lines, QList &textItems, const QImage (&arrows)[2]); + const QFont *poiFont(Style::FontSize size = Style::Normal, + int zoom = -1, bool extended = false); + Projection _proj; Transform _transform; MapData *_data; diff --git a/src/map/IMG/style.cpp b/src/map/IMG/style.cpp index 49f27ce3..4b6fac5f 100644 --- a/src/map/IMG/style.cpp +++ b/src/map/IMG/style.cpp @@ -4,6 +4,13 @@ using namespace IMG; +static QFont pixelSizeFont(int pixelSize) +{ + QFont f; + f.setPixelSize(pixelSize); + return f; +} + static bool readColor(SubFile *file, SubFile::Handle &hdl, QColor &color) { quint8 b, g, r; @@ -1226,6 +1233,11 @@ bool Style::parseTYPFile(SubFile *file) Style::Style(SubFile *typ) { + _large = pixelSizeFont(16); + _normal = pixelSizeFont(14); + _small = pixelSizeFont(12); + _extraSmall = pixelSizeFont(10); + defaultLineStyle(); defaultPolygonStyle(); defaultPointStyle(); @@ -1258,6 +1270,24 @@ const Style::Point &Style::point(quint32 type) const return (it == _points.constEnd()) ? null : *it; } +const QFont *Style::font(Style::FontSize size, Style::FontSize defaultSize) const +{ + switch (size) { + case Style::None: + return 0; + case Style::Large: + return &_large; + case Style::Normal: + return &_normal; + case Style::Small: + return &_small; + case Style::ExtraSmall: + return &_extraSmall; + default: + return font(defaultSize); + } +} + #ifndef QT_NO_DEBUG static QString penColor(const QPen &pen) { diff --git a/src/map/IMG/style.h b/src/map/IMG/style.h index 559dde73..8a5665c1 100644 --- a/src/map/IMG/style.h +++ b/src/map/IMG/style.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "subfile.h" @@ -94,6 +95,8 @@ public: const Polygon &polygon(quint32 type) const; const Point &point(quint32 type) const; const QList &drawOrder() const {return _drawOrder;} + const QFont *font(Style::FontSize size, Style::FontSize defaultSize + = Style::Normal) const; static bool isPOI(quint32 type) {return !((type >= TYPE(0x01) && type <= TYPE(0x1f)) @@ -172,6 +175,8 @@ private: QMap _polygons; QMap _points; QList _drawOrder; + + QFont _large, _normal, _small, _extraSmall; }; } diff --git a/src/map/encatlas.cpp b/src/map/encatlas.cpp index 2e08625f..08574240 100644 --- a/src/map/encatlas.cpp +++ b/src/map/encatlas.cpp @@ -5,6 +5,7 @@ #include "rectd.h" #include "pcs.h" #include "encjob.h" +#include "encstyle.h" #include "encatlas.h" using namespace ENC; @@ -357,7 +358,7 @@ void ENCAtlas::draw(QPainter *painter, const QRectF &rect, Flags flags) painter->drawPixmap(ttl, pm); else tiles.append(RasterTile(_projection, _transform, - _data.value(_usage), _zoom, zooms(_usage), + ENCStyle::style(), _data.value(_usage), _zoom, zooms(_usage), QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio)); } } diff --git a/src/map/encmap.cpp b/src/map/encmap.cpp index e37f67a1..8da435d1 100644 --- a/src/map/encmap.cpp +++ b/src/map/encmap.cpp @@ -5,6 +5,7 @@ #include "rectd.h" #include "pcs.h" #include "encjob.h" +#include "encstyle.h" #include "encmap.h" @@ -323,9 +324,9 @@ void ENCMap::draw(QPainter *painter, const QRectF &rect, Flags flags) if (QPixmapCache::find(key(_zoom, ttl), &pm)) painter->drawPixmap(ttl, pm); else - tiles.append(RasterTile(_projection, _transform, _data, - _zoom, _zooms, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), - _tileRatio)); + tiles.append(RasterTile(_projection, _transform, + ENCStyle::style(), _data, _zoom, _zooms, + QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio)); } } diff --git a/src/map/encstyle.cpp b/src/map/encstyle.cpp new file mode 100644 index 00000000..f90026ff --- /dev/null +++ b/src/map/encstyle.cpp @@ -0,0 +1,7 @@ +#include "encstyle.h" + +const ENC::Style *ENCStyle::style() +{ + static ENC::Style s; + return &s; +} diff --git a/src/map/encstyle.h b/src/map/encstyle.h new file mode 100644 index 00000000..cf914735 --- /dev/null +++ b/src/map/encstyle.h @@ -0,0 +1,12 @@ +#ifndef ENCSTYLE_H +#define ENCSTYLE_H + +#include "ENC/style.h" + +class ENCStyle +{ +public: + static const ENC::Style *style(); +}; + +#endif // ENCSTYLE_H -- 2.11.4.GIT