diff options
author | Ansis Brammanis <brammanis@gmail.com> | 2015-02-05 15:56:46 -0800 |
---|---|---|
committer | Ansis Brammanis <brammanis@gmail.com> | 2015-02-05 16:46:13 -0800 |
commit | 3a8aaad6a799fd4ab1feb47a47a7ffa0d05c1cc0 (patch) | |
tree | fdf3f3c402a870e3e0485b25f0c0bd423487b2fb /src | |
parent | 6e95c3b2e189e91a6244eef58ad1057258b2724b (diff) | |
download | qtlocation-mapboxgl-3a8aaad6a799fd4ab1feb47a47a7ffa0d05c1cc0.tar.gz |
make everything a function
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/style/function_properties.cpp | 20 | ||||
-rw-r--r-- | src/mbgl/style/property_value.hpp | 21 | ||||
-rw-r--r-- | src/mbgl/style/style_parser.cpp | 162 | ||||
-rw-r--r-- | src/mbgl/style/style_parser.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/util/interpolate.hpp | 20 |
5 files changed, 133 insertions, 94 deletions
diff --git a/src/mbgl/style/function_properties.cpp b/src/mbgl/style/function_properties.cpp index 81b1c85c72..2ea3682b8f 100644 --- a/src/mbgl/style/function_properties.cpp +++ b/src/mbgl/style/function_properties.cpp @@ -14,6 +14,16 @@ template <> inline float defaultStopsValue() { return 1.0f; } template <> inline Color defaultStopsValue() { return {{ 0, 0, 0, 1 }}; } template <> inline std::vector<float> defaultStopsValue() { return {{ 1, 0 }}; } +template <> inline std:: string defaultStopsValue() { return {}; } +template <> inline TranslateAnchorType defaultStopsValue() { return {}; }; +template <> inline RotateAnchorType defaultStopsValue() { return {}; }; +template <> inline CapType defaultStopsValue() { return {}; }; +template <> inline JoinType defaultStopsValue() { return {}; }; +template <> inline PlacementType defaultStopsValue() { return {}; }; +template <> inline TextAnchorType defaultStopsValue() { return {}; }; +template <> inline TextJustifyType defaultStopsValue() { return {}; }; +template <> inline TextTransformType defaultStopsValue() { return {}; }; +template <> inline RotationAlignmentType defaultStopsValue() { return {}; }; template <typename T> T StopsFunction<T>::evaluate(float z) const { @@ -67,4 +77,14 @@ template float StopsFunction<float>::evaluate(float z) const; template Color StopsFunction<Color>::evaluate(float z) const; template std::vector<float> StopsFunction<std::vector<float>>::evaluate(float z) const; +template std::string StopsFunction<std::string>::evaluate(float z) const; +template TranslateAnchorType StopsFunction<TranslateAnchorType>::evaluate(float z) const; +template RotateAnchorType StopsFunction<RotateAnchorType>::evaluate(float z) const; +template CapType StopsFunction<CapType>::evaluate(float z) const; +template JoinType StopsFunction<JoinType>::evaluate(float z) const; +template PlacementType StopsFunction<PlacementType>::evaluate(float z) const; +template TextAnchorType StopsFunction<TextAnchorType>::evaluate(float z) const; +template TextJustifyType StopsFunction<TextJustifyType>::evaluate(float z) const; +template TextTransformType StopsFunction<TextTransformType>::evaluate(float z) const; +template RotationAlignmentType StopsFunction<RotationAlignmentType>::evaluate(float z) const; } diff --git a/src/mbgl/style/property_value.hpp b/src/mbgl/style/property_value.hpp index c7fe823025..00f72ea643 100644 --- a/src/mbgl/style/property_value.hpp +++ b/src/mbgl/style/property_value.hpp @@ -11,18 +11,17 @@ namespace mbgl { typedef mapbox::util::variant< - std::string, - TranslateAnchorType, - RotateAnchorType, - bool, - CapType, - JoinType, + Function<std::string>, + Function<TranslateAnchorType>, + Function<RotateAnchorType>, + Function<CapType>, + Function<JoinType>, VisibilityType, - PlacementType, - RotationAlignmentType, - TextTransformType, - TextJustifyType, - TextAnchorType, + Function<PlacementType>, + Function<RotationAlignmentType>, + Function<TextTransformType>, + Function<TextJustifyType>, + Function<TextAnchorType>, Function<bool>, Function<float>, Function<Color>, diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index 4120ef470b..15a9f64aad 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -228,53 +228,40 @@ std::tuple<bool,std::vector<float>> parseFloatArray(JSVal value) { } template <> -bool StyleParser::parseFunctionArgument(JSVal value) { - JSVal rvalue = replaceConstant(value); - if (rvalue.IsBool()) { - return rvalue.GetBool(); - } else if (rvalue.IsNumber()) { - return rvalue.GetDouble(); - } else { - Log::Warning(Event::ParseStyle, "function argument must be a boolean or numeric value"); - return false; - } -} - -template <> -float StyleParser::parseFunctionArgument(JSVal value) { +std::tuple<bool, float> StyleParser::parseProperty(JSVal value, const char*) { JSVal rvalue = replaceConstant(value); if (rvalue.IsNumber()) { - return rvalue.GetDouble(); + return { true, rvalue.GetDouble() }; } else { Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); - return 0.0f; + return { false, 0.0f }; } } template <> -Color StyleParser::parseFunctionArgument(JSVal value) { +std::tuple<bool, Color> StyleParser::parseProperty(JSVal value, const char*) { JSVal rvalue = replaceConstant(value); - return parseColor(rvalue); + return { true, parseColor(rvalue) }; } template <> -Faded<std::vector<float>> StyleParser::parseFunctionArgument(JSVal value) { +std::tuple<bool, Faded<std::vector<float>>> StyleParser::parseProperty(JSVal value, const char*) { Faded<std::vector<float>> parsed; JSVal rvalue = replaceConstant(value); parsed.to = std::get<1>(parseFloatArray(rvalue)); - return parsed; + return { true, parsed }; } template <> -Faded<std::string> StyleParser::parseFunctionArgument(JSVal value) { +std::tuple<bool, Faded<std::string>> StyleParser::parseProperty(JSVal value, const char*) { JSVal rvalue = replaceConstant(value); Faded<std::string> parsed; if (rvalue.IsString()) { parsed.to = { value.GetString(), value.GetStringLength() }; - return parsed; + return { true, parsed }; } else { Log::Warning(Event::ParseStyle, "function argument must be a string"); - return parsed; + return { false, parsed }; } } @@ -302,7 +289,7 @@ std::tuple<bool, std::vector<std::pair<float, T>>> StyleParser::parseStops(JSVal return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}}; } - stops.emplace_back(z.GetDouble(), parseFunctionArgument<T>(stop[rapidjson::SizeType(1)])); + stops.emplace_back(z.GetDouble(), std::get<1>(parseProperty<T>(replaceConstant(stop[rapidjson::SizeType(1)]), ""))); } else { Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); return std::tuple<bool, std::vector<std::pair<float, T>>> { false, {}}; @@ -315,7 +302,12 @@ template <typename T> inline float defaultBaseValue() { return 1.75; } template <> inline float defaultBaseValue<Color>() { return 1.0; } template <typename T> -std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value) { +std::tuple<bool, Function<T>> StyleParser::parseFunction(JSVal value, const char *) { + + if (!value.IsObject()) { + return std::tuple<bool, Function<T>> { true, ConstantFunction<T>(std::get<1>(parseProperty<T>(value, ""))) }; + } + if (!value.HasMember("stops")) { Log::Warning(Event::ParseStyle, "function must specify a function type"); return std::tuple<bool, Function<T>> { false, ConstantFunction<T>(T()) }; @@ -528,41 +520,57 @@ template<> std::tuple<bool, PropertyTransition> StyleParser::parseProperty(JSVal return std::tuple<bool, PropertyTransition> { true, std::move(transition) }; } +template<> std::tuple<bool, Function<std::string>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<std::string>(value, property_name); +} + +template<> std::tuple<bool, Function<TranslateAnchorType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<TranslateAnchorType>(value, property_name); +} + +template<> std::tuple<bool, Function<RotateAnchorType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<RotateAnchorType>(value, property_name); +} + +template<> std::tuple<bool, Function<CapType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<CapType>(value, property_name); +} + +template<> std::tuple<bool, Function<JoinType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<JoinType>(value, property_name); +} + +template<> std::tuple<bool, Function<PlacementType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<PlacementType>(value, property_name); +} + +template<> std::tuple<bool, Function<TextAnchorType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<TextAnchorType>(value, property_name); +} + +template<> std::tuple<bool, Function<TextJustifyType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<TextJustifyType>(value, property_name); +} + +template<> std::tuple<bool, Function<TextTransformType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<TextTransformType>(value, property_name); +} + +template<> std::tuple<bool, Function<RotationAlignmentType>> StyleParser::parseProperty(JSVal value, const char *property_name) { + return parseFunction<RotationAlignmentType>(value, property_name); +} + + template<> std::tuple<bool, Function<bool>> StyleParser::parseProperty(JSVal value, const char *property_name) { - if (value.IsObject()) { - return parseFunction<bool>(value); - } else if (value.IsNumber()) { - return std::tuple<bool, Function<bool>> { true, ConstantFunction<bool>(value.GetDouble()) }; - } else if (value.IsBool()) { - return std::tuple<bool, Function<bool>> { true, ConstantFunction<bool>(value.GetBool()) }; - } else { - Log::Warning(Event::ParseStyle, "value of '%s' must be convertible to boolean, or a boolean function", property_name); - return std::tuple<bool, Function<bool>> { false, ConstantFunction<bool>(false) }; - } + return parseFunction<bool>(value, property_name); } template<> std::tuple<bool, Function<float>> StyleParser::parseProperty(JSVal value, const char *property_name) { - if (value.IsObject()) { - return parseFunction<float>(value); - } else if (value.IsNumber()) { - return std::tuple<bool, Function<float>> { true, ConstantFunction<float>(value.GetDouble()) }; - } else if (value.IsBool()) { - return std::tuple<bool, Function<float>> { true, ConstantFunction<float>(value.GetBool()) }; - } else { - Log::Warning(Event::ParseStyle, "value of '%s' must be a number, or a number function", property_name); - return std::tuple<bool, Function<float>> { false, ConstantFunction<float>(0) }; - } + return parseFunction<float>(value, property_name); } template<> std::tuple<bool, Function<Color>> StyleParser::parseProperty(JSVal value, const char *property_name) { - if (value.IsObject()) { - return parseFunction<Color>(value); - } else if (value.IsString()) { - return std::tuple<bool, Function<Color>> { true, ConstantFunction<Color>(parseColor(value)) }; - } else { - Log::Warning(Event::ParseStyle, "value of '%s' must be a color, or a color function", property_name); - return std::tuple<bool, Function<Color>> { false, ConstantFunction<Color>(Color {{ 0, 0, 0, 0 }}) }; - } + return parseFunction<Color>(value, property_name); } template<> std::tuple<bool, PiecewiseConstantFunction<Faded<std::vector<float>>>> StyleParser::parseProperty(JSVal value, const char *property_name, JSVal transition) { @@ -745,7 +753,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty<PropertyTransition>("fill-outline-color-transition", Key::FillOutlineColor, klass, value); parseOptionalProperty<Function<float>>("fill-translate", { Key::FillTranslateX, Key::FillTranslateY }, klass, value); parseOptionalProperty<PropertyTransition>("fill-translate-transition", Key::FillTranslate, klass, value); - parseOptionalProperty<TranslateAnchorType>("fill-translate-anchor", Key::FillTranslateAnchor, klass, value); + parseOptionalProperty<Function<TranslateAnchorType>>("fill-translate-anchor", Key::FillTranslateAnchor, klass, value); parseOptionalProperty<PiecewiseConstantFunction<Faded<std::string>>>("fill-image", Key::FillImage, klass, value, "fill-image-transition"); parseOptionalProperty<Function<float>>("line-opacity", Key::LineOpacity, klass, value); @@ -754,7 +762,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty<PropertyTransition>("line-color-transition", Key::LineColor, klass, value); parseOptionalProperty<Function<float>>("line-translate", { Key::LineTranslateX, Key::LineTranslateY }, klass, value); parseOptionalProperty<PropertyTransition>("line-translate-transition", Key::LineTranslate, klass, value); - parseOptionalProperty<TranslateAnchorType>("line-translate-anchor", Key::LineTranslateAnchor, klass, value); + parseOptionalProperty<Function<TranslateAnchorType>>("line-translate-anchor", Key::LineTranslateAnchor, klass, value); parseOptionalProperty<Function<float>>("line-width", Key::LineWidth, klass, value); parseOptionalProperty<PropertyTransition>("line-width-transition", Key::LineWidth, klass, value); parseOptionalProperty<Function<float>>("line-gap-width", Key::LineGapWidth, klass, value); @@ -779,7 +787,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty<PropertyTransition>("icon-halo-blur-transition", Key::IconHaloBlur, klass, value); parseOptionalProperty<Function<float>>("icon-translate", { Key::IconTranslateX, Key::IconTranslateY }, klass, value); parseOptionalProperty<PropertyTransition>("icon-translate-transition", Key::IconTranslate, klass, value); - parseOptionalProperty<TranslateAnchorType>("icon-translate-anchor", Key::IconTranslateAnchor, klass, value); + parseOptionalProperty<Function<TranslateAnchorType>>("icon-translate-anchor", Key::IconTranslateAnchor, klass, value); parseOptionalProperty<Function<float>>("text-opacity", Key::TextOpacity, klass, value); parseOptionalProperty<PropertyTransition>("text-opacity-transition", Key::TextOpacity, klass, value); @@ -795,7 +803,7 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty<PropertyTransition>("text-halo-blur-transition", Key::TextHaloBlur, klass, value); parseOptionalProperty<Function<float>>("text-translate", { Key::TextTranslateX, Key::TextTranslateY }, klass, value); parseOptionalProperty<PropertyTransition>("text-translate-transition", Key::TextTranslate, klass, value); - parseOptionalProperty<TranslateAnchorType>("text-translate-anchor", Key::TextTranslateAnchor, klass, value); + parseOptionalProperty<Function<TranslateAnchorType>>("text-translate-anchor", Key::TextTranslateAnchor, klass, value); parseOptionalProperty<Function<float>>("raster-opacity", Key::RasterOpacity, klass, value); parseOptionalProperty<PropertyTransition>("raster-opacity-transition", Key::RasterOpacity, klass, value); @@ -820,42 +828,42 @@ void StyleParser::parseLayout(JSVal value, util::ptr<StyleBucket> &bucket) { parseVisibility<VisibilityType>(*bucket, value); - parseOptionalProperty<CapType>("line-cap", Key::LineCap, bucket->layout, value); - parseOptionalProperty<JoinType>("line-join", Key::LineJoin, bucket->layout, value); + parseOptionalProperty<Function<CapType>>("line-cap", Key::LineCap, bucket->layout, value); + parseOptionalProperty<Function<JoinType>>("line-join", Key::LineJoin, bucket->layout, value); parseOptionalProperty<Function<float>>("line-miter-limit", Key::LineMiterLimit, bucket->layout, value); parseOptionalProperty<Function<float>>("line-round-limit", Key::LineRoundLimit, bucket->layout, value); - parseOptionalProperty<PlacementType>("symbol-placement", Key::SymbolPlacement, bucket->layout, value); + parseOptionalProperty<Function<PlacementType>>("symbol-placement", Key::SymbolPlacement, bucket->layout, value); parseOptionalProperty<Function<float>>("symbol-min-distance", Key::SymbolMinDistance, bucket->layout, value); - parseOptionalProperty<bool>("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value); - parseOptionalProperty<bool>("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value); - parseOptionalProperty<bool>("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value); - parseOptionalProperty<bool>("icon-optional", Key::IconOptional, bucket->layout, value); - parseOptionalProperty<RotationAlignmentType>("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value); + parseOptionalProperty<Function<bool>>("symbol-avoid-edges", Key::SymbolAvoidEdges, bucket->layout, value); + parseOptionalProperty<Function<bool>>("icon-allow-overlap", Key::IconAllowOverlap, bucket->layout, value); + parseOptionalProperty<Function<bool>>("icon-ignore-placement", Key::IconIgnorePlacement, bucket->layout, value); + parseOptionalProperty<Function<bool>>("icon-optional", Key::IconOptional, bucket->layout, value); + parseOptionalProperty<Function<RotationAlignmentType>>("icon-rotation-alignment", Key::IconRotationAlignment, bucket->layout, value); parseOptionalProperty<Function<float>>("icon-max-size", Key::IconMaxSize, bucket->layout, value); - parseOptionalProperty<std::string>("icon-image", Key::IconImage, bucket->layout, value); + parseOptionalProperty<Function<std::string>>("icon-image", Key::IconImage, bucket->layout, value); parseOptionalProperty<Function<float>>("icon-rotate", Key::IconRotate, bucket->layout, value); parseOptionalProperty<Function<float>>("icon-padding", Key::IconPadding, bucket->layout, value); - parseOptionalProperty<bool>("icon-keep-upright", Key::IconKeepUpright, bucket->layout, value); + parseOptionalProperty<Function<bool>>("icon-keep-upright", Key::IconKeepUpright, bucket->layout, value); parseOptionalProperty<Function<float>>("icon-offset", { Key::IconOffsetX, Key::IconOffsetY }, bucket->layout, value); - parseOptionalProperty<RotationAlignmentType>("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value); - parseOptionalProperty<std::string>("text-field", Key::TextField, bucket->layout, value); - parseOptionalProperty<std::string>("text-font", Key::TextFont, bucket->layout, value); + parseOptionalProperty<Function<RotationAlignmentType>>("text-rotation-alignment", Key::TextRotationAlignment, bucket->layout, value); + parseOptionalProperty<Function<std::string>>("text-field", Key::TextField, bucket->layout, value); + parseOptionalProperty<Function<std::string>>("text-font", Key::TextFont, bucket->layout, value); parseOptionalProperty<Function<float>>("text-max-size", Key::TextMaxSize, bucket->layout, value); parseOptionalProperty<Function<float>>("text-max-width", Key::TextMaxWidth, bucket->layout, value); parseOptionalProperty<Function<float>>("text-line-height", Key::TextLineHeight, bucket->layout, value); parseOptionalProperty<Function<float>>("text-letter-spacing", Key::TextLetterSpacing, bucket->layout, value); - parseOptionalProperty<TextJustifyType>("text-justify", Key::TextJustify, bucket->layout, value); - parseOptionalProperty<TextAnchorType>("text-anchor", Key::TextAnchor, bucket->layout, value); + parseOptionalProperty<Function<TextJustifyType>>("text-justify", Key::TextJustify, bucket->layout, value); + parseOptionalProperty<Function<TextAnchorType>>("text-anchor", Key::TextAnchor, bucket->layout, value); parseOptionalProperty<Function<float>>("text-max-angle", Key::TextMaxAngle, bucket->layout, value); parseOptionalProperty<Function<float>>("text-rotate", Key::TextRotate, bucket->layout, value); parseOptionalProperty<Function<float>>("text-padding", Key::TextPadding, bucket->layout, value); - parseOptionalProperty<bool>("text-keep-upright", Key::TextKeepUpright, bucket->layout, value); - parseOptionalProperty<TextTransformType>("text-transform", Key::TextTransform, bucket->layout, value); + parseOptionalProperty<Function<bool>>("text-keep-upright", Key::TextKeepUpright, bucket->layout, value); + parseOptionalProperty<Function<TextTransformType>>("text-transform", Key::TextTransform, bucket->layout, value); parseOptionalProperty<Function<float>>("text-offset", { Key::TextOffsetX, Key::TextOffsetY }, bucket->layout, value); - parseOptionalProperty<bool>("text-allow-overlap", Key::TextAllowOverlap, bucket->layout, value); - parseOptionalProperty<bool>("text-ignore-placement", Key::TextIgnorePlacement, bucket->layout, value); - parseOptionalProperty<bool>("text-optional", Key::TextOptional, bucket->layout, value); + parseOptionalProperty<Function<bool>>("text-allow-overlap", Key::TextAllowOverlap, bucket->layout, value); + parseOptionalProperty<Function<bool>>("text-ignore-placement", Key::TextIgnorePlacement, bucket->layout, value); + parseOptionalProperty<Function<bool>>("text-optional", Key::TextOptional, bucket->layout, value); } diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp index d25c705792..a32e6dd1d3 100644 --- a/src/mbgl/style/style_parser.hpp +++ b/src/mbgl/style/style_parser.hpp @@ -83,12 +83,10 @@ private: std::tuple<bool, T> parseProperty(JSVal value, const char *property_name, JSVal transition); template <typename T> - std::tuple<bool, Function<T>> parseFunction(JSVal value); + std::tuple<bool, Function<T>> parseFunction(JSVal value, const char *); template <typename T> std::tuple<bool, PiecewiseConstantFunction<T>> parsePiecewiseConstantFunction(JSVal value, std::chrono::steady_clock::duration duration); template <typename T> - T parseFunctionArgument(JSVal value); - template <typename T> std::tuple<bool, std::vector<std::pair<float, T>>> parseStops(JSVal value); FilterExpression parseFilter(JSVal); diff --git a/src/mbgl/util/interpolate.hpp b/src/mbgl/util/interpolate.hpp index 952d7b9c10..a2998233b5 100644 --- a/src/mbgl/util/interpolate.hpp +++ b/src/mbgl/util/interpolate.hpp @@ -4,6 +4,8 @@ #include <array> #include <vector> +#include <mbgl/style/types.hpp> + namespace mbgl { namespace util { @@ -22,9 +24,21 @@ inline std::array<T, 4> interpolate(const std::array<T, 4>& a, const std::array< }}; } -inline std::vector<float> interpolate(const std::vector<float> &a, const std::vector<float>, const double) { - return a; -} +// fake interpolations that just return the first value +template<> inline bool interpolate(const bool a, const bool, const double) { return a; } +template<> inline std::vector<float> interpolate(const std::vector<float> a, const std::vector<float>, const double) { return a; } +template<> inline std::string interpolate(const std::string a, const std::string, const double) { return a; } +template<> inline TranslateAnchorType interpolate(const TranslateAnchorType a, const TranslateAnchorType, const double) { return a; } +template<> inline RotateAnchorType interpolate(const RotateAnchorType a, const RotateAnchorType, const double) { return a; } +template<> inline CapType interpolate(const CapType a, const CapType, const double) { return a; } +template<> inline JoinType interpolate(const JoinType a, const JoinType, const double) { return a; } +template<> inline PlacementType interpolate(const PlacementType a, const PlacementType, const double) { return a; } +template<> inline TextAnchorType interpolate(const TextAnchorType a, const TextAnchorType, const double) { return a; } +template<> inline TextJustifyType interpolate(const TextJustifyType a, const TextJustifyType, const double) { return a; } +template<> inline TextTransformType interpolate(const TextTransformType a, const TextTransformType, const double) { return a; } +template<> inline RotationAlignmentType interpolate(const RotationAlignmentType a, const RotationAlignmentType, const double) { return a; } + + } } |