File indexing completed on 2025-01-05 04:01:13

0001 /*
0002  * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003  *
0004  * SPDX-License-Identifier: GPL-3.0-or-later
0005  */
0006 #pragma once
0007 
0008 #include <QDomDocument>
0009 #include <QGradientStops>
0010 
0011 #include "cos.hpp"
0012 #include "ae_project.hpp"
0013 
0014 namespace glaxnimate::io::aep {
0015 
0016 CosArray xml_array(const QDomElement& element);
0017 CosObject xml_map(const QDomElement& element);
0018 CosObject xml_list(const QDomElement& element);
0019 CosValue xml_value(const QDomElement& element);
0020 
0021 inline const CosValue& get_value(const CosObject& v, const QString& key)
0022 {
0023     return v->at(key);
0024 }
0025 
0026 inline const CosValue& get_value(const CosArray& v, int key)
0027 {
0028     return v->at(key);
0029 }
0030 
0031 inline const CosValue& get_value(const CosValue& v, const QString& key)
0032 {
0033     return v.get<CosValue::Index::Object>()->at(key);
0034 }
0035 
0036 inline const CosValue& get_value(const CosValue& v, int key)
0037 {
0038     return v.get<CosValue::Index::Array>()->at(key);
0039 }
0040 
0041 template<class V>
0042 const CosValue& get(const V& v)
0043 {
0044     return v;
0045 }
0046 
0047 template<class V, class H, class... T>
0048 const CosValue& get(const V& v, const H& key, const T&... keys)
0049 {
0050     return get(get_value(v, key), keys...);
0051 }
0052 
0053 template<CosValue::Index Ind, class V, class... T>
0054 const auto& get_as(const V& v, const T&... keys)
0055 {
0056     return get(v, keys...).template get<Ind>();
0057 }
0058 
0059 struct GradientStopAlpha
0060 {
0061     static constexpr const char* const name1 = "Alpha Stops";
0062     static constexpr const char* const name2 = "Stops Alpha";
0063     using Value = double;
0064 
0065     static Value get(const CosArray::element_type* arr)
0066     {
0067         return arr->at(2).get<CosValue::Index::Number>();
0068     }
0069 };
0070 
0071 struct GradientStopColor
0072 {
0073     static constexpr const char* const name1 = "Color Stops";
0074     static constexpr const char* const name2 = "Stops Color";
0075     using Value = QColor;
0076 
0077     static Value get(const CosArray::element_type* arr)
0078     {
0079         return QColor::fromRgbF(
0080             arr->at(2).get<CosValue::Index::Number>(),
0081             arr->at(3).get<CosValue::Index::Number>(),
0082             arr->at(4).get<CosValue::Index::Number>()
0083         );
0084     }
0085 };
0086 
0087 template<class Policy>
0088 GradientStops<typename Policy::Value> get_gradient_stops(const CosValue& data)
0089 {
0090     using Stop = GradientStop<typename Policy::Value>;
0091     GradientStops<typename Policy::Value> stops;
0092 
0093     for ( auto& stop : *get_as<CosValue::Index::Object>(data, Policy::name1, "Stops List") )
0094     {
0095         auto& stop_arr = get(stop.second, Policy::name2);
0096         auto ptr = stop_arr.template get<CosValue::Index::Array>().get();
0097         qreal offset = get_as<CosValue::Index::Number>(stop_arr, 0);
0098         qreal midpoint = get_as<CosValue::Index::Number>(stop_arr, 1);
0099         auto value = Policy::get(ptr);
0100         stops.push_back(Stop{offset, midpoint, value});
0101     }
0102 
0103     std::sort(stops.begin(), stops.end(), [](const Stop& a, const Stop& b) {
0104         return a.offset <= b.offset;
0105     });
0106 
0107     return stops;
0108 }
0109 
0110 Gradient parse_gradient_xml(const CosValue& value);
0111 
0112 Gradient parse_gradient_xml(const QString& xml);
0113 
0114 } // namespace glaxnimate::io::aep