parse rasterize values as well
This commit is contained in:
@@ -11,7 +11,7 @@ class Painter;
|
||||
|
||||
class PrerenderedTexture : private util::noncopyable {
|
||||
public:
|
||||
PrerenderedTexture(const PrerenderProperties &properties);
|
||||
PrerenderedTexture(const RasterizedProperties &properties);
|
||||
~PrerenderedTexture();
|
||||
|
||||
void bindTexture();
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
void blur(Painter& painter, uint16_t passes);
|
||||
|
||||
public:
|
||||
const PrerenderProperties properties;
|
||||
const RasterizedProperties properties;
|
||||
|
||||
private:
|
||||
GLint previous_fbo = 0;
|
||||
|
||||
@@ -15,13 +15,12 @@ public:
|
||||
inline ClassProperties(ClassProperties &&properties)
|
||||
: properties(std::move(properties.properties)) {}
|
||||
|
||||
template <typename ...Args>
|
||||
inline void set(Args&& ...args) {
|
||||
properties.emplace(::std::forward<Args>(args)...);
|
||||
inline void set(PropertyKey key, const PropertyValue &value) {
|
||||
properties.emplace(key, value);
|
||||
}
|
||||
template <typename ...Args>
|
||||
inline void setTransition(Args&& ...args) {
|
||||
transitions.emplace(::std::forward<Args>(args)...);
|
||||
|
||||
inline void set(PropertyKey key, const PropertyTransition &transition) {
|
||||
transitions.emplace(key, transition);
|
||||
}
|
||||
|
||||
const PropertyTransition &getTransition(PropertyKey key, const PropertyTransition &defaultTransition) const;
|
||||
|
||||
@@ -50,6 +50,7 @@ private:
|
||||
|
||||
template <typename T>
|
||||
using Function = util::variant<
|
||||
std::false_type,
|
||||
ConstantFunction<T>,
|
||||
LinearFunction<T>,
|
||||
ExponentialFunction<T>,
|
||||
@@ -61,6 +62,10 @@ struct FunctionEvaluator {
|
||||
typedef T result_type;
|
||||
inline FunctionEvaluator(float z) : z(z) {}
|
||||
|
||||
inline result_type operator()(const std::false_type &) {
|
||||
return result_type();
|
||||
}
|
||||
|
||||
template <template <typename> class Fn>
|
||||
inline result_type operator()(const Fn<T>& fn) {
|
||||
return fn.evaluate(z);
|
||||
|
||||
@@ -3,22 +3,23 @@
|
||||
|
||||
#include <llmr/style/function_properties.hpp>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
struct PrerenderProperties {
|
||||
float buffer = 1.0f / 32.0f;
|
||||
uint16_t size = 256;
|
||||
uint16_t blur = 0;
|
||||
};
|
||||
|
||||
class RasterizeProperties {
|
||||
public:
|
||||
boost::optional<Function<bool>> enabled;
|
||||
boost::optional<Function<float>> buffer;
|
||||
boost::optional<Function<float>> size;
|
||||
boost::optional<Function<float>> blur;
|
||||
Function<bool> enabled = ConstantFunction<bool>(false);
|
||||
Function<float> buffer = ConstantFunction<float>(1.0f / 32.0f);
|
||||
Function<float> size = ConstantFunction<float>(256);
|
||||
Function<float> blur = ConstantFunction<float>(0);
|
||||
};
|
||||
|
||||
// The calculated properties for a layer in a tile.
|
||||
class RasterizedProperties {
|
||||
public:
|
||||
bool enabled = false;
|
||||
float buffer = 1.0f / 32.0f;
|
||||
uint16_t size = 256;
|
||||
uint8_t blur = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <forward_list>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
@@ -50,7 +50,7 @@ private:
|
||||
void parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair);
|
||||
void parseStyles(JSVal value, std::map<ClassID, ClassProperties> &styles);
|
||||
void parseStyle(JSVal, ClassProperties &properties);
|
||||
std::unique_ptr<const RasterizeProperties> parseRasterize(JSVal value);
|
||||
std::unique_ptr<RasterizeProperties> parseRasterize(JSVal value);
|
||||
void parseReference(JSVal value, std::shared_ptr<StyleLayer> &layer);
|
||||
void parseBucket(JSVal value, std::shared_ptr<StyleLayer> &layer);
|
||||
void parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer);
|
||||
@@ -67,11 +67,17 @@ private:
|
||||
template <typename T>
|
||||
bool parseStyleProperty(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value);
|
||||
template <typename T>
|
||||
bool parseStyleProperty(const char *property_name, T &target, JSVal value);
|
||||
template <typename T>
|
||||
std::tuple<bool, T> parseStyleProperty(JSVal value, const char *property_name);
|
||||
template <typename T>
|
||||
bool parseStyleProperty(const char *property_name, const std::vector<PropertyKey> &keys, ClassProperties &klass, JSVal value);
|
||||
|
||||
template <typename T>
|
||||
bool parseFunction(PropertyKey key, ClassProperties &klass, JSVal value);
|
||||
template <typename T>
|
||||
std::tuple<bool, Function<T>> parseFunction(JSVal value);
|
||||
template <typename T>
|
||||
T parseFunctionArgument(JSVal value);
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
PrerenderedTexture::PrerenderedTexture(const PrerenderProperties &properties)
|
||||
PrerenderedTexture::PrerenderedTexture(const RasterizedProperties &properties)
|
||||
: properties(properties) {
|
||||
}
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ Color StyleParser::parseFunctionArgument(JSVal value) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool StyleParser::parseFunction(PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) {
|
||||
if (!value.HasMember("fn")) {
|
||||
fprintf(stderr, "[WARNING] function must specify a function name\n");
|
||||
return false;
|
||||
@@ -254,8 +254,7 @@ bool StyleParser::parseFunction(PropertyKey key, ClassProperties &klass, JSVal v
|
||||
const float slope = value.HasMember("slope") ? parseFunctionArgument<float>(value["slope"]) : 1;
|
||||
const T min = value.HasMember("min") ? parseFunctionArgument<T>(value["min"]) : T();
|
||||
const T max = value.HasMember("max") ? parseFunctionArgument<T>(value["max"]) : T();
|
||||
klass.set(key, LinearFunction<T>(val, z_base, slope, min, max));
|
||||
return true;
|
||||
return { true, LinearFunction<T>(val, z_base, slope, min, max) };
|
||||
}
|
||||
else if (type == "exponential") {
|
||||
if (!value.HasMember("z")) {
|
||||
@@ -271,9 +270,7 @@ bool StyleParser::parseFunction(PropertyKey key, ClassProperties &klass, JSVal v
|
||||
const float slope = value.HasMember("slope") ? parseFunctionArgument<float>(value["slope"]) : 1;
|
||||
const T min = value.HasMember("min") ? parseFunctionArgument<T>(value["min"]) : T();
|
||||
const T max = value.HasMember("max") ? parseFunctionArgument<T>(value["max"]) : T();
|
||||
klass.set(key, ExponentialFunction<T>(val, z_base, slope, min, max));
|
||||
return true;
|
||||
|
||||
return { true, ExponentialFunction<T>(val, z_base, slope, min, max) };
|
||||
}
|
||||
else if (type == "stops") {
|
||||
if (!value.HasMember("stops")) {
|
||||
@@ -313,8 +310,7 @@ bool StyleParser::parseFunction(PropertyKey key, ClassProperties &klass, JSVal v
|
||||
}
|
||||
}
|
||||
|
||||
klass.set(key, StopsFunction<T>(stops));
|
||||
return true;
|
||||
return { true, StopsFunction<T>(stops) };
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "[WARNING] function type '%s' is unknown\n", type.c_str());
|
||||
@@ -323,107 +319,136 @@ bool StyleParser::parseFunction(PropertyKey key, ClassProperties &klass, JSVal v
|
||||
return false;
|
||||
}
|
||||
|
||||
template<> bool StyleParser::parseStyleProperty<std::string>(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (!rvalue.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
return false;
|
||||
template <typename T>
|
||||
bool StyleParser::parseFunction(PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
bool parsed;
|
||||
Function<T> function;
|
||||
std::tie(parsed, function) = parseFunction<T>(value);
|
||||
if (parsed) {
|
||||
klass.set(key, function);
|
||||
}
|
||||
|
||||
klass.set(key, std::string { rvalue.GetString(), rvalue.GetStringLength() });
|
||||
return true;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
template<> bool StyleParser::parseStyleProperty<TranslateAnchorType>(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (!rvalue.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
return false;
|
||||
template<typename T>
|
||||
bool StyleParser::parseStyleProperty(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
bool parsed = false;
|
||||
T result;
|
||||
std::tie(parsed, result) = parseStyleProperty<T>(value, property_name);
|
||||
if (parsed) {
|
||||
klass.set(key, result);
|
||||
}
|
||||
|
||||
klass.set(key, parseTranslateAnchorType({ rvalue.GetString(), rvalue.GetStringLength() }));
|
||||
return true;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
template<> bool StyleParser::parseStyleProperty<RotateAnchorType>(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
template <typename T>
|
||||
bool StyleParser::parseStyleProperty(const char *property_name, T &target, JSVal value) {
|
||||
bool parsed = false;
|
||||
T result;
|
||||
std::tie(parsed, result) = parseStyleProperty<T>(value, property_name);
|
||||
if (parsed) {
|
||||
target = std::move(result);
|
||||
}
|
||||
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (!rvalue.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
klass.set(key, parseRotateAnchorType({ rvalue.GetString(), rvalue.GetStringLength() }));
|
||||
return true;
|
||||
return parsed;
|
||||
}
|
||||
|
||||
template <> bool StyleParser::parseStyleProperty<PropertyTransition>(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
|
||||
template<> std::tuple<bool, std::string> StyleParser::parseStyleProperty(JSVal value, const char *property_name) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
}
|
||||
JSVal elements = replaceConstant(value[property_name]);
|
||||
PropertyTransition transition;
|
||||
|
||||
if (elements.IsObject()) {
|
||||
if (elements.HasMember("duration") && elements["duration"].IsNumber()) {
|
||||
transition.duration = elements["duration"].GetUint();
|
||||
} else {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (!rvalue.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
return false;
|
||||
}
|
||||
if (elements.HasMember("delay") && elements["delay"].IsNumber()) {
|
||||
transition.delay = elements["delay"].GetUint();
|
||||
}
|
||||
}
|
||||
|
||||
if (transition.duration == 0 && transition.delay == 0) {
|
||||
return false;
|
||||
return { true, std::string { rvalue.GetString(), rvalue.GetStringLength() } };
|
||||
}
|
||||
|
||||
klass.setTransition(key, std::move(transition));
|
||||
return true;
|
||||
}
|
||||
|
||||
template<> bool StyleParser::parseStyleProperty<Function<bool>>(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
template<> std::tuple<bool, TranslateAnchorType> StyleParser::parseStyleProperty(JSVal value, const char *property_name) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
} else {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (!rvalue.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return { true, parseTranslateAnchorType({ rvalue.GetString(), rvalue.GetStringLength() }) };
|
||||
}
|
||||
}
|
||||
|
||||
template<> std::tuple<bool, RotateAnchorType> StyleParser::parseStyleProperty<RotateAnchorType>(JSVal value, const char *property_name) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
} else {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (!rvalue.IsString()) {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a string\n", property_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return { true, parseRotateAnchorType({ rvalue.GetString(), rvalue.GetStringLength() }) };
|
||||
}
|
||||
}
|
||||
|
||||
template<> std::tuple<bool, PropertyTransition> StyleParser::parseStyleProperty(JSVal value, const char *property_name) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
} else {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
PropertyTransition transition;
|
||||
if (rvalue.IsObject()) {
|
||||
if (rvalue.HasMember("duration") && rvalue["duration"].IsNumber()) {
|
||||
transition.duration = rvalue["duration"].GetUint();
|
||||
}
|
||||
if (rvalue.HasMember("delay") && rvalue["delay"].IsNumber()) {
|
||||
transition.delay = rvalue["delay"].GetUint();
|
||||
}
|
||||
}
|
||||
|
||||
if (transition.duration == 0 && transition.delay == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return { true, std::move(transition) };
|
||||
}
|
||||
}
|
||||
|
||||
template<> std::tuple<bool, Function<bool>> StyleParser::parseStyleProperty(JSVal value, const char *property_name) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
} else {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (rvalue.IsObject()) {
|
||||
return parseFunction<bool>(key, klass, rvalue);
|
||||
return parseFunction<bool>(rvalue);
|
||||
} else if (rvalue.IsNumber()) {
|
||||
klass.set(key, bool(rvalue.GetDouble()));
|
||||
return true;
|
||||
return { true, ConstantFunction<bool>(rvalue.GetDouble()) };
|
||||
} else if (rvalue.IsBool()) {
|
||||
klass.set(key, bool(rvalue.GetBool()));
|
||||
return true;
|
||||
return { true, ConstantFunction<bool>(rvalue.GetBool()) };
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a boolean, or a boolean function\n", property_name);
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be convertible to boolean, or a boolean function\n", property_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<> bool StyleParser::parseStyleProperty<Function<float>>(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
template<> std::tuple<bool, Function<float>> StyleParser::parseStyleProperty(JSVal value, const char *property_name) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
} else {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (rvalue.IsObject()) {
|
||||
return parseFunction<float>(key, klass, rvalue);
|
||||
return parseFunction<float>(rvalue);
|
||||
} else if (rvalue.IsNumber()) {
|
||||
klass.set(key, float(rvalue.GetDouble()));
|
||||
return true;
|
||||
return { true, ConstantFunction<float>(rvalue.GetDouble()) };
|
||||
} else if (rvalue.IsBool()) {
|
||||
klass.set(key, float(rvalue.GetBool()));
|
||||
return { true, ConstantFunction<float>(rvalue.GetBool()) };
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a number, or a number function\n", property_name);
|
||||
@@ -432,16 +457,15 @@ template<> bool StyleParser::parseStyleProperty<Function<float>>(const char *pro
|
||||
}
|
||||
}
|
||||
|
||||
template<> bool StyleParser::parseStyleProperty<Function<Color>>(const char *property_name, PropertyKey key, ClassProperties &klass, JSVal value) {
|
||||
template<> std::tuple<bool, Function<Color>> StyleParser::parseStyleProperty(JSVal value, const char *property_name) {
|
||||
if (!value.HasMember(property_name)) {
|
||||
return false;
|
||||
} else {
|
||||
JSVal rvalue = replaceConstant(value[property_name]);
|
||||
if (rvalue.IsObject()) {
|
||||
return parseFunction<Color>(key, klass, rvalue);
|
||||
return parseFunction<Color>(rvalue);
|
||||
} else if (rvalue.IsString()) {
|
||||
klass.set(key, parseColor(rvalue));
|
||||
return true;
|
||||
return { true, ConstantFunction<Color>(parseColor(rvalue)) };
|
||||
} else {
|
||||
fprintf(stderr, "[WARNING] value of '%s' must be a color, or a color function\n", property_name);
|
||||
return false;
|
||||
@@ -663,9 +687,17 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) {
|
||||
parseStyleProperty<Function<Color>>("background-color", Key::BackgroundColor, klass, value);
|
||||
}
|
||||
|
||||
std::unique_ptr<const RasterizeProperties> StyleParser::parseRasterize(JSVal value) {
|
||||
// TODO
|
||||
return nullptr;
|
||||
std::unique_ptr<RasterizeProperties> StyleParser::parseRasterize(JSVal value) {
|
||||
auto rasterize = std::make_unique<RasterizeProperties>();
|
||||
|
||||
if (value.IsObject()) {
|
||||
parseStyleProperty("enabled", rasterize->enabled, value);
|
||||
parseStyleProperty("buffer", rasterize->buffer, value);
|
||||
parseStyleProperty("size", rasterize->size, value);
|
||||
parseStyleProperty("blur", rasterize->blur, value);
|
||||
}
|
||||
|
||||
return rasterize;
|
||||
}
|
||||
|
||||
void StyleParser::parseReference(JSVal value, std::shared_ptr<StyleLayer> &layer) {
|
||||
|
||||
Reference in New Issue
Block a user