mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Squashed 'external/lunasvg/' changes from f924651b8..87137e791
87137e791 Release v2.3.6 a03316bbd Refactoring 906d326b2 Revert "Merge pull request #84 from seanharmer/master" git-subtree-dir: external/lunasvg git-subtree-split: 87137e791c912432b93982722a8e965628950ca7
This commit is contained in:
parent
2c16a78282
commit
9a2c8e1077
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
.vscode
|
||||
build/*
|
|
@ -1,15 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
|
||||
project(lunasvg VERSION 2.3.5 LANGUAGES CXX C)
|
||||
project(lunasvg VERSION 2.3.8 LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
# Default to hidden visibility for symbols
|
||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Builds as shared library" OFF)
|
||||
option(LUNASVG_BUILD_EXAMPLES "Builds examples" OFF)
|
||||
|
||||
|
@ -19,61 +14,25 @@ add_subdirectory(include)
|
|||
add_subdirectory(source)
|
||||
add_subdirectory(3rdparty/plutovg)
|
||||
|
||||
set_target_properties(lunasvg
|
||||
PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
)
|
||||
|
||||
add_library(lunasvg::lunasvg ALIAS lunasvg)
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(lunasvg PUBLIC LUNASVG_STATIC_DEFINE)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(lunasvg PUBLIC LUNASVG_SHARED)
|
||||
target_compile_definitions(lunasvg PRIVATE LUNASVG_EXPORT)
|
||||
endif()
|
||||
|
||||
if(LUNASVG_BUILD_EXAMPLES)
|
||||
add_subdirectory(example)
|
||||
endif()
|
||||
|
||||
#
|
||||
# Installation
|
||||
#
|
||||
include(GNUInstallDirs)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/lunasvg.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/lunasvg_export.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/lunasvg
|
||||
)
|
||||
install(
|
||||
TARGETS lunasvg
|
||||
EXPORT lunasvg-targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
install(
|
||||
EXPORT lunasvg-targets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lunasvg NAMESPACE lunasvg:: FILE lunasvgTargets.cmake
|
||||
)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/lunasvgConfig.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lunasvgConfig.cmake
|
||||
INSTALL_DESTINATION
|
||||
${CMAKE_INSTALL_LIBDIR}/cmake/lunasvg
|
||||
)
|
||||
|
||||
write_basic_package_version_file(lunasvgConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
set(LUNASVG_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib)
|
||||
set(LUNASVG_INCDIR ${CMAKE_INSTALL_PREFIX}/include)
|
||||
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lunasvgConfig.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lunasvgConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lunasvg
|
||||
include/lunasvg.h
|
||||
DESTINATION ${LUNASVG_INCDIR}
|
||||
)
|
||||
|
||||
export(EXPORT lunasvg-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/lunasvgTargets.cmake NAMESPACE lunasvg::)
|
||||
install(TARGETS lunasvg
|
||||
LIBRARY DESTINATION ${LUNASVG_LIBDIR}
|
||||
ARCHIVE DESTINATION ${LUNASVG_LIBDIR}
|
||||
INCLUDES DESTINATION ${LUNASVG_INCDIR}
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![Releases](https://img.shields.io/badge/Version-2.3.5-orange.svg)](https://github.com/sammycage/lunasvg/releases)
|
||||
[![Releases](https://img.shields.io/badge/Version-2.3.8-orange.svg)](https://github.com/sammycage/lunasvg/releases)
|
||||
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/sammycage/lunasvg/blob/master/LICENSE)
|
||||
[![Build Status](https://github.com/sammycage/lunasvg/actions/workflows/ci.yml/badge.svg)](https://github.com/sammycage/lunasvg/actions)
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/lunasvgTargets.cmake")
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.13)
|
||||
cmake_minimum_required(VERSION 3.3)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
|
|
|
@ -1,16 +1,4 @@
|
|||
# Generate a standard header with export macros
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(lunasvg)
|
||||
|
||||
target_include_directories(lunasvg
|
||||
# When building a project that uses the lunasvg library,
|
||||
# we need to look in the installed include directory
|
||||
PUBLIC
|
||||
$<INSTALL_INTERFACE:include>
|
||||
|
||||
# When building the lunasvg library we need to look in the
|
||||
# build dir for the lunasvg_export.h header and in the source
|
||||
# dir for other headers
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
)
|
||||
|
|
|
@ -27,16 +27,22 @@
|
|||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
#include <lunasvg_export.h>
|
||||
#define LUNASVG_API LUNASVG_EXPORT
|
||||
#if defined(_MSC_VER) && defined(LUNASVG_SHARED)
|
||||
#ifdef LUNASVG_EXPORT
|
||||
#define LUNASVG_API __declspec(dllexport)
|
||||
#else
|
||||
#define LUNASVG_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define LUNASVG_API
|
||||
#endif
|
||||
|
||||
namespace lunasvg {
|
||||
|
||||
class Rect;
|
||||
class Matrix;
|
||||
|
||||
class LUNASVG_API Box
|
||||
{
|
||||
class LUNASVG_API Box {
|
||||
public:
|
||||
Box() = default;
|
||||
Box(double x, double y, double w, double h);
|
||||
|
@ -54,8 +60,7 @@ public:
|
|||
|
||||
class Transform;
|
||||
|
||||
class LUNASVG_API Matrix
|
||||
{
|
||||
class LUNASVG_API Matrix {
|
||||
public:
|
||||
Matrix() = default;
|
||||
Matrix(double a, double b, double c, double d, double e, double f);
|
||||
|
@ -92,8 +97,7 @@ public:
|
|||
double f{0};
|
||||
};
|
||||
|
||||
class LUNASVG_API Bitmap
|
||||
{
|
||||
class LUNASVG_API Bitmap {
|
||||
public:
|
||||
/**
|
||||
* @note Bitmap format is ARGB Premultiplied.
|
||||
|
@ -123,8 +127,7 @@ private:
|
|||
|
||||
class LayoutSymbol;
|
||||
|
||||
class LUNASVG_API Document
|
||||
{
|
||||
class LUNASVG_API Document {
|
||||
public:
|
||||
/**
|
||||
* @brief Creates a document from a file
|
||||
|
@ -202,6 +205,7 @@ public:
|
|||
Bitmap renderToBitmap(std::uint32_t width = 0, std::uint32_t height = 0, std::uint32_t backgroundColor = 0x00000000) const;
|
||||
|
||||
~Document();
|
||||
|
||||
private:
|
||||
Document();
|
||||
|
||||
|
|
|
@ -149,11 +149,9 @@ void Canvas::luminance()
|
|||
auto height = plutovg_surface_get_height(surface);
|
||||
auto stride = plutovg_surface_get_stride(surface);
|
||||
auto data = plutovg_surface_get_data(surface);
|
||||
for(int y = 0;y < height;y++)
|
||||
{
|
||||
for(int y = 0; y < height; y++) {
|
||||
auto pixels = reinterpret_cast<uint32_t*>(data + stride * y);
|
||||
for(int x = 0;x < width;x++)
|
||||
{
|
||||
for(int x = 0; x < width; x++) {
|
||||
auto pixel = pixels[x];
|
||||
auto r = (pixel >> 16) & 0xFF;
|
||||
auto g = (pixel >> 8) & 0xFF;
|
||||
|
@ -229,8 +227,7 @@ static plutovg_texture_type_t to_plutovg_texture_type(TextureType type)
|
|||
|
||||
static void to_plutovg_stops(plutovg_gradient_t* gradient, const GradientStops& stops)
|
||||
{
|
||||
for(const auto& stop : stops)
|
||||
{
|
||||
for(const auto& stop : stops) {
|
||||
auto offset = std::get<0>(stop);
|
||||
auto& color = std::get<1>(stop);
|
||||
plutovg_gradient_add_stop_rgba(gradient, offset, color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0, color.alpha() / 255.0);
|
||||
|
@ -241,8 +238,7 @@ void to_plutovg_path(plutovg_t* pluto, const Path& path)
|
|||
{
|
||||
PathIterator it(path);
|
||||
std::array<Point, 3> p;
|
||||
while(!it.isDone())
|
||||
{
|
||||
while(!it.isDone()) {
|
||||
switch(it.currentSegment(p)) {
|
||||
case PathCommand::MoveTo:
|
||||
plutovg_move_to(pluto, p[0].x, p[0].y);
|
||||
|
|
|
@ -13,20 +13,17 @@ using GradientStops = std::vector<GradientStop>;
|
|||
|
||||
using DashArray = std::vector<double>;
|
||||
|
||||
struct DashData
|
||||
{
|
||||
struct DashData {
|
||||
DashArray array;
|
||||
double offset{0.0};
|
||||
};
|
||||
|
||||
enum class TextureType
|
||||
{
|
||||
enum class TextureType {
|
||||
Plain,
|
||||
Tiled
|
||||
};
|
||||
|
||||
enum class BlendMode
|
||||
{
|
||||
enum class BlendMode {
|
||||
Src,
|
||||
Src_Over,
|
||||
Dst_In,
|
||||
|
@ -35,8 +32,7 @@ enum class BlendMode
|
|||
|
||||
class CanvasImpl;
|
||||
|
||||
class Canvas
|
||||
{
|
||||
class Canvas {
|
||||
public:
|
||||
static std::shared_ptr<Canvas> create(unsigned char* data, unsigned int width, unsigned int height, unsigned int stride);
|
||||
static std::shared_ptr<Canvas> create(double x, double y, double width, double height);
|
||||
|
@ -61,6 +57,7 @@ public:
|
|||
Rect box() const;
|
||||
|
||||
~Canvas();
|
||||
|
||||
private:
|
||||
Canvas(unsigned char* data, int width, int height, int stride);
|
||||
Canvas(int x, int y, int width, int height);
|
||||
|
|
|
@ -7,8 +7,7 @@ namespace lunasvg {
|
|||
|
||||
class LayoutClipPath;
|
||||
|
||||
class ClipPathElement : public GraphicsElement
|
||||
{
|
||||
class ClipPathElement : public GraphicsElement {
|
||||
public:
|
||||
ClipPathElement();
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
class DefsElement : public GraphicsElement
|
||||
{
|
||||
class DefsElement : public GraphicsElement {
|
||||
public:
|
||||
DefsElement();
|
||||
|
||||
|
|
|
@ -1,53 +1,8 @@
|
|||
#include "element.h"
|
||||
#include "parser.h"
|
||||
#include "svgelement.h"
|
||||
|
||||
namespace lunasvg {
|
||||
|
||||
void PropertyList::set(PropertyID id, const std::string& value, int specificity)
|
||||
{
|
||||
auto property = get(id);
|
||||
if(property == nullptr)
|
||||
{
|
||||
Property property{id, value, specificity};
|
||||
m_properties.push_back(std::move(property));
|
||||
return;
|
||||
}
|
||||
|
||||
if(property->specificity > specificity)
|
||||
return;
|
||||
|
||||
property->specificity = specificity;
|
||||
property->value = value;
|
||||
}
|
||||
|
||||
Property* PropertyList::get(PropertyID id) const
|
||||
{
|
||||
auto data = m_properties.data();
|
||||
auto end = data + m_properties.size();
|
||||
while(data < end)
|
||||
{
|
||||
if(data->id == id)
|
||||
return const_cast<Property*>(data);
|
||||
++data;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PropertyList::add(const Property& property)
|
||||
{
|
||||
set(property.id, property.value, property.specificity);
|
||||
}
|
||||
|
||||
void PropertyList::add(const PropertyList& properties)
|
||||
{
|
||||
auto it = properties.m_properties.begin();
|
||||
auto end = properties.m_properties.end();
|
||||
for(;it != end;++it)
|
||||
add(*it);
|
||||
}
|
||||
|
||||
void Node::layout(LayoutContext*, LayoutContainer*) const
|
||||
{
|
||||
}
|
||||
|
@ -66,18 +21,32 @@ Element::Element(ElementID id)
|
|||
|
||||
void Element::set(PropertyID id, const std::string& value, int specificity)
|
||||
{
|
||||
properties.set(id, value, specificity);
|
||||
for(auto& property : properties) {
|
||||
if(property.id == id) {
|
||||
if(specificity >= property.specificity) {
|
||||
property.specificity = specificity;
|
||||
property.value = value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Property property{specificity, id, value};
|
||||
properties.push_back(std::move(property));
|
||||
}
|
||||
|
||||
static const std::string EmptyString;
|
||||
|
||||
const std::string& Element::get(PropertyID id) const
|
||||
{
|
||||
auto property = properties.get(id);
|
||||
if(property == nullptr)
|
||||
return EmptyString;
|
||||
for(auto& property : properties) {
|
||||
if(property.id == id) {
|
||||
return property.value;
|
||||
}
|
||||
}
|
||||
|
||||
return property->value;
|
||||
return EmptyString;
|
||||
}
|
||||
|
||||
static const std::string InheritString{"inherit"};
|
||||
|
@ -97,7 +66,13 @@ const std::string& Element::find(PropertyID id) const
|
|||
|
||||
bool Element::has(PropertyID id) const
|
||||
{
|
||||
return properties.get(id);
|
||||
for(auto& property : properties) {
|
||||
if(property.id == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Element* Element::previousElement() const
|
||||
|
@ -108,12 +83,10 @@ Element* Element::previousElement() const
|
|||
Element* element = nullptr;
|
||||
auto it = parent->children.begin();
|
||||
auto end = parent->children.end();
|
||||
for(;it != end;++it)
|
||||
{
|
||||
for(; it != end; ++it) {
|
||||
auto node = it->get();
|
||||
if(node->isText())
|
||||
continue;
|
||||
|
||||
if(node == this)
|
||||
return element;
|
||||
element = static_cast<Element*>(node);
|
||||
|
@ -130,8 +103,7 @@ Element* Element::nextElement() const
|
|||
Element* element = nullptr;
|
||||
auto it = parent->children.rbegin();
|
||||
auto end = parent->children.rend();
|
||||
for(;it != end;++it)
|
||||
{
|
||||
for(; it != end; ++it) {
|
||||
auto node = it->get();
|
||||
if(node->isText())
|
||||
continue;
|
||||
|
@ -153,22 +125,21 @@ Node* Element::addChild(std::unique_ptr<Node> child)
|
|||
|
||||
void Element::layoutChildren(LayoutContext* context, LayoutContainer* current) const
|
||||
{
|
||||
for(auto& child : children)
|
||||
for(auto& child : children) {
|
||||
child->layout(context, current);
|
||||
}
|
||||
}
|
||||
|
||||
Rect Element::currentViewport() const
|
||||
{
|
||||
if(parent == nullptr)
|
||||
{
|
||||
if(parent == nullptr) {
|
||||
auto element = static_cast<const SVGElement*>(this);
|
||||
if(element->has(PropertyID::ViewBox))
|
||||
return element->viewBox();
|
||||
return Rect{0, 0, 300, 150};
|
||||
}
|
||||
|
||||
if(parent->id == ElementID::Svg)
|
||||
{
|
||||
if(parent->id == ElementID::Svg) {
|
||||
auto element = static_cast<SVGElement*>(parent);
|
||||
if(element->has(PropertyID::ViewBox))
|
||||
return element->viewBox();
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
enum class ElementID
|
||||
{
|
||||
enum class ElementID {
|
||||
Unknown = 0,
|
||||
Star,
|
||||
Circle,
|
||||
|
@ -35,8 +34,7 @@ enum class ElementID
|
|||
Use
|
||||
};
|
||||
|
||||
enum class PropertyID
|
||||
{
|
||||
enum class PropertyID {
|
||||
Unknown = 0,
|
||||
Class,
|
||||
Clip_Path,
|
||||
|
@ -106,34 +104,19 @@ enum class PropertyID
|
|||
Y2
|
||||
};
|
||||
|
||||
struct Property
|
||||
{
|
||||
struct Property {
|
||||
int specificity;
|
||||
PropertyID id;
|
||||
std::string value;
|
||||
int specificity;
|
||||
};
|
||||
|
||||
class PropertyList
|
||||
{
|
||||
public:
|
||||
PropertyList() = default;
|
||||
|
||||
void set(PropertyID id, const std::string& value, int specificity);
|
||||
Property* get(PropertyID id) const;
|
||||
void add(const Property& property);
|
||||
void add(const PropertyList& properties);
|
||||
void clear() { m_properties.clear(); }
|
||||
|
||||
private:
|
||||
std::vector<Property> m_properties;
|
||||
};
|
||||
using PropertyList = std::vector<Property>;
|
||||
|
||||
class LayoutContext;
|
||||
class LayoutContainer;
|
||||
class Element;
|
||||
|
||||
class Node
|
||||
{
|
||||
class Node {
|
||||
public:
|
||||
Node() = default;
|
||||
virtual ~Node() = default;
|
||||
|
@ -148,8 +131,7 @@ public:
|
|||
Element* parent = nullptr;
|
||||
};
|
||||
|
||||
class TextNode : public Node
|
||||
{
|
||||
class TextNode : public Node {
|
||||
public:
|
||||
TextNode() = default;
|
||||
|
||||
|
@ -162,8 +144,7 @@ public:
|
|||
|
||||
using NodeList = std::list<std::unique_ptr<Node>>;
|
||||
|
||||
class Element : public Node
|
||||
{
|
||||
class Element : public Node {
|
||||
public:
|
||||
Element(ElementID id);
|
||||
|
||||
|
@ -179,16 +160,13 @@ public:
|
|||
Rect currentViewport() const;
|
||||
|
||||
template<typename T>
|
||||
void transverse(T callback)
|
||||
{
|
||||
if(callback(this))
|
||||
void transverse(T callback) {
|
||||
if(!callback(this))
|
||||
return;
|
||||
|
||||
for(auto& child : children)
|
||||
{
|
||||
if(child->isText())
|
||||
{
|
||||
if(callback(child.get()))
|
||||
for(auto& child : children) {
|
||||
if(child->isText()) {
|
||||
if(!callback(child.get()))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
@ -199,8 +177,7 @@ public:
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
std::unique_ptr<T> cloneElement() const
|
||||
{
|
||||
std::unique_ptr<T> cloneElement() const {
|
||||
auto element = std::make_unique<T>();
|
||||
element->properties = properties;
|
||||
for(auto& child : children)
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
class GElement : public GraphicsElement
|
||||
{
|
||||
class GElement : public GraphicsElement {
|
||||
public:
|
||||
GElement();
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@ namespace lunasvg {
|
|||
|
||||
class LayoutShape;
|
||||
|
||||
class GeometryElement : public GraphicsElement
|
||||
{
|
||||
class GeometryElement : public GraphicsElement {
|
||||
public:
|
||||
GeometryElement(ElementID id);
|
||||
|
||||
|
@ -17,8 +16,7 @@ public:
|
|||
virtual Path path() const = 0;
|
||||
};
|
||||
|
||||
class PathElement : public GeometryElement
|
||||
{
|
||||
class PathElement : public GeometryElement {
|
||||
public:
|
||||
PathElement();
|
||||
|
||||
|
@ -28,16 +26,14 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class PolyElement : public GeometryElement
|
||||
{
|
||||
class PolyElement : public GeometryElement {
|
||||
public:
|
||||
PolyElement(ElementID id);
|
||||
|
||||
PointList points() const;
|
||||
};
|
||||
|
||||
class PolygonElement : public PolyElement
|
||||
{
|
||||
class PolygonElement : public PolyElement {
|
||||
public:
|
||||
PolygonElement();
|
||||
|
||||
|
@ -46,8 +42,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class PolylineElement : public PolyElement
|
||||
{
|
||||
class PolylineElement : public PolyElement {
|
||||
public:
|
||||
PolylineElement();
|
||||
|
||||
|
@ -56,8 +51,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class CircleElement : public GeometryElement
|
||||
{
|
||||
class CircleElement : public GeometryElement {
|
||||
public:
|
||||
CircleElement();
|
||||
|
||||
|
@ -70,8 +64,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class EllipseElement : public GeometryElement
|
||||
{
|
||||
class EllipseElement : public GeometryElement {
|
||||
public:
|
||||
EllipseElement();
|
||||
|
||||
|
@ -85,8 +78,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class LineElement : public GeometryElement
|
||||
{
|
||||
class LineElement : public GeometryElement {
|
||||
public:
|
||||
LineElement();
|
||||
|
||||
|
@ -100,8 +92,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class RectElement : public GeometryElement
|
||||
{
|
||||
class RectElement : public GeometryElement {
|
||||
public:
|
||||
RectElement();
|
||||
|
||||
|
|
|
@ -43,8 +43,7 @@ const Rect& LayoutContainer::fillBoundingBox() const
|
|||
if(m_fillBoundingBox.valid())
|
||||
return m_fillBoundingBox;
|
||||
|
||||
for(const auto& child : children)
|
||||
{
|
||||
for(const auto& child : children) {
|
||||
if(child->isHidden())
|
||||
continue;
|
||||
m_fillBoundingBox.unite(child->map(child->fillBoundingBox()));
|
||||
|
@ -58,8 +57,7 @@ const Rect& LayoutContainer::strokeBoundingBox() const
|
|||
if(m_strokeBoundingBox.valid())
|
||||
return m_strokeBoundingBox;
|
||||
|
||||
for(const auto& child : children)
|
||||
{
|
||||
for(const auto& child : children) {
|
||||
if(child->isHidden())
|
||||
continue;
|
||||
m_strokeBoundingBox.unite(child->map(child->strokeBoundingBox()));
|
||||
|
@ -78,15 +76,15 @@ LayoutObject* LayoutContainer::addChildIfNotEmpty(std::unique_ptr<LayoutContaine
|
|||
{
|
||||
if(child->children.empty())
|
||||
return nullptr;
|
||||
|
||||
return addChild(std::move(child));
|
||||
}
|
||||
|
||||
void LayoutContainer::renderChildren(RenderState& state) const
|
||||
{
|
||||
for(const auto& child : children)
|
||||
for(const auto& child : children) {
|
||||
child->render(state);
|
||||
}
|
||||
}
|
||||
|
||||
LayoutClipPath::LayoutClipPath()
|
||||
: LayoutContainer(LayoutId::ClipPath)
|
||||
|
@ -98,8 +96,7 @@ void LayoutClipPath::apply(RenderState& state) const
|
|||
RenderState newState(this, RenderMode::Clipping);
|
||||
newState.canvas = Canvas::create(state.canvas->box());
|
||||
newState.transform = transform * state.transform;
|
||||
if(units == Units::ObjectBoundingBox)
|
||||
{
|
||||
if(units == Units::ObjectBoundingBox) {
|
||||
const auto& box = state.objectBoundingBox();
|
||||
newState.transform.translate(box.x, box.y);
|
||||
newState.transform.scale(box.w, box.h);
|
||||
|
@ -118,8 +115,7 @@ LayoutMask::LayoutMask()
|
|||
void LayoutMask::apply(RenderState& state) const
|
||||
{
|
||||
Rect rect{x, y, width, height};
|
||||
if(units == Units::ObjectBoundingBox)
|
||||
{
|
||||
if(units == Units::ObjectBoundingBox) {
|
||||
const auto& box = state.objectBoundingBox();
|
||||
rect.x = rect.x * box.w + box.x;
|
||||
rect.y = rect.y * box.h + box.y;
|
||||
|
@ -130,8 +126,7 @@ void LayoutMask::apply(RenderState& state) const
|
|||
RenderState newState(this, state.mode());
|
||||
newState.canvas = Canvas::create(state.canvas->box());
|
||||
newState.transform = state.transform;
|
||||
if(contentUnits == Units::ObjectBoundingBox)
|
||||
{
|
||||
if(contentUnits == Units::ObjectBoundingBox) {
|
||||
const auto& box = state.objectBoundingBox();
|
||||
newState.transform.translate(box.x, box.y);
|
||||
newState.transform.scale(box.w, box.h);
|
||||
|
@ -230,8 +225,7 @@ LayoutPattern::LayoutPattern()
|
|||
void LayoutPattern::apply(RenderState& state) const
|
||||
{
|
||||
Rect rect{x, y, width, height};
|
||||
if(units == Units::ObjectBoundingBox)
|
||||
{
|
||||
if(units == Units::ObjectBoundingBox) {
|
||||
const auto& box = state.objectBoundingBox();
|
||||
rect.x = rect.x * box.w + box.x;
|
||||
rect.y = rect.y * box.h + box.y;
|
||||
|
@ -250,13 +244,10 @@ void LayoutPattern::apply(RenderState& state) const
|
|||
newState.canvas = Canvas::create(0, 0, width, height);
|
||||
newState.transform = Transform::scaled(scalex, scaley);
|
||||
|
||||
if(viewBox.valid())
|
||||
{
|
||||
if(viewBox.valid()) {
|
||||
auto viewTransform = preserveAspectRatio.getMatrix(rect.w, rect.h, viewBox);
|
||||
newState.transform.premultiply(viewTransform);
|
||||
}
|
||||
else if(contentUnits == Units::ObjectBoundingBox)
|
||||
{
|
||||
} else if(contentUnits == Units::ObjectBoundingBox) {
|
||||
const auto& box = state.objectBoundingBox();
|
||||
newState.transform.scale(box.w, box.h);
|
||||
}
|
||||
|
@ -282,8 +273,7 @@ LayoutLinearGradient::LayoutLinearGradient()
|
|||
void LayoutLinearGradient::apply(RenderState& state) const
|
||||
{
|
||||
auto transform = this->transform;
|
||||
if(units == Units::ObjectBoundingBox)
|
||||
{
|
||||
if(units == Units::ObjectBoundingBox) {
|
||||
const auto& box = state.objectBoundingBox();
|
||||
transform *= Transform(box.w, 0, 0, box.h, box.x, box.y);
|
||||
}
|
||||
|
@ -299,8 +289,7 @@ LayoutRadialGradient::LayoutRadialGradient()
|
|||
void LayoutRadialGradient::apply(RenderState& state) const
|
||||
{
|
||||
auto transform = this->transform;
|
||||
if(units == Units::ObjectBoundingBox)
|
||||
{
|
||||
if(units == Units::ObjectBoundingBox) {
|
||||
const auto& box = state.objectBoundingBox();
|
||||
transform *= Transform(box.w, 0, 0, box.h, box.x, box.y);
|
||||
}
|
||||
|
@ -378,15 +367,17 @@ void MarkerData::add(const LayoutMarker* marker, const Point& origin, double ang
|
|||
|
||||
void MarkerData::render(RenderState& state) const
|
||||
{
|
||||
for(const auto& position : positions)
|
||||
for(const auto& position : positions) {
|
||||
position.marker->renderMarker(state, position.origin, position.angle, strokeWidth);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkerData::inflate(Rect& box) const
|
||||
{
|
||||
for(const auto& position : positions)
|
||||
for(const auto& position : positions) {
|
||||
box.unite(position.marker->markerBoundingBox(position.origin, position.angle, strokeWidth));
|
||||
}
|
||||
}
|
||||
|
||||
LayoutShape::LayoutShape()
|
||||
: LayoutObject(LayoutId::Shape)
|
||||
|
@ -403,14 +394,11 @@ void LayoutShape::render(RenderState& state) const
|
|||
newState.transform = transform * state.transform;
|
||||
newState.beginGroup(state, info);
|
||||
|
||||
if(newState.mode() == RenderMode::Display)
|
||||
{
|
||||
if(newState.mode() == RenderMode::Display) {
|
||||
fillData.fill(newState, path);
|
||||
strokeData.stroke(newState, path);
|
||||
markerData.render(newState);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
newState.canvas->setColor(Color::Black);
|
||||
newState.canvas->fill(path, newState.transform, clipRule, BlendMode::Src, 1.0);
|
||||
}
|
||||
|
@ -450,8 +438,8 @@ RenderState::RenderState(const LayoutObject* object, RenderMode mode)
|
|||
|
||||
void RenderState::beginGroup(RenderState& state, const BlendInfo& info)
|
||||
{
|
||||
if(!info.clipper && !info.clip.valid() && (m_mode == RenderMode::Display && !(info.masker || info.opacity < 1.0)))
|
||||
{
|
||||
if(!info.clipper && !info.clip.valid()
|
||||
&& (m_mode == RenderMode::Display && !(info.masker || info.opacity < 1.0))) {
|
||||
canvas = state.canvas;
|
||||
return;
|
||||
}
|
||||
|
@ -494,7 +482,6 @@ LayoutObject* LayoutContext::getResourcesById(const std::string& id) const
|
|||
auto it = m_resourcesCache.find(id);
|
||||
if(it == m_resourcesCache.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
@ -597,8 +584,7 @@ DashData LayoutContext::dashData(const StyledElement* element)
|
|||
|
||||
LengthContext lengthContex(element);
|
||||
DashArray dashes;
|
||||
for(auto& dash : dasharray)
|
||||
{
|
||||
for(auto& dash : dasharray) {
|
||||
auto value = lengthContex.valueForLength(dash, LengthMode::Both);
|
||||
dashes.push_back(value);
|
||||
}
|
||||
|
@ -610,8 +596,7 @@ DashData LayoutContext::dashData(const StyledElement* element)
|
|||
DashData dashData;
|
||||
dashData.array.resize(num_dash);
|
||||
double sum = 0.0;
|
||||
for(std::size_t i = 0;i < num_dash;i++)
|
||||
{
|
||||
for(std::size_t i = 0; i < num_dash; i++) {
|
||||
dashData.array[i] = dashes[i % dashes.size()];
|
||||
sum += dashData.array[i];
|
||||
}
|
||||
|
@ -623,7 +608,6 @@ DashData LayoutContext::dashData(const StyledElement* element)
|
|||
dashData.offset = std::fmod(offset, sum);
|
||||
if(dashData.offset < 0.0)
|
||||
dashData.offset += sum;
|
||||
|
||||
return dashData;
|
||||
}
|
||||
|
||||
|
@ -669,8 +653,7 @@ MarkerData LayoutContext::markerData(const GeometryElement* element, const Path&
|
|||
|
||||
int index = 0;
|
||||
std::array<Point, 3> points;
|
||||
while(!it.isDone())
|
||||
{
|
||||
while(!it.isDone()) {
|
||||
switch(it.currentSegment(points)) {
|
||||
case PathCommand::MoveTo:
|
||||
startPoint = points[0];
|
||||
|
@ -699,22 +682,19 @@ MarkerData LayoutContext::markerData(const GeometryElement* element, const Path&
|
|||
index += 1;
|
||||
it.next();
|
||||
|
||||
if(!it.isDone() && (markerStart || markerMid))
|
||||
{
|
||||
if(!it.isDone() && (markerStart || markerMid)) {
|
||||
it.currentSegment(points);
|
||||
outslopePoints[0] = origin;
|
||||
outslopePoints[1] = points[0];
|
||||
|
||||
if(index == 1 && markerStart)
|
||||
{
|
||||
if(index == 1 && markerStart) {
|
||||
Point slope{outslopePoints[1].x - outslopePoints[0].x, outslopePoints[1].y - outslopePoints[0].y};
|
||||
auto angle = 180.0 * std::atan2(slope.y, slope.x) / pi;
|
||||
|
||||
markerData.add(markerStart, origin, angle);
|
||||
}
|
||||
|
||||
if(index > 1 && markerMid)
|
||||
{
|
||||
if(index > 1 && markerMid) {
|
||||
Point inslope{inslopePoints[1].x - inslopePoints[0].x, inslopePoints[1].y - inslopePoints[0].y};
|
||||
Point outslope{outslopePoints[1].x - outslopePoints[0].x, outslopePoints[1].y - outslopePoints[0].y};
|
||||
auto inangle = 180.0 * std::atan2(inslope.y, inslope.x) / pi;
|
||||
|
@ -725,8 +705,7 @@ MarkerData LayoutContext::markerData(const GeometryElement* element, const Path&
|
|||
}
|
||||
}
|
||||
|
||||
if(it.isDone() && markerEnd)
|
||||
{
|
||||
if(it.isDone() && markerEnd) {
|
||||
Point slope{inslopePoints[1].x - inslopePoints[0].x, inslopePoints[1].y - inslopePoints[0].y};
|
||||
auto angle = 180.0 * std::atan2(slope.y, slope.x) / pi;
|
||||
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
enum class LayoutId
|
||||
{
|
||||
enum class LayoutId {
|
||||
Symbol,
|
||||
Group,
|
||||
Shape,
|
||||
|
@ -26,8 +25,7 @@ enum class LayoutId
|
|||
|
||||
class RenderState;
|
||||
|
||||
class LayoutObject
|
||||
{
|
||||
class LayoutObject {
|
||||
public:
|
||||
LayoutObject(LayoutId id);
|
||||
virtual ~LayoutObject();
|
||||
|
@ -47,8 +45,7 @@ public:
|
|||
|
||||
using LayoutList = std::list<std::unique_ptr<LayoutObject>>;
|
||||
|
||||
class LayoutContainer : public LayoutObject
|
||||
{
|
||||
class LayoutContainer : public LayoutObject {
|
||||
public:
|
||||
LayoutContainer(LayoutId id);
|
||||
|
||||
|
@ -67,8 +64,7 @@ protected:
|
|||
mutable Rect m_strokeBoundingBox{Rect::Invalid};
|
||||
};
|
||||
|
||||
class LayoutClipPath : public LayoutContainer
|
||||
{
|
||||
class LayoutClipPath : public LayoutContainer {
|
||||
public:
|
||||
LayoutClipPath();
|
||||
|
||||
|
@ -80,8 +76,7 @@ public:
|
|||
const LayoutClipPath* clipper;
|
||||
};
|
||||
|
||||
class LayoutMask : public LayoutContainer
|
||||
{
|
||||
class LayoutMask : public LayoutContainer {
|
||||
public:
|
||||
LayoutMask();
|
||||
|
||||
|
@ -99,8 +94,7 @@ public:
|
|||
const LayoutClipPath* clipper;
|
||||
};
|
||||
|
||||
class LayoutSymbol : public LayoutContainer
|
||||
{
|
||||
class LayoutSymbol : public LayoutContainer {
|
||||
public:
|
||||
LayoutSymbol();
|
||||
|
||||
|
@ -117,8 +111,7 @@ public:
|
|||
const LayoutClipPath* clipper;
|
||||
};
|
||||
|
||||
class LayoutGroup : public LayoutContainer
|
||||
{
|
||||
class LayoutGroup : public LayoutContainer {
|
||||
public:
|
||||
LayoutGroup();
|
||||
|
||||
|
@ -132,8 +125,7 @@ public:
|
|||
const LayoutClipPath* clipper;
|
||||
};
|
||||
|
||||
class LayoutMarker : public LayoutContainer
|
||||
{
|
||||
class LayoutMarker : public LayoutContainer {
|
||||
public:
|
||||
LayoutMarker();
|
||||
|
||||
|
@ -153,8 +145,7 @@ public:
|
|||
const LayoutClipPath* clipper;
|
||||
};
|
||||
|
||||
class LayoutPattern : public LayoutContainer
|
||||
{
|
||||
class LayoutPattern : public LayoutContainer {
|
||||
public:
|
||||
LayoutPattern();
|
||||
|
||||
|
@ -172,8 +163,7 @@ public:
|
|||
PreserveAspectRatio preserveAspectRatio;
|
||||
};
|
||||
|
||||
class LayoutGradient : public LayoutObject
|
||||
{
|
||||
class LayoutGradient : public LayoutObject {
|
||||
public:
|
||||
LayoutGradient(LayoutId id);
|
||||
|
||||
|
@ -184,8 +174,7 @@ public:
|
|||
GradientStops stops;
|
||||
};
|
||||
|
||||
class LayoutLinearGradient : public LayoutGradient
|
||||
{
|
||||
class LayoutLinearGradient : public LayoutGradient {
|
||||
public:
|
||||
LayoutLinearGradient();
|
||||
|
||||
|
@ -198,8 +187,7 @@ public:
|
|||
double y2;
|
||||
};
|
||||
|
||||
class LayoutRadialGradient : public LayoutGradient
|
||||
{
|
||||
class LayoutRadialGradient : public LayoutGradient {
|
||||
public:
|
||||
LayoutRadialGradient();
|
||||
|
||||
|
@ -213,8 +201,7 @@ public:
|
|||
double fy;
|
||||
};
|
||||
|
||||
class LayoutSolidColor : public LayoutObject
|
||||
{
|
||||
class LayoutSolidColor : public LayoutObject {
|
||||
public:
|
||||
LayoutSolidColor();
|
||||
|
||||
|
@ -224,8 +211,7 @@ public:
|
|||
Color color;
|
||||
};
|
||||
|
||||
class FillData
|
||||
{
|
||||
class FillData {
|
||||
public:
|
||||
FillData() = default;
|
||||
|
||||
|
@ -238,8 +224,7 @@ public:
|
|||
WindRule fillRule{WindRule::NonZero};
|
||||
};
|
||||
|
||||
class StrokeData
|
||||
{
|
||||
class StrokeData {
|
||||
public:
|
||||
StrokeData() = default;
|
||||
|
||||
|
@ -257,8 +242,7 @@ public:
|
|||
DashData dash;
|
||||
};
|
||||
|
||||
class MarkerPosition
|
||||
{
|
||||
class MarkerPosition {
|
||||
public:
|
||||
MarkerPosition(const LayoutMarker* marker, const Point& origin, double angle);
|
||||
|
||||
|
@ -270,8 +254,7 @@ public:
|
|||
|
||||
using MarkerPositionList = std::vector<MarkerPosition>;
|
||||
|
||||
class MarkerData
|
||||
{
|
||||
class MarkerData {
|
||||
public:
|
||||
MarkerData() = default;
|
||||
|
||||
|
@ -284,8 +267,7 @@ public:
|
|||
double strokeWidth{1};
|
||||
};
|
||||
|
||||
class LayoutShape : public LayoutObject
|
||||
{
|
||||
class LayoutShape : public LayoutObject {
|
||||
public:
|
||||
LayoutShape();
|
||||
|
||||
|
@ -311,22 +293,19 @@ private:
|
|||
mutable Rect m_strokeBoundingBox{Rect::Invalid};
|
||||
};
|
||||
|
||||
enum class RenderMode
|
||||
{
|
||||
enum class RenderMode {
|
||||
Display,
|
||||
Clipping
|
||||
};
|
||||
|
||||
struct BlendInfo
|
||||
{
|
||||
struct BlendInfo {
|
||||
const LayoutClipPath* clipper;
|
||||
const LayoutMask* masker;
|
||||
double opacity;
|
||||
Rect clip;
|
||||
};
|
||||
|
||||
class RenderState
|
||||
{
|
||||
class RenderState {
|
||||
public:
|
||||
RenderState(const LayoutObject* object, RenderMode mode);
|
||||
|
||||
|
@ -350,8 +329,7 @@ class TreeBuilder;
|
|||
class StyledElement;
|
||||
class GeometryElement;
|
||||
|
||||
class LayoutContext
|
||||
{
|
||||
class LayoutContext {
|
||||
public:
|
||||
LayoutContext(const TreeBuilder* builder, LayoutSymbol* root);
|
||||
|
||||
|
@ -379,8 +357,7 @@ private:
|
|||
std::set<const Element*> m_references;
|
||||
};
|
||||
|
||||
class LayoutBreaker
|
||||
{
|
||||
class LayoutBreaker {
|
||||
public:
|
||||
LayoutBreaker(LayoutContext* context, const Element* element);
|
||||
~LayoutBreaker();
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
struct Bitmap::Impl
|
||||
{
|
||||
struct Bitmap::Impl {
|
||||
Impl(std::uint8_t* data, std::uint32_t width, std::uint32_t height, std::uint32_t stride);
|
||||
Impl(std::uint32_t width, std::uint32_t height);
|
||||
|
||||
|
@ -56,7 +55,11 @@ void Bitmap::reset(std::uint32_t width, std::uint32_t height)
|
|||
|
||||
std::uint8_t* Bitmap::data() const
|
||||
{
|
||||
return m_impl ? m_impl->data ? m_impl->data : m_impl->ownData.get() : nullptr;
|
||||
if(m_impl == nullptr)
|
||||
return nullptr;
|
||||
if(m_impl->data == nullptr)
|
||||
return m_impl->ownData.get();
|
||||
return m_impl->data;
|
||||
}
|
||||
|
||||
std::uint32_t Bitmap::width() const
|
||||
|
@ -90,17 +93,16 @@ void Bitmap::clear(std::uint32_t color)
|
|||
auto stride = this->stride();
|
||||
auto rowData = this->data();
|
||||
|
||||
for(std::uint32_t y = 0;y < height;y++)
|
||||
{
|
||||
for(std::uint32_t y = 0; y < height; y++) {
|
||||
auto data = rowData;
|
||||
for(std::uint32_t x = 0;x < width;x++)
|
||||
{
|
||||
for(std::uint32_t x = 0; x < width; x++) {
|
||||
data[0] = pb;
|
||||
data[1] = pg;
|
||||
data[2] = pr;
|
||||
data[3] = a;
|
||||
data += 4;
|
||||
}
|
||||
|
||||
rowData += stride;
|
||||
}
|
||||
}
|
||||
|
@ -112,18 +114,15 @@ void Bitmap::convert(int ri, int gi, int bi, int ai, bool unpremultiply)
|
|||
auto stride = this->stride();
|
||||
auto rowData = this->data();
|
||||
|
||||
for(std::uint32_t y = 0;y < height;y++)
|
||||
{
|
||||
for(std::uint32_t y = 0; y < height; y++) {
|
||||
auto data = rowData;
|
||||
for(std::uint32_t x = 0;x < width;x++)
|
||||
{
|
||||
for(std::uint32_t x = 0; x < width; x++) {
|
||||
auto b = data[0];
|
||||
auto g = data[1];
|
||||
auto r = data[2];
|
||||
auto a = data[3];
|
||||
|
||||
if(unpremultiply && a != 0)
|
||||
{
|
||||
if(unpremultiply && a != 0) {
|
||||
r = (r * 255) / a;
|
||||
g = (g * 255) / a;
|
||||
b = (b * 255) / a;
|
||||
|
@ -135,6 +134,7 @@ void Bitmap::convert(int ri, int gi, int bi, int ai, bool unpremultiply)
|
|||
data[ai] = a;
|
||||
data += 4;
|
||||
}
|
||||
|
||||
rowData += stride;
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ Matrix Matrix::rotated(double angle, double cx, double cy)
|
|||
|
||||
Matrix Matrix::scaled(double sx, double sy)
|
||||
{
|
||||
return Transform::scaled(sx, sy);;
|
||||
return Transform::scaled(sx, sy);
|
||||
}
|
||||
|
||||
Matrix Matrix::sheared(double shx, double shy)
|
||||
|
@ -348,17 +348,12 @@ Bitmap Document::renderToBitmap(std::uint32_t width, std::uint32_t height, std::
|
|||
if(root->width == 0.0 || root->height == 0.0)
|
||||
return Bitmap{};
|
||||
|
||||
if(width == 0 && height == 0)
|
||||
{
|
||||
if(width == 0 && height == 0) {
|
||||
width = static_cast<std::uint32_t>(std::ceil(root->width));
|
||||
height = static_cast<std::uint32_t>(std::ceil(root->height));
|
||||
}
|
||||
else if(width != 0 && height == 0)
|
||||
{
|
||||
} else if(width != 0 && height == 0) {
|
||||
height = static_cast<std::uint32_t>(std::ceil(width * root->height / root->width));
|
||||
}
|
||||
else if(height != 0 && width == 0)
|
||||
{
|
||||
} else if(height != 0 && width == 0) {
|
||||
width = static_cast<std::uint32_t>(std::ceil(height * root->width / root->height));
|
||||
}
|
||||
|
||||
|
@ -369,12 +364,8 @@ Bitmap Document::renderToBitmap(std::uint32_t width, std::uint32_t height, std::
|
|||
return bitmap;
|
||||
}
|
||||
|
||||
Document::Document()
|
||||
{
|
||||
}
|
||||
Document::Document() = default;
|
||||
|
||||
Document::~Document()
|
||||
{
|
||||
}
|
||||
Document::~Document() = default;
|
||||
|
||||
} // namespace lunasvg
|
||||
|
|
|
@ -7,8 +7,7 @@ namespace lunasvg {
|
|||
|
||||
class LayoutMarker;
|
||||
|
||||
class MarkerElement : public StyledElement
|
||||
{
|
||||
class MarkerElement : public StyledElement {
|
||||
public:
|
||||
MarkerElement();
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@ namespace lunasvg {
|
|||
|
||||
class LayoutMask;
|
||||
|
||||
class MaskElement : public StyledElement
|
||||
{
|
||||
class MaskElement : public StyledElement {
|
||||
public:
|
||||
MaskElement();
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ GradientStops GradientElement::buildGradientStops() const
|
|||
{
|
||||
GradientStops gradientStops;
|
||||
double prevOffset = 0.0;
|
||||
for(auto& child : children)
|
||||
{
|
||||
for(auto& child : children) {
|
||||
if(child->isText())
|
||||
continue;
|
||||
auto element = static_cast<Element*>(child.get());
|
||||
|
@ -96,8 +95,7 @@ std::unique_ptr<LayoutObject> LinearGradientElement::getPainter(LayoutContext* c
|
|||
std::set<const GradientElement*> processedGradients;
|
||||
const GradientElement* current = this;
|
||||
|
||||
while(true)
|
||||
{
|
||||
while(true) {
|
||||
if(!attributes.hasGradientTransform() && current->has(PropertyID::GradientTransform))
|
||||
attributes.setGradientTransform(current->gradientTransform());
|
||||
if(!attributes.hasSpreadMethod() && current->has(PropertyID::SpreadMethod))
|
||||
|
@ -107,8 +105,7 @@ std::unique_ptr<LayoutObject> LinearGradientElement::getPainter(LayoutContext* c
|
|||
if(!attributes.hasGradientStops())
|
||||
attributes.setGradientStops(current->buildGradientStops());
|
||||
|
||||
if(current->id == ElementID::LinearGradient)
|
||||
{
|
||||
if(current->id == ElementID::LinearGradient) {
|
||||
auto element = static_cast<const LinearGradientElement*>(current);
|
||||
if(!attributes.hasX1() && element->has(PropertyID::X1))
|
||||
attributes.setX1(element->x1());
|
||||
|
@ -126,9 +123,10 @@ std::unique_ptr<LayoutObject> LinearGradientElement::getPainter(LayoutContext* c
|
|||
|
||||
processedGradients.insert(current);
|
||||
current = static_cast<const GradientElement*>(ref);
|
||||
if(processedGradients.find(current) != processedGradients.end())
|
||||
if(processedGradients.find(current) != processedGradients.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto& stops = attributes.gradientStops();
|
||||
if(stops.empty())
|
||||
|
@ -139,8 +137,7 @@ std::unique_ptr<LayoutObject> LinearGradientElement::getPainter(LayoutContext* c
|
|||
auto y1 = lengthContext.valueForLength(attributes.y1(), LengthMode::Height);
|
||||
auto x2 = lengthContext.valueForLength(attributes.x2(), LengthMode::Width);
|
||||
auto y2 = lengthContext.valueForLength(attributes.y2(), LengthMode::Height);
|
||||
if((x1 == x2 && y1 == y2) || stops.size() == 1)
|
||||
{
|
||||
if((x1 == x2 && y1 == y2) || stops.size() == 1) {
|
||||
auto solid = std::make_unique<LayoutSolidColor>();
|
||||
solid->color = std::get<1>(stops.back());
|
||||
return std::move(solid);
|
||||
|
@ -204,8 +201,7 @@ std::unique_ptr<LayoutObject> RadialGradientElement::getPainter(LayoutContext* c
|
|||
std::set<const GradientElement*> processedGradients;
|
||||
const GradientElement* current = this;
|
||||
|
||||
while(true)
|
||||
{
|
||||
while(true) {
|
||||
if(!attributes.hasGradientTransform() && current->has(PropertyID::GradientTransform))
|
||||
attributes.setGradientTransform(current->gradientTransform());
|
||||
if(!attributes.hasSpreadMethod() && current->has(PropertyID::SpreadMethod))
|
||||
|
@ -215,8 +211,7 @@ std::unique_ptr<LayoutObject> RadialGradientElement::getPainter(LayoutContext* c
|
|||
if(!attributes.hasGradientStops())
|
||||
attributes.setGradientStops(current->buildGradientStops());
|
||||
|
||||
if(current->id == ElementID::RadialGradient)
|
||||
{
|
||||
if(current->id == ElementID::RadialGradient) {
|
||||
auto element = static_cast<const RadialGradientElement*>(current);
|
||||
if(!attributes.hasCx() && element->has(PropertyID::Cx))
|
||||
attributes.setCx(element->cx());
|
||||
|
@ -236,9 +231,10 @@ std::unique_ptr<LayoutObject> RadialGradientElement::getPainter(LayoutContext* c
|
|||
|
||||
processedGradients.insert(current);
|
||||
current = static_cast<const GradientElement*>(ref);
|
||||
if(processedGradients.find(current) != processedGradients.end())
|
||||
if(processedGradients.find(current) != processedGradients.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!attributes.hasFx())
|
||||
attributes.setFx(attributes.cx());
|
||||
|
@ -250,8 +246,7 @@ std::unique_ptr<LayoutObject> RadialGradientElement::getPainter(LayoutContext* c
|
|||
return nullptr;
|
||||
|
||||
auto& r = attributes.r();
|
||||
if(r.isZero() || stops.size() == 1)
|
||||
{
|
||||
if(r.isZero() || stops.size() == 1) {
|
||||
auto solid = std::make_unique<LayoutSolidColor>();
|
||||
solid->color = std::get<1>(stops.back());
|
||||
return std::move(solid);
|
||||
|
@ -351,8 +346,7 @@ std::unique_ptr<LayoutObject> PatternElement::getPainter(LayoutContext* context)
|
|||
std::set<const PatternElement*> processedPatterns;
|
||||
const PatternElement* current = this;
|
||||
|
||||
while(true)
|
||||
{
|
||||
while(true) {
|
||||
if(!attributes.hasX() && current->has(PropertyID::X))
|
||||
attributes.setX(current->x());
|
||||
if(!attributes.hasY() && current->has(PropertyID::Y))
|
||||
|
@ -380,9 +374,10 @@ std::unique_ptr<LayoutObject> PatternElement::getPainter(LayoutContext* context)
|
|||
|
||||
processedPatterns.insert(current);
|
||||
current = static_cast<const PatternElement*>(ref);
|
||||
if(processedPatterns.find(current) != processedPatterns.end())
|
||||
if(processedPatterns.find(current) != processedPatterns.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto& width = attributes.width();
|
||||
auto& height = attributes.height();
|
||||
|
|
|
@ -8,8 +8,7 @@ namespace lunasvg {
|
|||
|
||||
class LayoutObject;
|
||||
|
||||
class PaintElement : public StyledElement
|
||||
{
|
||||
class PaintElement : public StyledElement {
|
||||
public:
|
||||
PaintElement(ElementID id);
|
||||
|
||||
|
@ -17,8 +16,7 @@ public:
|
|||
virtual std::unique_ptr<LayoutObject> getPainter(LayoutContext* context) const = 0;
|
||||
};
|
||||
|
||||
class GradientElement : public PaintElement
|
||||
{
|
||||
class GradientElement : public PaintElement {
|
||||
public:
|
||||
GradientElement(ElementID id);
|
||||
|
||||
|
@ -29,8 +27,7 @@ public:
|
|||
GradientStops buildGradientStops() const;
|
||||
};
|
||||
|
||||
class LinearGradientElement : public GradientElement
|
||||
{
|
||||
class LinearGradientElement : public GradientElement {
|
||||
public:
|
||||
LinearGradientElement();
|
||||
|
||||
|
@ -43,8 +40,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class RadialGradientElement : public GradientElement
|
||||
{
|
||||
class RadialGradientElement : public GradientElement {
|
||||
public:
|
||||
RadialGradientElement();
|
||||
|
||||
|
@ -58,8 +54,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class PatternElement : public PaintElement
|
||||
{
|
||||
class PatternElement : public PaintElement {
|
||||
public:
|
||||
PatternElement();
|
||||
|
||||
|
@ -79,8 +74,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class SolidColorElement : public PaintElement
|
||||
{
|
||||
class SolidColorElement : public PaintElement {
|
||||
public:
|
||||
SolidColorElement();
|
||||
|
||||
|
@ -88,8 +82,7 @@ public:
|
|||
std::unique_ptr<Node> clone() const;
|
||||
};
|
||||
|
||||
class GradientAttributes
|
||||
{
|
||||
class GradientAttributes {
|
||||
public:
|
||||
GradientAttributes() = default;
|
||||
|
||||
|
@ -103,26 +96,22 @@ public:
|
|||
bool hasGradientUnits() const { return m_hasGradientUnits; }
|
||||
bool hasGradientStops() const { return m_hasGradientStops; }
|
||||
|
||||
void setGradientTransform(const Transform& gradientTransform)
|
||||
{
|
||||
void setGradientTransform(const Transform& gradientTransform) {
|
||||
m_gradientTransform = gradientTransform;
|
||||
m_hasGradientTransform = true;
|
||||
}
|
||||
|
||||
void setSpreadMethod(SpreadMethod spreadMethod)
|
||||
{
|
||||
void setSpreadMethod(SpreadMethod spreadMethod) {
|
||||
m_spreadMethod = spreadMethod;
|
||||
m_hasSpreadMethod = true;
|
||||
}
|
||||
|
||||
void setGradientUnits(Units gradientUnits)
|
||||
{
|
||||
void setGradientUnits(Units gradientUnits) {
|
||||
m_gradientUnits = gradientUnits;
|
||||
m_hasGradientUnits = true;
|
||||
}
|
||||
|
||||
void setGradientStops(const GradientStops& gradientStops)
|
||||
{
|
||||
void setGradientStops(const GradientStops& gradientStops) {
|
||||
m_gradientStops = gradientStops;
|
||||
m_hasGradientStops = gradientStops.size();
|
||||
}
|
||||
|
@ -139,8 +128,7 @@ private:
|
|||
bool m_hasGradientStops{false};
|
||||
};
|
||||
|
||||
class LinearGradientAttributes : public GradientAttributes
|
||||
{
|
||||
class LinearGradientAttributes : public GradientAttributes {
|
||||
public:
|
||||
LinearGradientAttributes() = default;
|
||||
|
||||
|
@ -154,26 +142,22 @@ public:
|
|||
bool hasX2() const { return m_hasX2; }
|
||||
bool hasY2() const { return m_hasY2; }
|
||||
|
||||
void setX1(const Length& x1)
|
||||
{
|
||||
void setX1(const Length& x1) {
|
||||
m_x1 = x1;
|
||||
m_hasX1 = true;
|
||||
}
|
||||
|
||||
void setY1(const Length& y1)
|
||||
{
|
||||
void setY1(const Length& y1) {
|
||||
m_y1 = y1;
|
||||
m_hasY1 = true;
|
||||
}
|
||||
|
||||
void setX2(const Length& x2)
|
||||
{
|
||||
void setX2(const Length& x2) {
|
||||
m_x2 = x2;
|
||||
m_hasX2 = true;
|
||||
}
|
||||
|
||||
void setY2(const Length& y2)
|
||||
{
|
||||
void setY2(const Length& y2) {
|
||||
m_y2 = y2;
|
||||
m_hasY2 = true;
|
||||
}
|
||||
|
@ -190,8 +174,7 @@ private:
|
|||
bool m_hasY2{false};
|
||||
};
|
||||
|
||||
class RadialGradientAttributes : public GradientAttributes
|
||||
{
|
||||
class RadialGradientAttributes : public GradientAttributes {
|
||||
public:
|
||||
RadialGradientAttributes() = default;
|
||||
|
||||
|
@ -207,32 +190,27 @@ public:
|
|||
bool hasFx() const { return m_hasFx; }
|
||||
bool hasFy() const { return m_hasFy; }
|
||||
|
||||
void setCx(const Length& cx)
|
||||
{
|
||||
void setCx(const Length& cx) {
|
||||
m_cx = cx;
|
||||
m_hasCx = true;
|
||||
}
|
||||
|
||||
void setCy(const Length& cy)
|
||||
{
|
||||
void setCy(const Length& cy) {
|
||||
m_cy = cy;
|
||||
m_hasCy = true;
|
||||
}
|
||||
|
||||
void setR(const Length& r)
|
||||
{
|
||||
void setR(const Length& r) {
|
||||
m_r = r;
|
||||
m_hasR = true;
|
||||
}
|
||||
|
||||
void setFx(const Length& fx)
|
||||
{
|
||||
void setFx(const Length& fx) {
|
||||
m_fx = fx;
|
||||
m_hasFx = true;
|
||||
}
|
||||
|
||||
void setFy(const Length& fy)
|
||||
{
|
||||
void setFy(const Length& fy) {
|
||||
m_fy = fy;
|
||||
m_hasFy = true;
|
||||
}
|
||||
|
@ -252,8 +230,7 @@ private:
|
|||
bool m_hasFy{false};
|
||||
};
|
||||
|
||||
class PatternAttributes
|
||||
{
|
||||
class PatternAttributes {
|
||||
public:
|
||||
PatternAttributes() = default;
|
||||
|
||||
|
@ -279,62 +256,52 @@ public:
|
|||
bool hasPreserveAspectRatio() const { return m_hasPreserveAspectRatio; }
|
||||
bool hasPatternContentElement() const { return m_hasPatternContentElement; }
|
||||
|
||||
void setX(const Length& x)
|
||||
{
|
||||
void setX(const Length& x) {
|
||||
m_x = x;
|
||||
m_hasX = true;
|
||||
}
|
||||
|
||||
void setY(const Length& y)
|
||||
{
|
||||
void setY(const Length& y) {
|
||||
m_y = y;
|
||||
m_hasY = true;
|
||||
}
|
||||
|
||||
void setWidth(const Length& width)
|
||||
{
|
||||
void setWidth(const Length& width) {
|
||||
m_width = width;
|
||||
m_hasWidth = true;
|
||||
}
|
||||
|
||||
void setHeight(const Length& height)
|
||||
{
|
||||
void setHeight(const Length& height) {
|
||||
m_height = height;
|
||||
m_hasHeight = true;
|
||||
}
|
||||
|
||||
void setPatternTransform(const Transform& patternTransform)
|
||||
{
|
||||
void setPatternTransform(const Transform& patternTransform) {
|
||||
m_patternTransform = patternTransform;
|
||||
m_hasPatternTransform = true;
|
||||
}
|
||||
|
||||
void setPatternUnits(Units patternUnits)
|
||||
{
|
||||
void setPatternUnits(Units patternUnits) {
|
||||
m_patternUnits = patternUnits;
|
||||
m_hasPatternUnits = true;
|
||||
}
|
||||
|
||||
void setPatternContentUnits(Units patternContentUnits)
|
||||
{
|
||||
void setPatternContentUnits(Units patternContentUnits) {
|
||||
m_patternContentUnits = patternContentUnits;
|
||||
m_hasPatternContentUnits = true;
|
||||
}
|
||||
|
||||
void setViewBox(const Rect& viewBox)
|
||||
{
|
||||
void setViewBox(const Rect& viewBox) {
|
||||
m_viewBox = viewBox;
|
||||
m_hasViewBox = true;
|
||||
}
|
||||
|
||||
void setPreserveAspectRatio(const PreserveAspectRatio& preserveAspectRatio)
|
||||
{
|
||||
void setPreserveAspectRatio(const PreserveAspectRatio& preserveAspectRatio) {
|
||||
m_preserveAspectRatio = preserveAspectRatio;
|
||||
m_hasPreserveAspectRatio = true;
|
||||
}
|
||||
|
||||
void setPatternContentElement(const PatternElement* patternContentElement)
|
||||
{
|
||||
void setPatternContentElement(const PatternElement* patternContentElement) {
|
||||
m_patternContentElement = patternContentElement;
|
||||
m_hasPatternContentElement = true;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,14 +12,12 @@ namespace lunasvg {
|
|||
class SVGElement;
|
||||
class StyledElement;
|
||||
|
||||
enum LengthNegativeValuesMode
|
||||
{
|
||||
enum LengthNegativeValuesMode {
|
||||
AllowNegativeLengths,
|
||||
ForbidNegativeLengths
|
||||
};
|
||||
|
||||
enum class TransformType
|
||||
{
|
||||
enum class TransformType {
|
||||
Matrix,
|
||||
Rotate,
|
||||
Scale,
|
||||
|
@ -28,8 +26,7 @@ enum class TransformType
|
|||
Translate
|
||||
};
|
||||
|
||||
class Parser
|
||||
{
|
||||
class Parser {
|
||||
public:
|
||||
static Length parseLength(const std::string& string, LengthNegativeValuesMode mode, const Length& defaultValue);
|
||||
static LengthList parseLengthList(const std::string& string, LengthNegativeValuesMode mode);
|
||||
|
@ -69,10 +66,8 @@ struct SimpleSelector;
|
|||
using Selector = std::vector<SimpleSelector>;
|
||||
using SelectorList = std::vector<Selector>;
|
||||
|
||||
struct AttributeSelector
|
||||
{
|
||||
enum class MatchType
|
||||
{
|
||||
struct AttributeSelector {
|
||||
enum class MatchType {
|
||||
None,
|
||||
Equal,
|
||||
Includes,
|
||||
|
@ -87,10 +82,8 @@ struct AttributeSelector
|
|||
std::string value;
|
||||
};
|
||||
|
||||
struct PseudoClassSelector
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
struct PseudoClassSelector {
|
||||
enum class Type {
|
||||
Unknown,
|
||||
Empty,
|
||||
Root,
|
||||
|
@ -105,15 +98,11 @@ struct PseudoClassSelector
|
|||
};
|
||||
|
||||
Type type{Type::Unknown};
|
||||
int16_t a{0};
|
||||
int16_t b{0};
|
||||
SelectorList subSelectors;
|
||||
};
|
||||
|
||||
struct SimpleSelector
|
||||
{
|
||||
enum class Combinator
|
||||
{
|
||||
struct SimpleSelector {
|
||||
enum class Combinator {
|
||||
Descendant,
|
||||
Child,
|
||||
DirectAdjacent,
|
||||
|
@ -126,33 +115,40 @@ struct SimpleSelector
|
|||
std::vector<PseudoClassSelector> pseudoClassSelectors;
|
||||
};
|
||||
|
||||
struct Rule
|
||||
{
|
||||
struct Declaration {
|
||||
int specificity;
|
||||
PropertyID id;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
using DeclarationList = std::vector<Declaration>;
|
||||
|
||||
struct Rule {
|
||||
SelectorList selectors;
|
||||
PropertyList declarations;
|
||||
DeclarationList declarations;
|
||||
};
|
||||
|
||||
class RuleData {
|
||||
public:
|
||||
RuleData(const Selector& selector, const PropertyList& properties, uint32_t specificity, uint32_t position)
|
||||
: m_selector(selector), m_properties(properties), m_specificity(specificity), m_position(position)
|
||||
RuleData(const Selector& selector, const DeclarationList& declarations, uint32_t specificity, uint32_t position)
|
||||
: m_selector(selector), m_declarations(declarations), m_specificity(specificity), m_position(position)
|
||||
{}
|
||||
|
||||
const Selector& selector() const { return m_selector; }
|
||||
const PropertyList& properties() const { return m_properties; }
|
||||
const DeclarationList& declarations() const { return m_declarations; }
|
||||
const uint32_t& specificity() const { return m_specificity; }
|
||||
const uint32_t& position() const { return m_position; }
|
||||
|
||||
bool match(const Element* element) const;
|
||||
|
||||
private:
|
||||
bool matchSimpleSelector(const SimpleSelector& selector, const Element* element) const;
|
||||
bool matchAttributeSelector(const AttributeSelector& selector, const Element* element) const;
|
||||
bool matchPseudoClassSelector(const PseudoClassSelector& selector, const Element* element) const;
|
||||
static bool matchSimpleSelector(const SimpleSelector& selector, const Element* element);
|
||||
static bool matchAttributeSelector(const AttributeSelector& selector, const Element* element);
|
||||
static bool matchPseudoClassSelector(const PseudoClassSelector& selector, const Element* element);
|
||||
|
||||
private:
|
||||
Selector m_selector;
|
||||
PropertyList m_properties;
|
||||
DeclarationList m_declarations;
|
||||
uint32_t m_specificity;
|
||||
uint32_t m_position;
|
||||
};
|
||||
|
@ -164,31 +160,23 @@ class StyleSheet {
|
|||
public:
|
||||
StyleSheet() = default;
|
||||
|
||||
void parse(const std::string& content);
|
||||
bool parse(const std::string& content);
|
||||
void add(const Rule& rule);
|
||||
bool empty() const { return m_position == 0; }
|
||||
bool empty() const { return m_rules.empty(); }
|
||||
|
||||
std::vector<const PropertyList*> match(const Element* element) const;
|
||||
|
||||
private:
|
||||
std::multiset<RuleData> m_rules;
|
||||
uint32_t m_position{0};
|
||||
};
|
||||
|
||||
class CSSParser
|
||||
{
|
||||
public:
|
||||
CSSParser() = default;
|
||||
|
||||
static bool parseSheet(StyleSheet* sheet, const std::string& value);
|
||||
const std::multiset<RuleData>& rules() const { return m_rules; }
|
||||
|
||||
private:
|
||||
static bool parseAtRule(const char*& ptr, const char* end);
|
||||
static bool parseRule(const char*& ptr, const char* end, Rule& rule);
|
||||
static bool parseSelectors(const char*& ptr, const char* end, SelectorList& selectors);
|
||||
static bool parseDeclarations(const char*& ptr, const char* end, PropertyList& declarations);
|
||||
static bool parseDeclarations(const char*& ptr, const char* end, DeclarationList& declarations);
|
||||
static bool parseSelector(const char*& ptr, const char* end, Selector& selector);
|
||||
static bool parseSimpleSelector(const char*& ptr, const char* end, SimpleSelector& simpleSelector);
|
||||
|
||||
private:
|
||||
std::multiset<RuleData> m_rules;
|
||||
uint32_t m_position{0};
|
||||
};
|
||||
|
||||
class LayoutSymbol;
|
||||
|
|
|
@ -43,10 +43,8 @@ inline bool skipDesc(const char*& ptr, const char* end, const char ch)
|
|||
inline bool skipDesc(const char*& ptr, const char* end, const char* data)
|
||||
{
|
||||
int read = 0;
|
||||
while(data[read])
|
||||
{
|
||||
if(ptr >= end || *ptr != data[read])
|
||||
{
|
||||
while(data[read]) {
|
||||
if(ptr >= end || *ptr != data[read]) {
|
||||
ptr -= read;
|
||||
return false;
|
||||
}
|
||||
|
@ -68,8 +66,7 @@ inline bool skipUntil(const char*& ptr, const char* end, const char ch)
|
|||
|
||||
inline bool skipUntil(const char*& ptr, const char* end, const char* data)
|
||||
{
|
||||
while(ptr < end)
|
||||
{
|
||||
while(ptr < end) {
|
||||
auto start = ptr;
|
||||
if(skipDesc(start, end, data))
|
||||
break;
|
||||
|
@ -112,10 +109,8 @@ inline bool skipWsDelimiter(const char*& ptr, const char* end, const char delimi
|
|||
if(ptr < end && !IS_WS(*ptr) && *ptr != delimiter)
|
||||
return false;
|
||||
|
||||
if(skipWs(ptr, end))
|
||||
{
|
||||
if(ptr < end && *ptr == delimiter)
|
||||
{
|
||||
if(skipWs(ptr, end)) {
|
||||
if(ptr < end && *ptr == delimiter) {
|
||||
++ptr;
|
||||
skipWs(ptr, end);
|
||||
}
|
||||
|
@ -153,8 +148,7 @@ inline bool parseInteger(const char*& ptr, const char* end, T& integer, int base
|
|||
|
||||
if(ptr < end && *ptr == '+')
|
||||
++ptr;
|
||||
else if(ptr < end && isSigned && *ptr == '-')
|
||||
{
|
||||
else if(ptr < end && isSigned && *ptr == '-') {
|
||||
++ptr;
|
||||
isNegative = true;
|
||||
}
|
||||
|
@ -200,8 +194,7 @@ inline bool parseNumber(const char*& ptr, const char* end, T& number)
|
|||
|
||||
if(ptr < end && *ptr == '+')
|
||||
++ptr;
|
||||
else if(ptr < end && *ptr == '-')
|
||||
{
|
||||
else if(ptr < end && *ptr == '-') {
|
||||
++ptr;
|
||||
sign = -1;
|
||||
}
|
||||
|
@ -209,16 +202,14 @@ inline bool parseNumber(const char*& ptr, const char* end, T& number)
|
|||
if(ptr >= end || !(IS_NUM(*ptr) || *ptr == '.'))
|
||||
return false;
|
||||
|
||||
if(*ptr != '.')
|
||||
{
|
||||
if(*ptr != '.') {
|
||||
do {
|
||||
integer = static_cast<T>(10) * integer + (*ptr - '0');
|
||||
++ptr;
|
||||
} while(ptr < end && IS_NUM(*ptr));
|
||||
}
|
||||
|
||||
if(ptr < end && *ptr == '.')
|
||||
{
|
||||
if(ptr < end && *ptr == '.') {
|
||||
++ptr;
|
||||
if(ptr >= end || !IS_NUM(*ptr))
|
||||
return false;
|
||||
|
@ -238,8 +229,7 @@ inline bool parseNumber(const char*& ptr, const char* end, T& number)
|
|||
++ptr;
|
||||
if(ptr < end && *ptr == '+')
|
||||
++ptr;
|
||||
else if(ptr < end && *ptr == '-')
|
||||
{
|
||||
else if(ptr < end && *ptr == '-') {
|
||||
++ptr;
|
||||
expsign = -1;
|
||||
}
|
||||
|
|
|
@ -238,8 +238,7 @@ Rect Transform::map(const Rect& rect) const
|
|||
auto r = p[0].x;
|
||||
auto b = p[0].y;
|
||||
|
||||
for(int i = 1;i < 4;i++)
|
||||
{
|
||||
for(int i = 1; i < 4; i++) {
|
||||
if(p[i].x < l) l = p[i].x;
|
||||
if(p[i].x > r) r = p[i].x;
|
||||
if(p[i].y < t) t = p[i].y;
|
||||
|
@ -356,8 +355,7 @@ void Path::arcTo(double cx, double cy, double rx, double ry, double xAxisRotatio
|
|||
auto Px = dx1 * dx1;
|
||||
auto Py = dy1 * dy1;
|
||||
auto check = Px / Pr1 + Py / Pr2;
|
||||
if(check > 1)
|
||||
{
|
||||
if(check > 1) {
|
||||
rx = rx * std::sqrt(check);
|
||||
ry = ry * std::sqrt(check);
|
||||
}
|
||||
|
@ -388,8 +386,7 @@ void Path::arcTo(double cx, double cy, double rx, double ry, double xAxisRotatio
|
|||
th_arc -= 2.0 * pi;
|
||||
|
||||
auto n_segs = static_cast<int>(std::ceil(std::fabs(th_arc / (pi * 0.5 + 0.001))));
|
||||
for(int i = 0;i < n_segs;i++)
|
||||
{
|
||||
for(int i = 0; i < n_segs; i++) {
|
||||
auto th2 = th0 + i * th_arc / n_segs;
|
||||
auto th3 = th0 + (i + 1) * th_arc / n_segs;
|
||||
|
||||
|
@ -445,17 +442,14 @@ void Path::rect(double x, double y, double w, double h, double rx, double ry)
|
|||
auto right = x + w;
|
||||
auto bottom = y + h;
|
||||
|
||||
if(rx == 0.0 && ry == 0.0)
|
||||
{
|
||||
if(rx == 0.0 && ry == 0.0) {
|
||||
moveTo(x, y);
|
||||
lineTo(right, y);
|
||||
lineTo(right, bottom);
|
||||
lineTo(x, bottom);
|
||||
lineTo(x, y);
|
||||
close();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
double cpx = rx * kappa;
|
||||
double cpy = ry * kappa;
|
||||
moveTo(x, y+ry);
|
||||
|
@ -481,8 +475,7 @@ Rect Path::box() const
|
|||
auto r = m_points[0].x;
|
||||
auto b = m_points[0].y;
|
||||
|
||||
for(std::size_t i = 1;i < m_points.size();i++)
|
||||
{
|
||||
for(std::size_t i = 1; i < m_points.size(); i++) {
|
||||
if(m_points[i].x < l) l = m_points[i].x;
|
||||
if(m_points[i].x > r) r = m_points[i].x;
|
||||
if(m_points[i].y < t) t = m_points[i].y;
|
||||
|
@ -594,8 +587,7 @@ static const double sqrt2 = 1.41421356237309504880;
|
|||
|
||||
double Length::value(const Element* element, LengthMode mode) const
|
||||
{
|
||||
if(m_units == LengthUnits::Percent)
|
||||
{
|
||||
if(m_units == LengthUnits::Percent) {
|
||||
auto viewport = element->currentViewport();
|
||||
auto w = viewport.w;
|
||||
auto h = viewport.h;
|
||||
|
@ -635,8 +627,7 @@ Transform PreserveAspectRatio::getMatrix(double width, double height, const Rect
|
|||
|
||||
auto xscale = width / viewBox.w;
|
||||
auto yscale = height / viewBox.h;
|
||||
if(m_align == Align::None)
|
||||
{
|
||||
if(m_align == Align::None) {
|
||||
auto xoffset = -viewBox.x * xscale;
|
||||
auto yoffset = -viewBox.y * yscale;
|
||||
return Transform{xscale, 0, 0, yscale, xoffset, yoffset};
|
||||
|
|
|
@ -8,65 +8,55 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
enum class Display
|
||||
{
|
||||
enum class Display {
|
||||
Inline,
|
||||
None
|
||||
};
|
||||
|
||||
enum class Visibility
|
||||
{
|
||||
enum class Visibility {
|
||||
Visible,
|
||||
Hidden
|
||||
};
|
||||
|
||||
enum class Overflow
|
||||
{
|
||||
enum class Overflow {
|
||||
Visible,
|
||||
Hidden
|
||||
};
|
||||
|
||||
enum class LineCap
|
||||
{
|
||||
enum class LineCap {
|
||||
Butt,
|
||||
Round,
|
||||
Square
|
||||
};
|
||||
|
||||
enum class LineJoin
|
||||
{
|
||||
enum class LineJoin {
|
||||
Miter,
|
||||
Round,
|
||||
Bevel
|
||||
};
|
||||
|
||||
enum class WindRule
|
||||
{
|
||||
enum class WindRule {
|
||||
NonZero,
|
||||
EvenOdd
|
||||
};
|
||||
|
||||
enum class Units
|
||||
{
|
||||
enum class Units {
|
||||
UserSpaceOnUse,
|
||||
ObjectBoundingBox
|
||||
};
|
||||
|
||||
enum class SpreadMethod
|
||||
{
|
||||
enum class SpreadMethod {
|
||||
Pad,
|
||||
Reflect,
|
||||
Repeat
|
||||
};
|
||||
|
||||
enum class MarkerUnits
|
||||
{
|
||||
enum class MarkerUnits {
|
||||
StrokeWidth,
|
||||
UserSpaceOnUse
|
||||
};
|
||||
|
||||
class Color
|
||||
{
|
||||
class Color {
|
||||
public:
|
||||
Color() = default;
|
||||
explicit Color(uint32_t value) : m_value(value) {}
|
||||
|
@ -92,8 +82,7 @@ private:
|
|||
uint32_t m_value{0};
|
||||
};
|
||||
|
||||
class Paint
|
||||
{
|
||||
class Paint {
|
||||
public:
|
||||
Paint() = default;
|
||||
Paint(const Color& color);
|
||||
|
@ -108,8 +97,7 @@ public:
|
|||
Color m_color{Color::Transparent};
|
||||
};
|
||||
|
||||
class Point
|
||||
{
|
||||
class Point {
|
||||
public:
|
||||
Point() = default;
|
||||
Point(double x, double y);
|
||||
|
@ -123,8 +111,7 @@ using PointList = std::vector<Point>;
|
|||
|
||||
class Box;
|
||||
|
||||
class Rect
|
||||
{
|
||||
class Rect {
|
||||
public:
|
||||
Rect() = default;
|
||||
Rect(double x, double y, double w, double h);
|
||||
|
@ -151,8 +138,7 @@ public:
|
|||
|
||||
class Matrix;
|
||||
|
||||
class Transform
|
||||
{
|
||||
class Transform {
|
||||
public:
|
||||
Transform() = default;
|
||||
Transform(double m00, double m10, double m01, double m11, double m02, double m12);
|
||||
|
@ -193,16 +179,14 @@ public:
|
|||
double m12{0};
|
||||
};
|
||||
|
||||
enum class PathCommand
|
||||
{
|
||||
enum class PathCommand {
|
||||
MoveTo,
|
||||
LineTo,
|
||||
CubicTo,
|
||||
Close
|
||||
};
|
||||
|
||||
class Path
|
||||
{
|
||||
class Path {
|
||||
public:
|
||||
Path() = default;
|
||||
|
||||
|
@ -229,8 +213,7 @@ private:
|
|||
std::vector<Point> m_points;
|
||||
};
|
||||
|
||||
class PathIterator
|
||||
{
|
||||
class PathIterator {
|
||||
public:
|
||||
PathIterator(const Path& path);
|
||||
|
||||
|
@ -245,8 +228,7 @@ private:
|
|||
unsigned int m_index{0};
|
||||
};
|
||||
|
||||
enum class LengthUnits
|
||||
{
|
||||
enum class LengthUnits {
|
||||
Unknown,
|
||||
Number,
|
||||
Px,
|
||||
|
@ -260,8 +242,7 @@ enum class LengthUnits
|
|||
Percent
|
||||
};
|
||||
|
||||
enum LengthMode
|
||||
{
|
||||
enum LengthMode {
|
||||
Width,
|
||||
Height,
|
||||
Both
|
||||
|
@ -269,8 +250,7 @@ enum LengthMode
|
|||
|
||||
class Element;
|
||||
|
||||
class Length
|
||||
{
|
||||
class Length {
|
||||
public:
|
||||
Length() = default;
|
||||
Length(double value);
|
||||
|
@ -299,8 +279,7 @@ private:
|
|||
|
||||
using LengthList = std::vector<Length>;
|
||||
|
||||
class LengthContext
|
||||
{
|
||||
class LengthContext {
|
||||
public:
|
||||
LengthContext(const Element* element);
|
||||
LengthContext(const Element* element, Units units);
|
||||
|
@ -312,8 +291,7 @@ private:
|
|||
Units m_units{Units::UserSpaceOnUse};
|
||||
};
|
||||
|
||||
enum class Align
|
||||
{
|
||||
enum class Align {
|
||||
None,
|
||||
xMinYMin,
|
||||
xMidYMin,
|
||||
|
@ -326,14 +304,12 @@ enum class Align
|
|||
xMaxYMax
|
||||
};
|
||||
|
||||
enum class MeetOrSlice
|
||||
{
|
||||
enum class MeetOrSlice {
|
||||
Meet,
|
||||
Slice
|
||||
};
|
||||
|
||||
class PreserveAspectRatio
|
||||
{
|
||||
class PreserveAspectRatio {
|
||||
public:
|
||||
PreserveAspectRatio() = default;
|
||||
PreserveAspectRatio(Align align, MeetOrSlice scale);
|
||||
|
@ -349,14 +325,12 @@ private:
|
|||
MeetOrSlice m_scale{MeetOrSlice::Meet};
|
||||
};
|
||||
|
||||
enum class MarkerOrient
|
||||
{
|
||||
enum class MarkerOrient {
|
||||
Auto,
|
||||
Angle
|
||||
};
|
||||
|
||||
class Angle
|
||||
{
|
||||
class Angle {
|
||||
public:
|
||||
Angle() = default;
|
||||
Angle(MarkerOrient type);
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
class StopElement : public StyledElement
|
||||
{
|
||||
class StopElement : public StyledElement {
|
||||
public:
|
||||
StopElement();
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
class StyledElement : public Element
|
||||
{
|
||||
class StyledElement : public Element {
|
||||
public:
|
||||
StyledElement(ElementID id);
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
class StyleElement : public Element
|
||||
{
|
||||
class StyleElement : public Element {
|
||||
public:
|
||||
StyleElement();
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@ namespace lunasvg {
|
|||
class TreeBuilder;
|
||||
class LayoutSymbol;
|
||||
|
||||
class SVGElement : public GraphicsElement
|
||||
{
|
||||
class SVGElement : public GraphicsElement {
|
||||
public:
|
||||
SVGElement();
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
class SymbolElement : public StyledElement
|
||||
{
|
||||
class SymbolElement : public StyledElement {
|
||||
public:
|
||||
SymbolElement();
|
||||
|
||||
|
|
|
@ -77,14 +77,11 @@ void UseElement::layout(LayoutContext* context, LayoutContainer* current) const
|
|||
transform += ')';
|
||||
group->set(PropertyID::Transform, transform, 0x10);
|
||||
|
||||
if(ref->id == ElementID::Svg || ref->id == ElementID::Symbol)
|
||||
{
|
||||
if(ref->id == ElementID::Svg || ref->id == ElementID::Symbol) {
|
||||
auto element = ref->cloneElement<SVGElement>();
|
||||
transferWidthAndHeight(element.get());
|
||||
group->addChild(std::move(element));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
group->addChild(ref->clone());
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
namespace lunasvg {
|
||||
|
||||
class UseElement : public GraphicsElement
|
||||
{
|
||||
class UseElement : public GraphicsElement {
|
||||
public:
|
||||
UseElement();
|
||||
|
||||
|
|
Loading…
Reference in a new issue