move to std::map for classes
This commit is contained in:
@@ -2,21 +2,35 @@
|
||||
#define LLMR_STYLE_CLASS_DESCRIPTION
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include "properties.hpp"
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class ClassDescription {
|
||||
public:
|
||||
BackgroundClass background;
|
||||
std::map<std::string, FillClass> fill;
|
||||
std::map<std::string, LineClass> line;
|
||||
std::map<std::string, IconClass> icon;
|
||||
std::map<std::string, TextClass> text;
|
||||
std::map<std::string, RasterClass> raster;
|
||||
std::map<std::string, CompositeClass> composite;
|
||||
inline const ClassProperties &operator[](const std::string &name) const {
|
||||
auto it = styles.find(name);
|
||||
if (it != styles.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
return defaultProperties;
|
||||
}
|
||||
}
|
||||
|
||||
void addClass(const std::string &name, ClassProperties &&properties);
|
||||
|
||||
inline std::unordered_map<std::string, ClassProperties>::const_iterator begin() const {
|
||||
return styles.begin();
|
||||
}
|
||||
|
||||
inline std::unordered_map<std::string, ClassProperties>::const_iterator end() const {
|
||||
return styles.end();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, ClassProperties> styles;
|
||||
static const ClassProperties defaultProperties;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <llmr/util/variant.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
@@ -16,7 +19,10 @@ namespace llmr {
|
||||
typedef std::array<float, 4> Color;
|
||||
|
||||
struct PropertyTransition {
|
||||
inline PropertyTransition(uint16_t duration, uint16_t delay = 0) : duration(duration), delay(delay) {}
|
||||
inline PropertyTransition(uint16_t duration, uint16_t delay = 0)
|
||||
: duration(duration), delay(delay) {}
|
||||
inline PropertyTransition(const PropertyTransition &transition)
|
||||
: duration(transition.duration), delay(transition.delay) {}
|
||||
uint16_t duration = 0;
|
||||
uint16_t delay = 0;
|
||||
};
|
||||
@@ -82,21 +88,124 @@ struct FunctionProperty {
|
||||
std::vector<float> values;
|
||||
|
||||
inline FunctionProperty() : function(&functions::null) {}
|
||||
|
||||
inline FunctionProperty(const FunctionProperty &property)
|
||||
: function(property.function), values(property.values) {}
|
||||
inline FunctionProperty(FunctionProperty &&property)
|
||||
: function(property.function), values(std::move(property.values)) {}
|
||||
|
||||
|
||||
inline void operator=(const FunctionProperty &rhs) {
|
||||
function = rhs.function;
|
||||
values = rhs.values;
|
||||
}
|
||||
|
||||
inline FunctionProperty(float value) : function(&functions::constant), values(1, value) {}
|
||||
template <typename T> inline T evaluate(float z) const { return function(z, values); }
|
||||
};
|
||||
|
||||
struct GenericClass {
|
||||
boost::optional<FunctionProperty> enabled;
|
||||
boost::optional<std::array<FunctionProperty, 2>> translate;
|
||||
boost::optional<PropertyTransition> translate_transition;
|
||||
boost::optional<TranslateAnchor> translateAnchor;
|
||||
boost::optional<FunctionProperty> opacity;
|
||||
boost::optional<PropertyTransition> opacity_transition;
|
||||
boost::optional<FunctionProperty> prerender;
|
||||
boost::optional<FunctionProperty> prerenderBuffer;
|
||||
boost::optional<FunctionProperty> prerenderSize;
|
||||
boost::optional<FunctionProperty> prerenderBlur;
|
||||
|
||||
enum class RenderType {
|
||||
Fill,
|
||||
Line,
|
||||
Icon,
|
||||
Text,
|
||||
Raster,
|
||||
Composite,
|
||||
Background
|
||||
};
|
||||
|
||||
enum class ClassPropertyKey {
|
||||
Enabled,
|
||||
TranslateX,
|
||||
TranslateY,
|
||||
TranslateTransition,
|
||||
TranslateAnchor,
|
||||
Opacity,
|
||||
OpacityTransition,
|
||||
Prerender,
|
||||
PrerenderBuffer,
|
||||
PrerenderSize,
|
||||
PrerenderBlur,
|
||||
|
||||
FillWinding,
|
||||
FillAntialias,
|
||||
FillColor,
|
||||
FillColorTransition,
|
||||
FillStrokeColor,
|
||||
FillStrokeColorTransition,
|
||||
FillImage,
|
||||
|
||||
LineWidth,
|
||||
LineWidthTransition,
|
||||
LineOffset,
|
||||
LineOffsetTransition,
|
||||
LineColor,
|
||||
LineColorTransition,
|
||||
LineDashLand,
|
||||
LineDashGap,
|
||||
LineDashTransition,
|
||||
|
||||
IconSize,
|
||||
IconColor,
|
||||
IconColorTransition,
|
||||
IconImage,
|
||||
IconRadius,
|
||||
IconRadiusTransition,
|
||||
IconBlur,
|
||||
IconBlurTransition,
|
||||
|
||||
TextColor,
|
||||
TextColorTransition,
|
||||
TextHaloColor,
|
||||
TextHaloColorTransition,
|
||||
TextHaloRadius,
|
||||
TextHaloRadiusTransition,
|
||||
TextHaloBlur,
|
||||
TextHaloBlurTransition,
|
||||
TextSize,
|
||||
TextRotate,
|
||||
TextAlwaysVisible,
|
||||
|
||||
BackgroundColor,
|
||||
BackgroundColorTransition,
|
||||
};
|
||||
|
||||
typedef util::variant<
|
||||
FunctionProperty,
|
||||
PropertyTransition,
|
||||
TranslateAnchor,
|
||||
Color,
|
||||
Winding,
|
||||
std::string,
|
||||
bool
|
||||
> ClassPropertyValue;
|
||||
|
||||
class ClassProperties {
|
||||
public:
|
||||
inline ClassProperties(RenderType type) : type(type) {}
|
||||
inline ClassProperties(ClassProperties &&properties)
|
||||
: type(properties.type), properties(std::move(properties.properties)) {}
|
||||
|
||||
template <typename T>
|
||||
inline const T *get(ClassPropertyKey key) const {
|
||||
const auto it = properties.find(key);
|
||||
if (it != properties.end() && it->second.is<T>()) {
|
||||
return ::std::addressof(it->second.get<T>());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
inline void emplace(Args&& ...args) {
|
||||
properties.emplace(::std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
const RenderType type;
|
||||
|
||||
private:
|
||||
std::map<ClassPropertyKey, ClassPropertyValue> properties;
|
||||
};
|
||||
|
||||
struct PrerenderProperties {
|
||||
@@ -137,17 +246,6 @@ struct GenericProperties {
|
||||
}
|
||||
};
|
||||
|
||||
struct IconClass : public GenericClass {
|
||||
boost::optional<FunctionProperty> size;
|
||||
boost::optional<Color> color;
|
||||
boost::optional<PropertyTransition> color_transition;
|
||||
boost::optional<std::string> image;
|
||||
boost::optional<FunctionProperty> radius;
|
||||
boost::optional<PropertyTransition> radius_transition;
|
||||
boost::optional<FunctionProperty> blur;
|
||||
boost::optional<PropertyTransition> blur_transition;
|
||||
};
|
||||
|
||||
struct IconProperties : public GenericProperties {
|
||||
inline IconProperties() : GenericProperties() {}
|
||||
float size = 0;
|
||||
@@ -157,17 +255,6 @@ struct IconProperties : public GenericProperties {
|
||||
float blur = 0;
|
||||
};
|
||||
|
||||
struct LineClass : public GenericClass {
|
||||
boost::optional<FunctionProperty> width;
|
||||
boost::optional<PropertyTransition> width_transition;
|
||||
boost::optional<FunctionProperty> offset;
|
||||
boost::optional<PropertyTransition> offset_transition;
|
||||
boost::optional<Color> color;
|
||||
boost::optional<PropertyTransition> color_transition;
|
||||
boost::optional<std::array<FunctionProperty, 2>> dash_array;
|
||||
boost::optional<PropertyTransition> dash_array_transition;
|
||||
};
|
||||
|
||||
struct LineProperties : public GenericProperties {
|
||||
inline LineProperties() : GenericProperties() {}
|
||||
float width = 0;
|
||||
@@ -176,16 +263,6 @@ struct LineProperties : public GenericProperties {
|
||||
std::array<float, 2> dash_array = {{ 1, -1 }};
|
||||
};
|
||||
|
||||
struct FillClass : public GenericClass {
|
||||
boost::optional<Winding> winding;
|
||||
boost::optional<FunctionProperty> antialias;
|
||||
boost::optional<Color> fill_color;
|
||||
boost::optional<PropertyTransition> fill_color_transition;
|
||||
boost::optional<Color> stroke_color;
|
||||
boost::optional<PropertyTransition> stroke_color_transition;
|
||||
boost::optional<std::string> image;
|
||||
};
|
||||
|
||||
struct FillProperties : public GenericProperties {
|
||||
inline FillProperties() : GenericProperties() {}
|
||||
Winding winding = Winding::NonZero;
|
||||
@@ -196,20 +273,6 @@ struct FillProperties : public GenericProperties {
|
||||
std::string image;
|
||||
};
|
||||
|
||||
struct TextClass : public GenericClass {
|
||||
boost::optional<Color> color;
|
||||
boost::optional<PropertyTransition> color_transition;
|
||||
boost::optional<Color> halo;
|
||||
boost::optional<PropertyTransition> halo_transition;
|
||||
boost::optional<FunctionProperty> halo_radius;
|
||||
boost::optional<PropertyTransition> halo_radius_transition;
|
||||
boost::optional<FunctionProperty> halo_blur;
|
||||
boost::optional<PropertyTransition> halo_blur_transition;
|
||||
boost::optional<FunctionProperty> size;
|
||||
boost::optional<FunctionProperty> rotate;
|
||||
boost::optional<FunctionProperty> always_visible;
|
||||
};
|
||||
|
||||
struct TextProperties : public GenericProperties {
|
||||
inline TextProperties() : GenericProperties() {}
|
||||
Color color = {{ 0, 0, 0, 1 }};
|
||||
@@ -221,26 +284,15 @@ struct TextProperties : public GenericProperties {
|
||||
bool always_visible = false;
|
||||
};
|
||||
|
||||
struct BackgroundClass : public GenericClass {
|
||||
boost::optional<Color> color;
|
||||
boost::optional<PropertyTransition> color_transition;
|
||||
};
|
||||
|
||||
struct BackgroundProperties : public GenericProperties {
|
||||
inline BackgroundProperties() : GenericProperties() {}
|
||||
Color color = {{ 1, 1, 1, 1 }};
|
||||
};
|
||||
|
||||
struct RasterClass : public GenericClass {
|
||||
};
|
||||
|
||||
struct RasterProperties : public GenericProperties {
|
||||
inline RasterProperties() : GenericProperties() {}
|
||||
};
|
||||
|
||||
struct CompositeClass : public GenericClass {
|
||||
};
|
||||
|
||||
struct CompositeProperties : public GenericProperties {
|
||||
inline CompositeProperties() : GenericProperties() {}
|
||||
};
|
||||
|
||||
@@ -69,7 +69,14 @@ private:
|
||||
uint64_t transitionDuration(const std::string &layer_name, TransitionablePropertyKey key) const;
|
||||
uint64_t transitionDelay(const std::string &layer_name, TransitionablePropertyKey key) const;
|
||||
|
||||
void cascadeProperties(GenericProperties &properties, const GenericClass& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(GenericProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(FillProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(LineProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(IconProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(TextProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(RasterProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(CompositeProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
void cascadeProperties(BackgroundProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z);
|
||||
|
||||
private:
|
||||
// Last applied settings.
|
||||
|
||||
@@ -30,14 +30,14 @@ private:
|
||||
const std::map<std::string, BucketDescription> &buckets,
|
||||
const std::map<std::string, std::string> &layerBuckets);
|
||||
|
||||
void parseGenericClass(GenericClass &klass, JSVal value);
|
||||
FillClass parseFillClass(JSVal value);
|
||||
LineClass parseLineClass(JSVal value);
|
||||
IconClass parseIconClass(JSVal value);
|
||||
TextClass parseTextClass(JSVal value);
|
||||
BackgroundClass parseBackgroundClass(JSVal value);
|
||||
RasterClass parseRasterClass(JSVal value);
|
||||
CompositeClass parseCompositeClass(JSVal value);
|
||||
void parseGenericClass(ClassProperties &klass, JSVal value);
|
||||
ClassProperties parseFillClass(JSVal value);
|
||||
ClassProperties parseLineClass(JSVal value);
|
||||
ClassProperties parseIconClass(JSVal value);
|
||||
ClassProperties parseTextClass(JSVal value);
|
||||
ClassProperties parseBackgroundClass(JSVal value);
|
||||
ClassProperties parseRasterClass(JSVal value);
|
||||
ClassProperties parseCompositeClass(JSVal value);
|
||||
|
||||
PropertyFilterExpression parseFilterOrExpression(JSVal value);
|
||||
|
||||
@@ -49,7 +49,7 @@ private:
|
||||
Value parseValue(JSVal value);
|
||||
FunctionProperty::fn parseFunctionType(JSVal type);
|
||||
FunctionProperty parseFunction(JSVal value);
|
||||
boost::optional<PropertyTransition> parseTransition(JSVal value, std::string property_name);
|
||||
void parseTransition(ClassProperties &klass, ClassPropertyKey key, JSVal value, std::string property_name);
|
||||
|
||||
private:
|
||||
std::map<std::string, const rapidjson::Value *> constants;
|
||||
|
||||
9
src/style/class_description.cpp
Normal file
9
src/style/class_description.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include <llmr/style/class_description.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
void ClassDescription::addClass(const std::string &name, ClassProperties &&properties) {
|
||||
styles.emplace(name, std::move(properties));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,36 +25,272 @@ void Style::reset() {
|
||||
properties_to_transition.clear();
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(GenericProperties &properties, const GenericClass& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
if (klass.enabled) {
|
||||
properties.enabled = klass.enabled.get().evaluate<bool>(z);
|
||||
void Style::cascadeProperties(GenericProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (const FunctionProperty *enabled = klass.get<FunctionProperty>(Key::Enabled)) {
|
||||
properties.enabled = enabled->evaluate<bool>(z);
|
||||
}
|
||||
|
||||
if (klass.translate) {
|
||||
properties.translate = {{ klass.translate.get()[0].evaluate<float>(z),
|
||||
klass.translate.get()[1].evaluate<float>(z) }};
|
||||
if (const FunctionProperty *translateX = klass.get<FunctionProperty>(Key::TranslateX)) {
|
||||
properties.translate[0] = translateX->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Translate] = class_name;
|
||||
if (klass.translate_transition && klass.translate_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Translate, klass.translate_transition.get());
|
||||
}
|
||||
|
||||
if (const FunctionProperty *translateY = klass.get<FunctionProperty>(Key::TranslateY)) {
|
||||
properties.translate[1] = translateY->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Translate] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *translateTransition = klass.get<PropertyTransition>(Key::TranslateTransition)) {
|
||||
if (translateTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Translate, *translateTransition);
|
||||
}
|
||||
}
|
||||
|
||||
if (klass.translateAnchor) {
|
||||
properties.translateAnchor = klass.translateAnchor.get();
|
||||
if (const TranslateAnchor *translateAnchor = klass.get<TranslateAnchor>(Key::TranslateAnchor)) {
|
||||
properties.translateAnchor = *translateAnchor;
|
||||
}
|
||||
|
||||
if (klass.opacity) {
|
||||
properties.opacity = klass.opacity.get().evaluate<float>(z);
|
||||
if (const FunctionProperty *opacity = klass.get<FunctionProperty>(Key::Opacity)) {
|
||||
properties.opacity = opacity->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Opacity] = class_name;
|
||||
if (klass.opacity_transition && klass.opacity_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Opacity, klass.opacity_transition.get());
|
||||
}
|
||||
|
||||
if (const PropertyTransition *opacityTransition = klass.get<PropertyTransition>(Key::OpacityTransition)) {
|
||||
if (opacityTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Opacity, *opacityTransition);
|
||||
}
|
||||
}
|
||||
|
||||
properties.prerender = klass.prerender;
|
||||
properties.prerenderBuffer = klass.prerenderBuffer;
|
||||
properties.prerenderSize = klass.prerenderSize;
|
||||
properties.prerenderBlur = klass.prerenderBlur;
|
||||
if (const FunctionProperty *prerender = klass.get<FunctionProperty>(Key::Prerender)) {
|
||||
properties.prerender = *prerender;
|
||||
}
|
||||
|
||||
if (const FunctionProperty *prerenderBuffer = klass.get<FunctionProperty>(Key::PrerenderBuffer)) {
|
||||
properties.prerenderBuffer = *prerenderBuffer;
|
||||
}
|
||||
|
||||
if (const FunctionProperty *prerenderSize = klass.get<FunctionProperty>(Key::PrerenderSize)) {
|
||||
properties.prerenderSize = *prerenderSize;
|
||||
}
|
||||
|
||||
if (const FunctionProperty *prerenderBlur = klass.get<FunctionProperty>(Key::PrerenderBlur)) {
|
||||
properties.prerenderBlur = *prerenderBlur;
|
||||
}
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(FillProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
cascadeProperties(reinterpret_cast<GenericProperties &>(properties), klass, layer_name, class_name, z);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (const Winding *winding = klass.get<Winding>(Key::FillWinding)) {
|
||||
properties.winding = *winding;
|
||||
}
|
||||
|
||||
if (const FunctionProperty *antialias = klass.get<FunctionProperty>(Key::FillAntialias)) {
|
||||
properties.antialias = antialias->evaluate<bool>(z);
|
||||
}
|
||||
|
||||
if (const Color *fillColor = klass.get<Color>(Key::FillColor)) {
|
||||
properties.fill_color = *fillColor;
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::FillColor] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *fillColorTransition = klass.get<PropertyTransition>(Key::FillColorTransition)) {
|
||||
if (fillColorTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::FillColor, *fillColorTransition);
|
||||
}
|
||||
}
|
||||
|
||||
if (const Color *fillStrokeColor = klass.get<Color>(Key::FillStrokeColor)) {
|
||||
properties.stroke_color = *fillStrokeColor;
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::StrokeColor] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *fillStrokeColorTransition = klass.get<PropertyTransition>(Key::FillStrokeColorTransition)) {
|
||||
if (fillStrokeColorTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::StrokeColor, *fillStrokeColorTransition);
|
||||
}
|
||||
}
|
||||
|
||||
if (const std::string *image = klass.get<std::string>(Key::FillImage)) {
|
||||
properties.image = *image;
|
||||
}
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(LineProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
cascadeProperties(reinterpret_cast<GenericProperties &>(properties), klass, layer_name, class_name, z);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (const FunctionProperty *width = klass.get<FunctionProperty>(Key::LineWidth)) {
|
||||
properties.width = width->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Width] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *width_transition = klass.get<PropertyTransition>(Key::LineWidthTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Width, *width_transition);
|
||||
}
|
||||
|
||||
if (const FunctionProperty *offset = klass.get<FunctionProperty>(Key::LineOffset)) {
|
||||
properties.offset = offset->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Offset] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *offset_transition = klass.get<PropertyTransition>(Key::LineOffsetTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Offset, *offset_transition);
|
||||
}
|
||||
|
||||
if (const Color *color = klass.get<Color>(Key::LineColor)) {
|
||||
properties.color = *color;
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Color] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *color_transition = klass.get<PropertyTransition>(Key::LineColorTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Color, *color_transition);
|
||||
}
|
||||
|
||||
if (const FunctionProperty *dash_array = klass.get<FunctionProperty>(Key::LineDashLand)) {
|
||||
properties.dash_array[0] = dash_array->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::DashArray] = class_name;
|
||||
}
|
||||
|
||||
if (const FunctionProperty *dash_array = klass.get<FunctionProperty>(Key::LineDashGap)) {
|
||||
properties.dash_array[1] = dash_array->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::DashArray] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *dash_array_transition = klass.get<PropertyTransition>(Key::LineDashTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::DashArray, *dash_array_transition);
|
||||
}
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(TextProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
cascadeProperties(reinterpret_cast<GenericProperties &>(properties), klass, layer_name, class_name, z);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (const Color *color = klass.get<Color>(Key::TextColor)) {
|
||||
properties.color = *color;
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Color] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *colorTransition = klass.get<PropertyTransition>(Key::TextColorTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Color, *colorTransition);
|
||||
}
|
||||
|
||||
if (const FunctionProperty *size = klass.get<FunctionProperty>(Key::TextSize)) {
|
||||
properties.size = size->evaluate<float>(z);
|
||||
}
|
||||
|
||||
if (const Color *haloColor = klass.get<Color>(Key::TextHaloColor)) {
|
||||
properties.halo = *haloColor;
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Halo] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *haloColorTransition = klass.get<PropertyTransition>(Key::TextHaloColorTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Halo, *haloColorTransition);
|
||||
}
|
||||
|
||||
if (const FunctionProperty *haloRadius = klass.get<FunctionProperty>(Key::TextHaloRadius)) {
|
||||
properties.halo_radius = haloRadius->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::HaloRadius] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *haloRadiusTransition = klass.get<PropertyTransition>(Key::TextHaloRadiusTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::HaloRadius, *haloRadiusTransition);
|
||||
}
|
||||
|
||||
if (const FunctionProperty *haloBlur = klass.get<FunctionProperty>(Key::TextHaloBlur)) {
|
||||
properties.halo_blur = haloBlur->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::HaloBlur] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *haloBlurTransition = klass.get<PropertyTransition>(Key::TextHaloBlurTransition)) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::HaloBlur, *haloBlurTransition);
|
||||
}
|
||||
|
||||
if (const FunctionProperty *rotate = klass.get<FunctionProperty>(Key::TextRotate)) {
|
||||
properties.rotate = rotate->evaluate<float>(z);
|
||||
}
|
||||
|
||||
if (const FunctionProperty *alwaysVisible = klass.get<FunctionProperty>(Key::TextAlwaysVisible)) {
|
||||
properties.always_visible = alwaysVisible->evaluate<bool>(z);
|
||||
}
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(IconProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
cascadeProperties(reinterpret_cast<GenericProperties &>(properties), klass, layer_name, class_name, z);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (const Color *color = klass.get<Color>(Key::IconColor)) {
|
||||
properties.color = *color;
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Color] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *colorTransition = klass.get<PropertyTransition>(Key::IconColorTransition)) {
|
||||
if (colorTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Color, *colorTransition);
|
||||
}
|
||||
}
|
||||
|
||||
if (const FunctionProperty *size = klass.get<FunctionProperty>(Key::IconSize)) {
|
||||
properties.size = size->evaluate<float>(z);
|
||||
}
|
||||
|
||||
if (const std::string *image = klass.get<std::string>(Key::IconImage)) {
|
||||
properties.image = *image;
|
||||
}
|
||||
|
||||
if (const FunctionProperty *radius = klass.get<FunctionProperty>(Key::IconRadius)) {
|
||||
properties.radius = radius->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Radius] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *radiusTransition = klass.get<PropertyTransition>(Key::IconRadiusTransition)) {
|
||||
if (radiusTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Radius, *radiusTransition);
|
||||
}
|
||||
}
|
||||
|
||||
if (const FunctionProperty *blur = klass.get<FunctionProperty>(Key::IconBlur)) {
|
||||
properties.blur = blur->evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Blur] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *blurTransition = klass.get<PropertyTransition>(Key::IconBlurTransition)) {
|
||||
if (blurTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Blur, *blurTransition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(RasterProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
cascadeProperties(reinterpret_cast<GenericProperties &>(properties), klass, layer_name, class_name, z);
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(CompositeProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
cascadeProperties(reinterpret_cast<GenericProperties &>(properties), klass, layer_name, class_name, z);
|
||||
}
|
||||
|
||||
void Style::cascadeProperties(BackgroundProperties &properties, const ClassProperties& klass, const std::string& layer_name, const std::string& class_name, float z) {
|
||||
cascadeProperties(reinterpret_cast<GenericProperties &>(properties), klass, layer_name, class_name, z);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (const Color *backgroundColor = klass.get<Color>(Key::BackgroundColor)) {
|
||||
properties.color = *backgroundColor;
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Color] = class_name;
|
||||
}
|
||||
|
||||
if (const PropertyTransition *colorTransition = klass.get<PropertyTransition>(Key::TextColorTransition)) {
|
||||
if (colorTransition->duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Color, *colorTransition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,217 +321,38 @@ void Style::cascade(float z) {
|
||||
const std::string& class_name = class_pair.first;
|
||||
const ClassDescription& sheetClass = class_pair.second;
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
// Skip if not enabled.
|
||||
if (appliedClasses.find(class_name) == appliedClasses.end()) continue;
|
||||
|
||||
// Cascade fill classes.
|
||||
for (const auto& fill_pair : sheetClass.fill) {
|
||||
const std::string& layer_name = fill_pair.first;
|
||||
const llmr::FillClass& layer = fill_pair.second;
|
||||
for (const auto &pair : sheetClass) {
|
||||
const std::string& layer_name = pair.first;
|
||||
const ClassProperties& properties = pair.second;
|
||||
|
||||
llmr::FillProperties& fill = computed.fills[layer_name];
|
||||
|
||||
cascadeProperties(fill, layer, layer_name, class_name, z);
|
||||
|
||||
if (layer.winding) {
|
||||
fill.winding = layer.winding.get();
|
||||
}
|
||||
|
||||
if (layer.antialias) {
|
||||
fill.antialias = layer.antialias.get().evaluate<bool>(z);
|
||||
}
|
||||
|
||||
if (layer.fill_color) {
|
||||
fill.fill_color = layer.fill_color.get();
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::FillColor] = class_name;
|
||||
if (layer.fill_color_transition && layer.fill_color_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::FillColor, layer.fill_color_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.stroke_color) {
|
||||
fill.stroke_color = layer.stroke_color.get();
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::StrokeColor] = class_name;
|
||||
if (layer.stroke_color_transition && layer.stroke_color_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::StrokeColor, layer.stroke_color_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.image) {
|
||||
fill.image = layer.image.get();
|
||||
}
|
||||
}
|
||||
|
||||
// Cascade line classes.
|
||||
for (const auto& line_pair : sheetClass.line) {
|
||||
const std::string& layer_name = line_pair.first;
|
||||
const llmr::LineClass& layer = line_pair.second;
|
||||
|
||||
llmr::LineProperties& stroke = computed.lines[layer_name];
|
||||
|
||||
cascadeProperties(stroke, layer, layer_name, class_name, z);
|
||||
|
||||
if (layer.width) {
|
||||
stroke.width = layer.width.get().evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Width] = class_name;
|
||||
if (layer.width_transition && layer.width_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Width, layer.width_transition.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (layer.offset) {
|
||||
stroke.offset = layer.offset.get().evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Offset] = class_name;
|
||||
if (layer.offset_transition && layer.offset_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Offset, layer.offset_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.color) {
|
||||
stroke.color = layer.color.get();
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Color] = class_name;
|
||||
if (layer.color_transition && layer.color_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Color, layer.color_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.dash_array) {
|
||||
stroke.dash_array = {{ layer.dash_array.get()[0].evaluate<float>(z),
|
||||
layer.dash_array.get()[1].evaluate<float>(z) }};
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::DashArray] = class_name;
|
||||
if (layer.dash_array_transition && layer.dash_array_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::DashArray, layer.dash_array_transition.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cascade icon classes.
|
||||
for (const auto& icon_pair : sheetClass.icon) {
|
||||
const std::string& layer_name = icon_pair.first;
|
||||
const llmr::IconClass& layer = icon_pair.second;
|
||||
|
||||
llmr::IconProperties& icon = computed.icons[layer_name];
|
||||
|
||||
cascadeProperties(icon, layer, layer_name, class_name, z);
|
||||
|
||||
if (layer.color) {
|
||||
icon.color = layer.color.get();
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Color] = class_name;
|
||||
if (layer.color_transition && layer.color_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Color, layer.color_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.size) {
|
||||
icon.size = layer.size.get().evaluate<float>(z);
|
||||
}
|
||||
|
||||
if (layer.image) {
|
||||
icon.image = layer.image.get();
|
||||
}
|
||||
|
||||
if (layer.radius) {
|
||||
icon.radius = layer.radius.get().evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Radius] = class_name;
|
||||
if (layer.radius_transition && layer.radius_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Radius, layer.radius_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.blur) {
|
||||
icon.blur = layer.blur.get().evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Blur] = class_name;
|
||||
if (layer.blur_transition && layer.blur_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Blur, layer.blur_transition.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cascade text classes.
|
||||
for (const auto& text_pair : sheetClass.text) {
|
||||
const std::string& layer_name = text_pair.first;
|
||||
const llmr::TextClass& layer = text_pair.second;
|
||||
|
||||
llmr::TextProperties& text = computed.texts[layer_name];
|
||||
|
||||
cascadeProperties(text, layer, layer_name, class_name, z);
|
||||
|
||||
if (layer.color) {
|
||||
text.color = layer.color.get();
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Color] = class_name;
|
||||
if (layer.color_transition && layer.color_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Color, layer.color_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.size) {
|
||||
text.size = layer.size.get().evaluate<float>(z);
|
||||
}
|
||||
|
||||
if (layer.halo) {
|
||||
text.halo = layer.halo.get();
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::Halo] = class_name;
|
||||
if (layer.halo_transition && layer.halo_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::Halo, layer.halo_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.halo_radius) {
|
||||
text.halo_radius = layer.halo_radius.get().evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::HaloRadius] = class_name;
|
||||
if (layer.halo_radius_transition && layer.halo_radius_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::HaloRadius, layer.halo_radius_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.halo_blur) {
|
||||
text.halo_blur = layer.halo_blur.get().evaluate<float>(z);
|
||||
computed.effective_classes[layer_name][TransitionablePropertyKey::HaloBlur] = class_name;
|
||||
if (layer.halo_blur_transition && layer.halo_blur_transition.get().duration) {
|
||||
properties_to_transition[layer_name].emplace(TransitionablePropertyKey::HaloBlur, layer.halo_blur_transition.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer.rotate) {
|
||||
text.rotate = layer.rotate.get().evaluate<float>(z);
|
||||
}
|
||||
|
||||
if (layer.always_visible) {
|
||||
text.always_visible = layer.always_visible.get().evaluate<bool>(z);
|
||||
}
|
||||
}
|
||||
|
||||
// Cascade raster classes.
|
||||
for (const auto& raster_pair : sheetClass.raster) {
|
||||
const std::string& layer_name = raster_pair.first;
|
||||
const llmr::RasterClass& layer = raster_pair.second;
|
||||
|
||||
llmr::RasterProperties& raster = computed.rasters[layer_name];
|
||||
|
||||
cascadeProperties(raster, layer, layer_name, class_name, z);
|
||||
}
|
||||
|
||||
// Cascade composite classes.
|
||||
for (const auto& composite_pair : sheetClass.composite) {
|
||||
const std::string& layer_name = composite_pair.first;
|
||||
const llmr::CompositeClass& layer = composite_pair.second;
|
||||
|
||||
llmr::CompositeProperties& composite = computed.composites[layer_name];
|
||||
|
||||
cascadeProperties(composite, layer, layer_name, class_name, z);
|
||||
}
|
||||
|
||||
// Cascade background.
|
||||
{
|
||||
cascadeProperties(computed.background, sheetClass.background, "background", class_name, z);
|
||||
|
||||
if (sheetClass.background.color) {
|
||||
computed.background.color = sheetClass.background.color.get();
|
||||
computed.effective_classes["background"][TransitionablePropertyKey::Color] = class_name;
|
||||
if (sheetClass.background.color_transition && sheetClass.background.color_transition.get().duration) {
|
||||
properties_to_transition["background"].emplace(TransitionablePropertyKey::Color, sheetClass.background.color_transition.get());
|
||||
}
|
||||
// Find out what bucket this class is
|
||||
switch (properties.type) {
|
||||
case RenderType::Fill:
|
||||
cascadeProperties(computed.fills[layer_name], properties, layer_name, class_name, z);
|
||||
break;
|
||||
case RenderType::Line:
|
||||
cascadeProperties(computed.lines[layer_name], properties, layer_name, class_name, z);
|
||||
break;
|
||||
case RenderType::Icon:
|
||||
cascadeProperties(computed.icons[layer_name], properties, layer_name, class_name, z);
|
||||
break;
|
||||
case RenderType::Text:
|
||||
cascadeProperties(computed.texts[layer_name], properties, layer_name, class_name, z);
|
||||
break;
|
||||
case RenderType::Raster:
|
||||
cascadeProperties(computed.rasters[layer_name], properties, layer_name, class_name, z);
|
||||
break;
|
||||
case RenderType::Composite:
|
||||
cascadeProperties(computed.composites[layer_name], properties, layer_name, class_name, z);
|
||||
break;
|
||||
case RenderType::Background:
|
||||
cascadeProperties(computed.background, properties, layer_name, class_name, z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <llmr/style/style_parser.hpp>
|
||||
#include <llmr/style/properties.hpp>
|
||||
#include <llmr/util/constants.hpp>
|
||||
#include <csscolorparser/csscolorparser.hpp>
|
||||
|
||||
@@ -482,10 +483,10 @@ void StyleParser::parseClass(const std::string &name, JSVal value, ClassDescript
|
||||
const std::string &bucket_name = layer_bucket_it->second;
|
||||
if (bucket_name == "background") {
|
||||
// background buckets are fake
|
||||
class_desc.background = parseBackgroundClass(value);
|
||||
class_desc.addClass("background", parseBackgroundClass(value));
|
||||
} else if (bucket_name.length() == 0) {
|
||||
// no bucket name == composite bucket.
|
||||
class_desc.composite.insert({ name, std::forward<CompositeClass>(parseCompositeClass(value)) });
|
||||
class_desc.addClass(name, parseCompositeClass(value));
|
||||
} else {
|
||||
auto bucket_it = buckets.find(bucket_name);
|
||||
if (bucket_it == buckets.end()) {
|
||||
@@ -497,15 +498,15 @@ void StyleParser::parseClass(const std::string &name, JSVal value, ClassDescript
|
||||
|
||||
BucketType type = bucket_it->second.type;
|
||||
if (type == BucketType::Fill) {
|
||||
class_desc.fill.insert({ name, std::forward<FillClass>(parseFillClass(value)) });
|
||||
class_desc.addClass(name, parseFillClass(value));
|
||||
} else if (type == BucketType::Line) {
|
||||
class_desc.line.insert({ name, std::forward<LineClass>(parseLineClass(value)) });
|
||||
class_desc.addClass(name, parseLineClass(value));
|
||||
} else if (type == BucketType::Icon) {
|
||||
class_desc.icon.insert({ name, std::forward<IconClass>(parseIconClass(value)) });
|
||||
class_desc.addClass(name, parseIconClass(value));
|
||||
} else if (type == BucketType::Text) {
|
||||
class_desc.text.insert({ name, std::forward<TextClass>(parseTextClass(value)) });
|
||||
class_desc.addClass(name, parseTextClass(value));
|
||||
} else if (type == BucketType::Raster) {
|
||||
class_desc.raster.insert({ name, std::forward<RasterClass>(parseRasterClass(value)) });
|
||||
class_desc.addClass(name, parseRasterClass(value));
|
||||
} else {
|
||||
throw Style::exception("unknown class type name");
|
||||
}
|
||||
@@ -663,7 +664,7 @@ FunctionProperty StyleParser::parseFunction(JSVal value) {
|
||||
return property;
|
||||
}
|
||||
|
||||
boost::optional<PropertyTransition> StyleParser::parseTransition(JSVal value, std::string property_name) {
|
||||
void StyleParser::parseTransition(ClassProperties &klass, ClassPropertyKey key, JSVal value, std::string property_name) {
|
||||
uint16_t duration = 0, delay = 0;
|
||||
std::string transition_property = std::string("transition-").append(property_name);
|
||||
if (value.HasMember(transition_property.c_str())) {
|
||||
@@ -679,200 +680,212 @@ boost::optional<PropertyTransition> StyleParser::parseTransition(JSVal value, st
|
||||
}
|
||||
|
||||
if (duration || delay) {
|
||||
return boost::optional<PropertyTransition>(PropertyTransition { duration, delay });
|
||||
} else {
|
||||
return boost::optional<PropertyTransition>();
|
||||
klass.emplace(key, PropertyTransition { duration, delay });
|
||||
}
|
||||
}
|
||||
|
||||
void StyleParser::parseGenericClass(GenericClass &klass, JSVal value) {
|
||||
if (value.HasMember("enabled")) {
|
||||
klass.enabled = parseFunction(value["enabled"]);
|
||||
void StyleParser::parseGenericClass(ClassProperties &klass, JSVal value) {
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (value.HasMember("enabled")) {
|
||||
klass.emplace(Key::Enabled, parseFunction(value["enabled"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("translate")) {
|
||||
std::vector<FunctionProperty> values = parseArray(value["translate"], 2);
|
||||
klass.translate = std::array<FunctionProperty, 2> {{ values[0], values[1] }};
|
||||
klass.translate_transition = parseTransition(value, "translate");
|
||||
klass.emplace(Key::TranslateX, std::move(values[0]));
|
||||
klass.emplace(Key::TranslateY, std::move(values[1]));
|
||||
parseTransition(klass, Key::TranslateTransition, value, "translate");
|
||||
}
|
||||
|
||||
if (value.HasMember("translate-anchor")) {
|
||||
klass.translateAnchor = parseTranslateAnchor(value["translate-anchor"]);
|
||||
klass.emplace(Key::TranslateAnchor, parseTranslateAnchor(value["translate-anchor"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("opacity")) {
|
||||
klass.opacity = parseFunction(value["opacity"]);
|
||||
klass.opacity_transition = parseTransition(value, "opacity");
|
||||
klass.emplace(Key::Opacity, parseFunction(value["opacity"]));
|
||||
parseTransition(klass, Key::OpacityTransition, value, "opacity");
|
||||
}
|
||||
|
||||
if (value.HasMember("prerender")) {
|
||||
klass.prerender = parseFunction(value["prerender"]);
|
||||
klass.emplace(Key::Prerender, parseFunction(value["prerender"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("prerender-buffer")) {
|
||||
klass.prerenderBuffer = parseFunction(value["prerender-buffer"]);
|
||||
klass.emplace(Key::PrerenderBuffer, parseFunction(value["prerender-buffer"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("prerender-size")) {
|
||||
klass.prerenderSize = parseFunction(value["prerender-size"]);
|
||||
klass.emplace(Key::PrerenderSize, parseFunction(value["prerender-size"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("prerender-blur")) {
|
||||
klass.prerenderBlur = parseFunction(value["prerender-blur"]);
|
||||
klass.emplace(Key::PrerenderBlur, parseFunction(value["prerender-blur"]));
|
||||
}
|
||||
}
|
||||
|
||||
FillClass StyleParser::parseFillClass(JSVal value) {
|
||||
FillClass klass;
|
||||
ClassProperties StyleParser::parseFillClass(JSVal value) {
|
||||
ClassProperties klass(RenderType::Fill);
|
||||
|
||||
parseGenericClass(klass, value);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (value.HasMember("winding")) {
|
||||
throw std::runtime_error("winding in stylesheets not yet supported");
|
||||
}
|
||||
|
||||
if (value.HasMember("color")) {
|
||||
klass.fill_color = parseColor(value["color"]);
|
||||
klass.fill_color_transition = parseTransition(value, "color");
|
||||
klass.emplace(Key::FillColor, parseColor(value["color"]));
|
||||
parseTransition(klass, Key::FillColorTransition, value, "color");
|
||||
}
|
||||
|
||||
if (value.HasMember("stroke")) {
|
||||
klass.stroke_color = parseColor(value["stroke"]);
|
||||
klass.stroke_color_transition = parseTransition(value, "stroke");
|
||||
} else {
|
||||
klass.stroke_color = klass.fill_color;
|
||||
klass.emplace(Key::FillStrokeColor, parseColor(value["stroke"]));
|
||||
parseTransition(klass, Key::FillStrokeColorTransition, value, "stroke");
|
||||
} else if (const Color *fillColor = klass.get<Color>(Key::FillColor)) {
|
||||
klass.emplace(Key::FillStrokeColor, *fillColor);
|
||||
}
|
||||
|
||||
if (value.HasMember("antialias")) {
|
||||
klass.antialias = parseBoolean(value["antialias"]);
|
||||
klass.emplace(Key::FillAntialias, parseBoolean(value["antialias"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("image")) {
|
||||
klass.image = parseString(value["image"]);
|
||||
klass.emplace(Key::FillImage, parseString(value["image"]));
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
LineClass StyleParser::parseLineClass(JSVal value) {
|
||||
LineClass klass;
|
||||
ClassProperties StyleParser::parseLineClass(JSVal value) {
|
||||
ClassProperties klass(RenderType::Line);
|
||||
|
||||
parseGenericClass(klass, value);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (value.HasMember("color")) {
|
||||
klass.color = parseColor(value["color"]);
|
||||
klass.color_transition = parseTransition(value, "color");
|
||||
klass.emplace(Key::LineColor, parseColor(value["color"]));
|
||||
parseTransition(klass, Key::LineColorTransition, value, "color");
|
||||
}
|
||||
|
||||
if (value.HasMember("width")) {
|
||||
klass.width = parseFunction(value["width"]);
|
||||
klass.width_transition = parseTransition(value, "width");
|
||||
klass.emplace(Key::LineWidth, parseFunction(value["width"]));
|
||||
parseTransition(klass, Key::LineWidthTransition, value, "width");
|
||||
}
|
||||
|
||||
if (value.HasMember("dasharray")) {
|
||||
std::vector<FunctionProperty> values = parseArray(value["dasharray"], 2);
|
||||
klass.dash_array = std::array<FunctionProperty, 2> {{ values[0], values[1] }};
|
||||
klass.dash_array_transition = parseTransition(value, "dasharray");
|
||||
klass.emplace(Key::LineDashLand, std::move(values[0]));
|
||||
klass.emplace(Key::LineDashGap, std::move(values[1]));
|
||||
parseTransition(klass, Key::LineDashTransition, value, "dasharray");
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
IconClass StyleParser::parseIconClass(JSVal value) {
|
||||
IconClass klass;
|
||||
ClassProperties StyleParser::parseIconClass(JSVal value) {
|
||||
ClassProperties klass(RenderType::Icon);
|
||||
|
||||
parseGenericClass(klass, value);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (value.HasMember("color")) {
|
||||
klass.color = parseColor(value["color"]);
|
||||
klass.color_transition = parseTransition(value, "color");
|
||||
klass.emplace(Key::IconColor, parseColor(value["color"]));
|
||||
parseTransition(klass, Key::IconColorTransition, value, "color");
|
||||
}
|
||||
|
||||
if (value.HasMember("image")) {
|
||||
klass.image = parseString(value["image"]);
|
||||
klass.emplace(Key::IconImage, parseString(value["image"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("size")) {
|
||||
klass.size = parseFunction(value["size"]);
|
||||
klass.emplace(Key::IconSize, parseFunction(value["size"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("radius")) {
|
||||
klass.radius = parseFunction(value["radius"]);
|
||||
klass.radius_transition = parseTransition(value, "radius");
|
||||
klass.emplace(Key::IconRadius, parseFunction(value["radius"]));
|
||||
parseTransition(klass, Key::IconRadiusTransition, value, "radius");
|
||||
}
|
||||
|
||||
if (value.HasMember("blur")) {
|
||||
klass.blur = parseFunction(value["blur"]);
|
||||
klass.blur_transition = parseTransition(value, "blur");
|
||||
klass.emplace(Key::IconBlur, parseFunction(value["blur"]));
|
||||
parseTransition(klass, Key::IconBlurTransition, value, "blur");
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
TextClass StyleParser::parseTextClass(JSVal value) {
|
||||
TextClass klass;
|
||||
ClassProperties StyleParser::parseTextClass(JSVal value) {
|
||||
ClassProperties klass(RenderType::Text);
|
||||
|
||||
parseGenericClass(klass, value);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (value.HasMember("color")) {
|
||||
klass.color = parseColor(value["color"]);
|
||||
klass.color_transition = parseTransition(value, "color");
|
||||
klass.emplace(Key::TextColor, parseColor(value["color"]));
|
||||
parseTransition(klass, Key::TextColorTransition, value, "color");
|
||||
}
|
||||
|
||||
if (value.HasMember("stroke")) {
|
||||
klass.halo = parseColor(value["stroke"]);
|
||||
klass.halo_transition = parseTransition(value, "stroke");
|
||||
klass.emplace(Key::TextHaloColor, parseColor(value["stroke"]));
|
||||
parseTransition(klass, Key::TextHaloColorTransition, value, "stroke");
|
||||
}
|
||||
|
||||
if (value.HasMember("strokeWidth")) {
|
||||
klass.halo_radius = parseFunction(value["strokeWidth"]);
|
||||
klass.halo_radius_transition = parseTransition(value, "strokeWidth");
|
||||
klass.emplace(Key::TextHaloRadius, parseFunction(value["strokeWidth"]));
|
||||
parseTransition(klass, Key::TextHaloRadiusTransition, value, "strokeWidth");
|
||||
}
|
||||
|
||||
if (value.HasMember("strokeBlur")) {
|
||||
klass.halo_blur = parseFunction(value["strokeBlur"]);
|
||||
klass.halo_blur_transition = parseTransition(value, "strokeBlur");
|
||||
klass.emplace(Key::TextHaloBlur, parseFunction(value["strokeBlur"]));
|
||||
parseTransition(klass, Key::TextHaloBlurTransition, value, "strokeBlur");
|
||||
}
|
||||
|
||||
if (value.HasMember("size")) {
|
||||
klass.size = parseFunction(value["size"]);
|
||||
klass.emplace(Key::TextSize, parseFunction(value["size"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("rotate")) {
|
||||
klass.rotate = parseFunction(value["rotate"]);
|
||||
klass.emplace(Key::TextRotate, parseFunction(value["rotate"]));
|
||||
}
|
||||
|
||||
if (value.HasMember("alwaysVisible")) {
|
||||
klass.always_visible = parseFunction(value["alwaysVisible"]);
|
||||
klass.emplace(Key::TextAlwaysVisible, parseFunction(value["alwaysVisible"]));
|
||||
}
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
RasterClass StyleParser::parseRasterClass(JSVal value) {
|
||||
RasterClass klass;
|
||||
ClassProperties StyleParser::parseRasterClass(JSVal value) {
|
||||
ClassProperties klass(RenderType::Raster);
|
||||
|
||||
parseGenericClass(klass, value);
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
CompositeClass StyleParser::parseCompositeClass(JSVal value) {
|
||||
CompositeClass klass;
|
||||
ClassProperties StyleParser::parseCompositeClass(JSVal value) {
|
||||
ClassProperties klass(RenderType::Composite);
|
||||
|
||||
parseGenericClass(klass, value);
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
BackgroundClass StyleParser::parseBackgroundClass(JSVal value) {
|
||||
BackgroundClass klass;
|
||||
ClassProperties StyleParser::parseBackgroundClass(JSVal value) {
|
||||
ClassProperties klass(RenderType::Background);
|
||||
|
||||
parseGenericClass(klass, value);
|
||||
|
||||
using Key = ClassPropertyKey;
|
||||
|
||||
if (value.HasMember("color")) {
|
||||
klass.color = parseColor(value["color"]);
|
||||
klass.color_transition = parseTransition(value, "color");
|
||||
klass.emplace(Key::BackgroundColor, parseColor(value["color"]));
|
||||
parseTransition(klass, Key::BackgroundColorTransition, value, "color");
|
||||
}
|
||||
|
||||
return klass;
|
||||
|
||||
Reference in New Issue
Block a user