diff --git a/src/function.h b/src/function.h index fbd2ec8..cda8934 100644 --- a/src/function.h +++ b/src/function.h @@ -22,9 +22,9 @@ private: class FunctionC { public: - FunctionC(const QColor &deflt = QColor()) + FunctionC(const QColor &deflt = QColor(Qt::black)) : _default(deflt), _base(1.0) {} - FunctionC(const QJsonObject &json, const QColor &dflt = QColor()); + FunctionC(const QJsonObject &json, const QColor &dflt = QColor(Qt::black)); QColor value(qreal x) const; diff --git a/src/style.cpp b/src/style.cpp index 0bb2565..510d2df 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -141,11 +141,14 @@ Style::Layer::Paint::Paint(const QJsonObject &json) _fillOpacity = FunctionF(json["fill-opacity"].toDouble()); else if (json.contains("fill-opacity") && json["fill-opacity"].isObject()) _fillOpacity = FunctionF(json["fill-opacity"].toObject()); - if (json.contains("fill-color") && json["fill-color"].isString()) + if (json.contains("fill-color") && json["fill-color"].isString()) { _fillColor = FunctionC(Color::fromJsonString( json["fill-color"].toString())); - if (json.contains("fill-color") && json["fill-color"].isObject()) + _fillOutlineColor = _fillColor; + } else if (json.contains("fill-color") && json["fill-color"].isObject()) { _fillColor = FunctionC(json["fill-color"].toObject()); + _fillOutlineColor = _fillColor; + } if (json.contains("fill-outline-color") && json["fill-outline-color"].isString()) _fillOutlineColor = FunctionC(Color::fromJsonString( @@ -155,6 +158,11 @@ Style::Layer::Paint::Paint(const QJsonObject &json) _fillOutlineColor = FunctionC(json["fill-outline-color"].toObject()); if (json.contains("fill-antialias") && json["fill-antialias"].isBool()) _fillAntialias = json["fill-antialias"].toBool(); + if (json.contains("fill-pattern")) { + _fillColor = FunctionC(QColor()); + _fillOutlineColor = FunctionC(QColor()); + } + if (json.contains("line-color") && json["line-color"].isString()) _lineColor = FunctionC(Color::fromJsonString(json["line-color"] @@ -208,11 +216,6 @@ QPen Style::Layer::Paint::pen(Type type, int zoom) const color = _fillOutlineColor.value(zoom); if (color.isValid()) pen = QPen(color); - else { - color = _fillColor.value(zoom); - if (color.isValid()) - pen = QPen(color); - } break; case Symbol: color = _textColor.value(zoom); @@ -267,8 +270,8 @@ bool Style::Layer::Paint::antialias(Layer::Type type) const } Style::Layer::Layout::Layout(const QJsonObject &json) - : _textSize(16), _textMaxWidth(10), _textMaxAngle(45), _lineCap(Qt::FlatCap), - _lineJoin(Qt::MiterJoin), _capitalize(false) + : _textSize(16), _textMaxWidth(10), _textMaxAngle(45), _symbolSpacing(250), + _lineCap(Qt::FlatCap), _lineJoin(Qt::MiterJoin), _capitalize(false) { if (!(json.contains("text-field") && json["text-field"].isString())) return; @@ -296,6 +299,11 @@ Style::Layer::Layout::Layout(const QJsonObject &json) else if (json.contains("text-max-angle") && json["text-max-angle"].isDouble()) _textMaxWidth = json["text-max-angle"].toDouble(); + if (json.contains("symbol-spacing") && json["symbol-spacing"].isObject()) + _symbolSpacing = json["symbol-spacing"].toObject(); + else if (json.contains("symbol-spacing") && json["symbol-spacing"].isDouble()) + _symbolSpacing = json["symbol-spacing"].toDouble(); + if (json.contains("text-transform") && json["text-transform"].isString()) _capitalize = json["text-transform"].toString() == "uppercase"; @@ -409,7 +417,7 @@ void Style::Layer::drawSymbol(int zoom, const QPainterPath &path, _layout.maxTextWidth(zoom)); else tile.text().addLabel(text.trimmed(), path, font, pen, - _layout.maxTextAngle(zoom)); + _layout.maxTextAngle(zoom), _layout.symbolSpacing(zoom)); } bool Style::load(const QString &fileName) diff --git a/src/style.h b/src/style.h index c713320..3aecdd8 100644 --- a/src/style.h +++ b/src/style.h @@ -79,13 +79,17 @@ private: class Layout { public: Layout() : _textSize(16), _textMaxWidth(10), _textMaxAngle(45), - _lineCap(Qt::FlatCap), _lineJoin(Qt::MiterJoin), - _capitalize(false) {} + _symbolSpacing(250), _lineCap(Qt::FlatCap), + _lineJoin(Qt::MiterJoin), _capitalize(false) {} Layout(const QJsonObject &json); bool capitalize() const {return _capitalize;} - qreal maxTextWidth(int zoom) const {return _textMaxWidth.value(zoom);} - qreal maxTextAngle(int zoom) const {return _textMaxAngle.value(zoom);} + qreal maxTextWidth(int zoom) const + {return _textMaxWidth.value(zoom);} + qreal maxTextAngle(int zoom) const + {return _textMaxAngle.value(zoom);} + qreal symbolSpacing(int zoom) const + {return _symbolSpacing.value(zoom);} const QString &field() const {return _textField;} const QStringList &keys() const {return _keys;} QFont font(int zoom) const; @@ -98,6 +102,7 @@ private: FunctionF _textSize; FunctionF _textMaxWidth; FunctionF _textMaxAngle; + FunctionF _symbolSpacing; Qt::PenCapStyle _lineCap; Qt::PenJoinStyle _lineJoin; bool _capitalize; diff --git a/src/text.cpp b/src/text.cpp index 961c2e8..55216f9 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -6,43 +6,60 @@ #include "textpathitem.h" -static QPainterPath subpath(const QPainterPath &path, int start, int end) +static QPainterPath subpath(const QPainterPath &path, int start, int end, + qreal cut) { QPainterPath p(path.elementAt(start)); - for (int i = start + 1; i <= end; i++) + + for (int i = start + 1; i < end; i++) p.lineTo(path.elementAt(i)); + + QLineF l(path.elementAt(end - 1), path.elementAt(end)); + l.setLength(l.length() - cut); + p.lineTo(l.p2()); + return p; } -static QList segments(const QPainterPath &path, qreal pathLimit, - qreal maxAngle, qreal charWidth, const QRectF &tileRect) +static QList segments(const QPainterPath &path, qreal textLength, + qreal maxAngle, qreal charWidth, int symbolSpacing, const QRectF &tileRect) { QList list; int start = 0; qreal length = 0; qreal angle = -1; + qreal dist = symbolSpacing; for (int i = 1; i < path.elementCount(); i++) { QLineF l(path.elementAt(i-1), path.elementAt(i)); - qreal a = l.angle(); qreal sl = l.length(); + + if (dist < symbolSpacing) { + dist += sl; + start++; + continue; + } + + qreal a = l.angle(); if (angle < 0) angle = a; + if (!tileRect.contains(path.elementAt(i)) || sl < charWidth || qAbs(angle - a) > maxAngle - || length > pathLimit) { - if (length > pathLimit) - list.append(subpath(path, start, i - 1)); + || length > textLength) { + if (length > textLength) { + list.append(subpath(path, start, i - 1, length - textLength - 1)); + dist = 0; + } start = i; length = 0; } else length += sl; + + dist += sl; angle = a; } - if (length > pathLimit) - list.append(subpath(path, start, path.elementCount() - 1)); - return list; } @@ -76,7 +93,7 @@ void Text::addLabel(const QString &text, const QPointF &pos, const QFont &font, } void Text::addLabel(const QString &text, const QPainterPath &path, - const QFont &font, const QPen &pen, qreal maxAngle) + const QFont &font, const QPen &pen, qreal maxAngle, qreal symbolSpacing) { if (path.elementCount() < 2 || !path.elementAt(0).isMoveTo()) return; @@ -90,7 +107,7 @@ void Text::addLabel(const QString &text, const QPainterPath &path, return; QList list(segments(path, textWidth, maxAngle, - fm.averageCharWidth(), sceneRect())); + fm.averageCharWidth(), symbolSpacing, sceneRect())); for (int i = 0; i < list.size(); i++) { const QPainterPath &segment = list.at(i); TextPathItem *pi = new TextPathItem(text, reverse(segment) diff --git a/src/text.h b/src/text.h index 0649290..894044f 100644 --- a/src/text.h +++ b/src/text.h @@ -12,7 +12,7 @@ public: void addLabel(const QString &text, const QPointF &pos, const QFont &font, const QPen &pen, qreal maxTextWidth); void addLabel(const QString &text, const QPainterPath &path, - const QFont &font, const QPen &pen, qreal maxAngle); + const QFont &font, const QPen &pen, qreal maxAngle, qreal symbolSpacing); }; #endif // TEXT_H