aboutsummaryrefslogtreecommitdiffstats
path: root/include/litehtml/css_length.h
blob: 235ff54580a08217031587bc7aec9483f6306d42 (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
#ifndef LH_CSS_LENGTH_H
#define LH_CSS_LENGTH_H

#include "types.h"
#include "css_tokenizer.h"

namespace litehtml
{
	// from_token options (flags)
	enum {
		f_length     = 1, // <length> (includes unitless zero)
		f_percentage = 2, // <percentage>
		f_length_percentage = f_length | f_percentage, // <length-percentage>
		f_number     = 4, // <number>
		f_integer    = 8, // <integer>
		f_positive   = 16 // ⩾0 (non-negative)
	};

	// <length> | <percentage> | <number> | auto | none | normal
	// https://developer.mozilla.org/en-US/docs/Web/CSS/length
	class css_length
	{
		union
		{
			float	m_value;
			int		m_predef;
		};
		css_units	m_units;
		bool		m_is_predefined;
	public:
		css_length();
		css_length(float val, css_units units = css_units_px);
		css_length&	operator=(float val);

		bool		is_predefined() const;
		void		predef(int val);
		int			predef() const;
		static css_length predef_value(int val = 0);
		void		set_value(float val, css_units units);
		float		val() const;
		css_units	units() const;
		int			calc_percent(int width) const;
		bool		from_token(const css_token& token, int options, const string& predefined_keywords = "");
		string		to_string() const;
	};

	using length_vector = vector<css_length>;

	// css_length inlines

	inline css_length::css_length()
	{
		m_value			= 0;
		m_predef		= 0;
		m_units			= css_units_none;
		m_is_predefined	= false;
	}

	inline css_length::css_length(float val, css_units units)
	{
		m_value = val;
		m_units = units;
		m_is_predefined = false;
	}

	inline css_length&	css_length::operator=(float val)
	{
		m_value = val;
		m_units = css_units_px;
		m_is_predefined = false;
		return *this;
	}

	inline bool css_length::is_predefined() const
	{ 
		return m_is_predefined;					
	}

	inline void css_length::predef(int val)		
	{ 
		m_predef		= val; 
		m_is_predefined = true;	
	}

	inline int css_length::predef() const
	{ 
		if(m_is_predefined)
		{
			return m_predef; 
		}
		return 0;
	}

	inline void css_length::set_value(float val, css_units units)
	{ 
		m_value			= val; 
		m_is_predefined = false;	
		m_units			= units;
	}

	inline float css_length::val() const
	{
		if(!m_is_predefined)
		{
			return m_value;
		}
		return 0;
	}

	inline css_units css_length::units() const
	{
		return m_units;
	}

	inline int css_length::calc_percent(int width) const
	{
		if(!is_predefined())
		{
			if(units() == css_units_percentage)
			{
				return (int) ((double) width * (double) m_value / 100.0);
			} else
			{
				return (int) val();
			}
		}
		return 0;
	}
}

#endif  // LH_CSS_LENGTH_H