aboutsummaryrefslogtreecommitdiffstats
path: root/include/litehtml/background.h
blob: 51db39d0056d1135d76e940ab8c2e6846e060a21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#ifndef LH_BACKGROUND_H
#define LH_BACKGROUND_H

#include "types.h"
#include "css_length.h"
#include "css_position.h"
#include "web_color.h"
#include "borders.h"
#include "gradient.h"

namespace litehtml
{
	class background_layer
	{
	public:
		// border_box defines draw boundary. Everything must be drawn inside this rectangle only.
		position border_box;
		// border_radius defines radius of the border_box.
		border_radiuses border_radius;
		// clip_box defines clipping rectangle. Works like border_box. Container must set additional clipping.
		position clip_box;
		// origin_box defines origin rectangle.
		position origin_box;
		background_attachment attachment;
		background_repeat repeat;
		// is_root is true for root element. Container can use this flag to apply background to the top window.
		bool is_root;

		background_layer() :
				attachment(background_attachment_scroll),
				repeat(background_repeat_repeat),
				is_root(false)
				{}

		class image
		{
		public:
			string url;
			string base_url;
		};

		struct color_point
		{
			float offset;
			web_color color;
			optional<float> hint;
			color_point() { offset = 0.0; }
			color_point(float _offset, web_color _color) : offset(_offset), color(_color) {}
		};

		class color
		{
		public:
			web_color color;
		};

		class gradient_base
		{
		public:
			vector<color_point>  color_points;
			color_space_t        color_space       = color_space_none;
			hue_interpolation_t  hue_interpolation = hue_interpolation_none;

			void color_points_transparent_fix();
			bool prepare_color_points(float len, string_id grad_type, const vector<gradient::color_stop>& colors);
		};

		class linear_gradient : public gradient_base
		{
		public:
			pointF start;
			pointF end;
		};

		class radial_gradient : public gradient_base
		{
		public:
			pointF position;
			pointF radius;
		};

		class conic_gradient : public gradient_base
		{
		public:
			pointF position; // position is the center of the conic gradient
			float angle = 0; // angle is the angle of the gradient in degrees, starting from 0 at the top and going clockwise
			float radius = 0; // radius is the distance from the center to the farthest corner of the background box
		};
	};

	class background
	{
	public:
		enum layer_type
		{
			type_none,
			type_color,
			type_image,
			type_linear_gradient,
			type_radial_gradient,
			type_conic_gradient,
		};

		vector<image>			m_image;
		string					m_baseurl;
		web_color				m_color;
		int_vector				m_attachment;
		length_vector			m_position_x;
		length_vector			m_position_y;
		size_vector				m_size;
		int_vector				m_repeat;
		int_vector				m_clip;
		int_vector				m_origin;

		bool is_empty() const
		{
			if(m_color.alpha != 0)
				return false;
			if(m_image.empty())
				return true;
			for(const auto& img : m_image)
			{
				if(!img.is_empty()) return false;
			}
			return true;
		}
		int get_layers_number() const
		{
			if(m_color != web_color::transparent)
			{
				return (int) m_image.size() + 1;
			}
			return (int) m_image.size();
		}
		bool get_layer(int idx, position pos, const element* el, const std::shared_ptr<render_item>& ri, background_layer& layer) const;
		layer_type get_layer_type(int idx) const;
		std::unique_ptr<background_layer::image> get_image_layer(int idx) const;
		std::unique_ptr<background_layer::color> get_color_layer(int idx) const;
		std::unique_ptr<background_layer::linear_gradient> get_linear_gradient_layer(int idx, const background_layer& layer) const;
		std::unique_ptr<background_layer::radial_gradient> get_radial_gradient_layer(int idx, const background_layer& layer) const;
		std::unique_ptr<background_layer::conic_gradient> get_conic_gradient_layer(int idx, const background_layer& layer) const;
		void draw_layer(uint_ptr hdc, int idx, const background_layer& layer, document_container* container) const;
	};
}

#endif  // LH_BACKGROUND_H