Made almost every paint/layout property "zoom-capable"

This commit is contained in:
Martin Tůma 2018-11-24 09:52:54 +01:00
parent 4cab88d79a
commit e9bf62dd2e
4 changed files with 154 additions and 158 deletions

View File

@ -44,13 +44,18 @@ static QColor interpolate(const QPair<qreal, QColor> &p0,
f(p0l, p1l, ratio), f(p0a, p1a, ratio));
}
FunctionF::FunctionF(const QJsonObject &json, qreal dflt)
FunctionF::FunctionF(const QJsonValue &json, qreal dflt)
: _default(dflt), _base(1.0)
{
if (!(json.contains("stops") && json["stops"].isArray()))
if (json.isDouble())
_default = json.toDouble();
else if (json.isObject()) {
QJsonObject obj(json.toObject());
if (!(obj.contains("stops") && obj["stops"].isArray()))
return;
QJsonArray stops = json["stops"].toArray();
QJsonArray stops = obj["stops"].toArray();
for (int i = 0; i < stops.size(); i++) {
if (!stops.at(i).isArray())
return;
@ -60,8 +65,9 @@ FunctionF::FunctionF(const QJsonObject &json, qreal dflt)
_stops.append(QPointF(stop.at(0).toDouble(), stop.at(1).toDouble()));
}
if (json.contains("base") && json["base"].isDouble())
_base = json["base"].toDouble();
if (obj.contains("base") && obj["base"].isDouble())
_base = obj["base"].toDouble();
}
}
qreal FunctionF::value(qreal x) const
@ -80,14 +86,18 @@ qreal FunctionF::value(qreal x) const
return _stops.last().y();
}
FunctionC::FunctionC(const QJsonObject &json, const QColor &dflt)
FunctionC::FunctionC(const QJsonValue &json, const QColor &dflt)
: _default(dflt), _base(1.0)
{
if (!(json.contains("stops") && json["stops"].isArray()))
if (json.isString())
_default = Color::fromJsonString(json.toString());
else if (json.isObject()) {
QJsonObject obj(json.toObject());
if (!(obj.contains("stops") && obj["stops"].isArray()))
return;
QJsonArray stops = json["stops"].toArray();
QJsonArray stops = obj["stops"].toArray();
for (int i = 0; i < stops.size(); i++) {
if (!stops.at(i).isArray())
return;
@ -98,8 +108,9 @@ FunctionC::FunctionC(const QJsonObject &json, const QColor &dflt)
Color::fromJsonString(stop.at(1).toString())));
}
if (json.contains("base") && json["base"].isDouble())
_base = json["base"].toDouble();
if (obj.contains("base") && obj["base"].isDouble())
_base = obj["base"].toDouble();
}
}
QColor FunctionC::value(qreal x) const
@ -118,12 +129,17 @@ QColor FunctionC::value(qreal x) const
return _stops.last().second;
}
FunctionB::FunctionB(const QJsonObject &json, bool dflt) : _default(dflt)
FunctionB::FunctionB(const QJsonValue &json, bool dflt) : _default(dflt)
{
if (!(json.contains("stops") && json["stops"].isArray()))
if (json.isBool())
_default = json.toBool();
else if (json.isObject()) {
QJsonObject obj(json.toObject());
if (!(obj.contains("stops") && obj["stops"].isArray()))
return;
QJsonArray stops = json["stops"].toArray();
QJsonArray stops = obj["stops"].toArray();
for (int i = 0; i < stops.size(); i++) {
if (!stops.at(i).isArray())
return;
@ -133,6 +149,7 @@ FunctionB::FunctionB(const QJsonObject &json, bool dflt) : _default(dflt)
_stops.append(QPair<qreal, bool>(stop.at(0).toDouble(),
stop.at(1).toBool()));
}
}
}
bool FunctionB::value(qreal x) const
@ -151,13 +168,18 @@ bool FunctionB::value(qreal x) const
return _stops.last().second;
}
FunctionS::FunctionS(const QJsonObject &json, const QString &dflt)
FunctionS::FunctionS(const QJsonValue &json, const QString &dflt)
: _default(dflt)
{
if (!(json.contains("stops") && json["stops"].isArray()))
if (json.isString())
_default = json.toString();
else if (json.isObject()) {
QJsonObject obj(json.toObject());
if (!(obj.contains("stops") && obj["stops"].isArray()))
return;
QJsonArray stops = json["stops"].toArray();
QJsonArray stops = obj["stops"].toArray();
for (int i = 0; i < stops.size(); i++) {
if (!stops.at(i).isArray())
return;
@ -167,6 +189,7 @@ FunctionS::FunctionS(const QJsonObject &json, const QString &dflt)
_stops.append(QPair<qreal, QString>(stop.at(0).toDouble(),
stop.at(1).toString()));
}
}
}
const QString FunctionS::value(qreal x) const

View File

@ -10,7 +10,7 @@ class QJsonObject;
class FunctionB {
public:
FunctionB(bool deflt = true) : _default(deflt) {}
FunctionB(const QJsonObject &json, bool dflt = true);
FunctionB(const QJsonValue &json, bool dflt = true);
bool value(qreal x) const;
@ -22,7 +22,7 @@ private:
class FunctionS {
public:
FunctionS(const QString &deflt = QString()) : _default(deflt) {}
FunctionS(const QJsonObject &json, const QString &dflt = QString());
FunctionS(const QJsonValue &json, const QString &dflt = QString());
const QString value(qreal x) const;
@ -34,7 +34,7 @@ private:
class FunctionF {
public:
FunctionF(qreal deflt = 0) : _default(deflt), _base(1.0) {}
FunctionF(const QJsonObject &json, qreal dflt = 0);
FunctionF(const QJsonValue &json, qreal dflt = 0);
qreal value(qreal x) const;
@ -48,7 +48,7 @@ class FunctionC {
public:
FunctionC(const QColor &deflt = QColor(Qt::black))
: _default(deflt), _base(1.0) {}
FunctionC(const QJsonObject &json, const QColor &dflt = QColor(Qt::black));
FunctionC(const QJsonValue &json, const QColor &dflt = QColor(Qt::black));
QColor value(qreal x) const;

View File

@ -13,50 +13,6 @@
#include "style.h"
static void jsonColor(const QJsonObject &json, const char *name, FunctionC &var)
{
if (json.contains(name)) {
const QJsonValue value = json[name];
if (value.isString())
var = FunctionC(Color::fromJsonString(value.toString()));
else if (value.isObject())
var = FunctionC(value.toObject());
}
}
static void jsonFloat(const QJsonObject &json, const char *name, FunctionF &var)
{
if (json.contains(name)) {
const QJsonValue value = json[name];
if (value.isDouble())
var = FunctionF(value.toDouble());
else if (value.isObject())
var = FunctionF(value.toObject());
}
}
static void jsonBool(const QJsonObject &json, const char *name, FunctionB &var)
{
if (json.contains(name)) {
QJsonValue value = json[name];
if (value.isBool())
var = FunctionB(value.toBool());
else if (value.isObject())
var = FunctionB(value.toObject());
}
}
static void jsonString(const QJsonObject &json, const char *name, FunctionS &var)
{
if (json.contains(name)) {
QJsonValue value = json[name];
if (value.isString())
var = FunctionS(value.toString());
else if (value.isObject())
var = FunctionS(value.toObject());
}
}
Style::Layer::Filter::Filter(const QJsonArray &json)
: _type(Unknown), _not(false)
{
@ -202,24 +158,25 @@ QString Style::Layer::Template::value(int zoom, const QVariantHash &tags) const
}
Style::Layer::Paint::Paint(const QJsonObject &json)
: _fillOpacity(1.0), _lineOpacity(1.0), _lineWidth(1.0)
{
// fill
jsonFloat(json, "fill-opacity", _fillOpacity);
jsonColor(json, "fill-color", _fillColor);
_fillOpacity = FunctionF(json["fill-opacity"], 1.0);
_fillColor = FunctionC(json["fill-color"]);
if (json.contains("fill-outline-color"))
_fillOutlineColor = FunctionC(json["fill-outline-color"]);
else
_fillOutlineColor = _fillColor;
jsonColor(json, "fill-outline-color", _fillOutlineColor);
jsonBool(json, "fill-antialias",_fillAntialias);
jsonString(json, "fill-pattern", _fillPattern);
_fillAntialias = FunctionB(json["fill-antialias"]);
if (json.contains("fill-pattern")) {
_fillPattern = FunctionS(json["fill-pattern"]);
_fillColor = FunctionC(QColor());
_fillOutlineColor = FunctionC(QColor());
}
// line
jsonColor(json, "line-color", _lineColor);
jsonFloat(json, "line-width", _lineWidth);
jsonFloat(json, "line-opacity", _lineOpacity);
_lineColor = FunctionC(json["line-color"]);
_lineWidth = FunctionF(json["line-width"], 1.0);
_lineOpacity = FunctionF(json["line-opacity"], 1.0);
if (json.contains("line-dasharray") && json["line-dasharray"].isArray()) {
QJsonArray array = json["line-dasharray"].toArray();
for (int i = 0; i < array.size(); i++)
@ -227,10 +184,10 @@ Style::Layer::Paint::Paint(const QJsonObject &json)
}
// background
jsonColor(json, "background-color", _backgroundColor);
_backgroundColor = FunctionC(json["background-color"]);
// text
jsonColor(json, "text-color", _textColor);
_textColor = FunctionC(json["text-color"]);
}
QPen Style::Layer::Paint::pen(Type type, int zoom) const
@ -321,31 +278,19 @@ bool Style::Layer::Paint::antialias(Layer::Type type, int zoom) const
}
Style::Layer::Layout::Layout(const QJsonObject &json)
: _textSize(16), _textMaxWidth(10), _textMaxAngle(45), _lineCap(Qt::FlatCap),
_lineJoin(Qt::MiterJoin), _font("Open Sans"), _capitalize(false),
_viewportAlignment(false), _textAnchor(Text::Center)
: _lineCap(Qt::FlatCap), _lineJoin(Qt::MiterJoin), _font("Open Sans"),
_capitalize(false), _viewportAlignment(false)
{
// line
if (json.contains("line-cap") && json["line-cap"].isString()) {
if (json["line-cap"].toString() == "round")
_lineCap = Qt::RoundCap;
else if (json["line-cap"].toString() == "square")
_lineCap = Qt::SquareCap;
}
if (json.contains("line-join") && json["line-join"].isString()) {
if (json["line-join"].toString() == "bevel")
_lineJoin = Qt::BevelJoin;
else if (json["line-join"].toString() == "round")
_lineJoin = Qt::RoundJoin;
}
_lineCap = FunctionS(json["line-cap"], "butt");
_lineJoin = FunctionS(json["line-join"], "miter");
// text
if (json.contains("text-field") && json["text-field"].isString())
_text = Template(json["text-field"].toString());
_text = Template(FunctionS(json["text-field"]));
jsonFloat(json, "text-size", _textSize);
jsonFloat(json, "text-max-width", _textMaxWidth);
jsonFloat(json, "text-max-angle", _textMaxAngle);
_textSize = FunctionF(json["text-size"], 16);
_textMaxWidth = FunctionF(json["text-max-width"], 10);
_textMaxAngle = FunctionF(json["text-max-angle"], 45);
if (json.contains("text-font") && json["text-font"].isArray())
_font = Font::fromJsonArray(json["text-font"].toArray());
if (json.contains("text-transform") && json["text-transform"].isString())
@ -354,23 +299,11 @@ Style::Layer::Layout::Layout(const QJsonObject &json)
&& json["text-rotation-alignment"].isString())
if (json["text-rotation-alignment"].toString() == "viewport")
_viewportAlignment = true;
if (json.contains("text-anchor") && json["text-anchor"].isString()) {
QString anchor(json["text-anchor"].toString());
if (anchor == "center")
_textAnchor = Text::Center;
else if (anchor == "left")
_textAnchor = Text::Left;
else if (anchor == "right")
_textAnchor = Text::Right;
else if (anchor == "top")
_textAnchor = Text::Top;
else if (anchor == "bottom")
_textAnchor = Text::Bottom;
}
_textAnchor = FunctionS(json["text-anchor"]);
// icon
if (json.contains("icon-image") && json["icon-image"].isString())
_icon = Template(json["icon-image"].toString());
_icon = Template(FunctionS(json["icon-image"]));
}
QFont Style::Layer::Layout::font(int zoom) const
@ -381,6 +314,46 @@ QFont Style::Layer::Layout::font(int zoom) const
return font;
}
Text::Anchor Style::Layer::Layout::textAnchor(int zoom) const
{
QString anchor(_textAnchor.value(zoom));
if (anchor == "left")
return Text::Left;
else if (anchor == "right")
return Text::Right;
else if (anchor == "top")
return Text::Top;
else if (anchor == "bottom")
return Text::Bottom;
else
return Text::Center;
}
Qt::PenCapStyle Style::Layer::Layout::lineCap(int zoom) const
{
QString cap(_lineCap.value(zoom));
if (cap == "round")
return Qt::RoundCap;
else if (cap == "square")
return Qt::SquareCap;
else
return Qt::FlatCap;
}
Qt::PenJoinStyle Style::Layer::Layout::lineJoin(int zoom) const
{
QString join(_lineJoin.value(zoom));
if (join == "bevel")
return Qt::BevelJoin;
else if (join == "round")
return Qt::RoundJoin;
else
return Qt::MiterJoin;
}
Style::Layer::Layer(const QJsonObject &json)
: _type(Unknown), _minZoom(-1), _maxZoom(-1)
{
@ -434,8 +407,8 @@ void Style::Layer::setPathPainter(Tile &tile, const Sprites &sprites) const
QPen pen(_paint.pen(_type, tile.zoom()));
QBrush brush(_paint.brush(_type, tile.zoom(), sprites));
pen.setJoinStyle(_layout.lineJoin());
pen.setCapStyle(_layout.lineCap());
pen.setJoinStyle(_layout.lineJoin(tile.zoom()));
pen.setCapStyle(_layout.lineCap(tile.zoom()));
QPainter &p = tile.painter();
p.setRenderHint(QPainter::Antialiasing, _paint.antialias(_type, tile.zoom()));
@ -459,7 +432,7 @@ void Style::Layer::setTextProperties(Tile &tile) const
Text::Properties prop;
prop.maxWidth = _layout.maxTextWidth(tile.zoom());
prop.maxAngle = _layout.maxTextAngle(tile.zoom());
prop.anchor = _layout.textAnchor();
prop.anchor = _layout.textAnchor(tile.zoom());
tile.text().setProperties(prop);
}

View File

@ -96,12 +96,10 @@ private:
class Layout {
public:
Layout() : _textSize(16), _textMaxWidth(10), _textMaxAngle(45),
_lineCap(Qt::FlatCap), _lineJoin(Qt::MiterJoin),
_font("Open Sans"), _capitalize(false), _viewportAlignment(false),
_textAnchor(Text::Center) {}
_font("Open Sans"), _capitalize(false),
_viewportAlignment(false) {}
Layout(const QJsonObject &json);
bool capitalize() const {return _capitalize;}
qreal maxTextWidth(int zoom) const
{return _textMaxWidth.value(zoom);}
qreal maxTextAngle(int zoom) const
@ -111,10 +109,12 @@ private:
QString icon(int zoom, const QVariantHash &tags) const
{return _icon.value(zoom, tags);}
QFont font(int zoom) const;
Qt::PenCapStyle lineCap() const {return _lineCap;}
Qt::PenJoinStyle lineJoin() const {return _lineJoin;}
Qt::PenCapStyle lineCap(int zoom) const;
Qt::PenJoinStyle lineJoin(int zoom) const;
Text::Anchor textAnchor(int zoom) const;
bool viewportAlignment() const {return _viewportAlignment;}
Text::Anchor textAnchor() const {return _textAnchor;}
bool capitalize() const {return _capitalize;}
private:
Template _text;
@ -122,12 +122,12 @@ private:
FunctionF _textSize;
FunctionF _textMaxWidth;
FunctionF _textMaxAngle;
Qt::PenCapStyle _lineCap;
Qt::PenJoinStyle _lineJoin;
FunctionS _lineCap;
FunctionS _lineJoin;
FunctionS _textAnchor;
QFont _font;
bool _capitalize;
bool _viewportAlignment;
Text::Anchor _textAnchor;
};
class Paint {