Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 65128c3

Browse filesBrowse files
authored
Updated inline layout rendering (#389)
* Added subscripts/superscripts baseline shift to the font_metrics * Improved rendering of inline elements with top and bottom vertical align * Improved rendering of the line-height property
1 parent baad157 commit 65128c3
Copy full SHA for 65128c3
Expand file treeCollapse file tree

15 files changed

+379
-200
lines changed

‎CMakeLists.txt

Copy file name to clipboardExpand all lines: CMakeLists.txt
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ else ()
199199
ExternalProject_Add(
200200
litehtml-tests
201201
GIT_REPOSITORY https://github.com/litehtml/litehtml-tests.git
202-
GIT_TAG 1893e7b9f4f7a3e316c79795b29248fc0e761ef2
202+
GIT_TAG e90547605bda845c1b953232b1c2b3645928eac2
203203
SOURCE_DIR "${CMAKE_BINARY_DIR}/litehtml-tests-src"
204204
BINARY_DIR "${CMAKE_BINARY_DIR}/litehtml-tests-build"
205205
CMAKE_ARGS -DLITEHTML_PATH=${CMAKE_CURRENT_SOURCE_DIR}

‎containers/cairo/container_cairo_pango.cpp

Copy file name to clipboardExpand all lines: containers/cairo/container_cairo_pango.cpp
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ litehtml::uint_ptr container_cairo_pango::create_font(const char *faceName, int
9898
fm->descent = PANGO_PIXELS((double)pango_font_metrics_get_descent(metrics));
9999
fm->height = PANGO_PIXELS((double)pango_font_metrics_get_height(metrics));
100100
fm->x_height = fm->height;
101+
fm->draw_spaces = (decoration != litehtml::font_decoration_none);
102+
fm->sub_shift = size / 5;
103+
fm->super_shift = size / 3;
101104

102105
pango_layout_set_text(layout, "x", 1);
103106

‎include/litehtml/css_properties.h

Copy file name to clipboardExpand all lines: include/litehtml/css_properties.h
+19-7Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ namespace litehtml
1313
class html_tag;
1414
class document;
1515

16+
template<class CssT, class CompT>
17+
class css_property
18+
{
19+
public:
20+
CssT css_value;
21+
CompT computed_value;
22+
23+
css_property(const CssT& css_val, const CompT& computed_val) : css_value(css_val), computed_value(computed_val) {}
24+
};
25+
26+
// CSS Properties types
27+
using css_line_height_t = css_property<css_length, int>;
28+
1629
class css_properties
1730
{
1831
private:
@@ -40,7 +53,7 @@ namespace litehtml
4053
css_offsets m_css_offsets;
4154
css_length m_css_text_indent;
4255
css_length m_css_line_height;
43-
int m_line_height;
56+
css_line_height_t m_line_height {{}, 0};
4457
list_style_type m_list_style_type;
4558
list_style_position m_list_style_position;
4659
string m_list_style_image;
@@ -107,7 +120,6 @@ namespace litehtml
107120
m_css_offsets(),
108121
m_css_text_indent(),
109122
m_css_line_height(0),
110-
m_line_height(0),
111123
m_list_style_type(list_style_type_none),
112124
m_list_style_position(list_style_position_outside),
113125
m_bg(),
@@ -201,8 +213,8 @@ namespace litehtml
201213
const css_length &get_text_indent() const;
202214
void set_text_indent(const css_length &mCssTextIndent);
203215

204-
int get_line_height() const;
205-
void set_line_height(int mLineHeight);
216+
const css_line_height_t& line_height() const;
217+
css_line_height_t& line_height_w();
206218

207219
list_style_type get_list_style_type() const;
208220
void set_list_style_type(list_style_type mListStyleType);
@@ -496,14 +508,14 @@ namespace litehtml
496508
m_css_text_indent = mCssTextIndent;
497509
}
498510

499-
inline int css_properties::get_line_height() const
511+
inline const css_line_height_t& css_properties::line_height() const
500512
{
501513
return m_line_height;
502514
}
503515

504-
inline void css_properties::set_line_height(int mLineHeight)
516+
inline css_line_height_t& css_properties::line_height_w()
505517
{
506-
m_line_height = mLineHeight;
518+
return m_line_height;
507519
}
508520

509521
inline list_style_type css_properties::get_list_style_type() const

‎include/litehtml/el_style.h

Copy file name to clipboardExpand all lines: include/litehtml/el_style.h
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace litehtml
1313

1414
void parse_attributes() override;
1515
bool appendChild(const ptr &el) override;
16+
void compute_styles(bool recursive) override;
1617
string_id tag() const override;
1718
const char* get_tagName() const override;
1819
};

‎include/litehtml/html.h

Copy file name to clipboardExpand all lines: include/litehtml/html.h
+3-8Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,10 @@ namespace litehtml
3636
double t_strtod(const char* string, char** endPtr = nullptr);
3737
string get_escaped_string(const string& in_str);
3838

39-
template<typename X, typename A>
40-
bool is_one_of(X x, A a)
39+
template<typename T, typename... Opts>
40+
bool is_one_of(T val, Opts ...opts)
4141
{
42-
return x == a;
43-
}
44-
template<typename X, typename A, typename... AA>
45-
bool is_one_of(X x, A a, AA... aa)
46-
{
47-
return x == a || is_one_of(x, aa...);
42+
return (... || (val == opts));
4843
}
4944
template<class T>
5045
const T& at(const vector<T>& vec, int index /*may be negative*/)

‎include/litehtml/line_box.h

Copy file name to clipboardExpand all lines: include/litehtml/line_box.h
+21-12Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ namespace litehtml
4040
};
4141
protected:
4242
std::shared_ptr<render_item> m_element;
43-
int m_rendered_min_width;
43+
int m_rendered_min_width = 0;
44+
int m_items_top = 0;
45+
int m_items_bottom = 0;
4446
public:
45-
explicit line_box_item(const std::shared_ptr<render_item>& element) : m_element(element), m_rendered_min_width(0) {}
46-
line_box_item() : m_element(), m_rendered_min_width(0) {};
47+
explicit line_box_item(const std::shared_ptr<render_item>& element) : m_element(element) {}
4748
line_box_item(const line_box_item& el) = default;
4849
line_box_item(line_box_item&&) = default;
4950
virtual ~line_box_item();
5051

51-
int height() const { return right() - left(); }
52+
virtual int height() const;
5253
const std::shared_ptr<render_item>& get_el() const { return m_element; }
5354
virtual position& pos();
5455
virtual void place_to(int x, int y);
@@ -60,6 +61,15 @@ namespace litehtml
6061
virtual element_type get_type() const { return type_text_part; }
6162
virtual int get_rendered_min_width() const { return m_rendered_min_width; }
6263
virtual void set_rendered_min_width(int min_width) { m_rendered_min_width = min_width; }
64+
65+
void reset_items_height() { m_items_top = m_items_bottom = 0; }
66+
void add_item_height(int item_top, int item_bottom)
67+
{
68+
m_items_top = std::min(m_items_top, item_top);
69+
m_items_bottom = std::max(m_items_bottom, item_bottom);
70+
}
71+
int get_items_top() const { return m_items_top; }
72+
int get_items_bottom() const { return m_items_bottom; }
6373
};
6474

6575
class lbi_start : public line_box_item
@@ -68,9 +78,10 @@ namespace litehtml
6878
position m_pos;
6979
public:
7080
explicit lbi_start(const std::shared_ptr<render_item>& element);
71-
virtual ~lbi_start() override;
81+
~lbi_start() override;
7282

7383
void place_to(int x, int y) override;
84+
int height() const override;
7485
int width() const override;
7586
position& pos() override { return m_pos; }
7687
int top() const override;
@@ -110,32 +121,30 @@ namespace litehtml
110121
{
111122
struct va_context
112123
{
113-
int baseline;
124+
int line_height = 0;
125+
int baseline = 0;
114126
font_metrics fm;
115-
116-
va_context() : baseline(0) {}
127+
line_box_item* start_lbi = nullptr;
117128
};
118129

119130
int m_top;
120131
int m_left;
121132
int m_right;
122133
int m_height;
123134
int m_width;
124-
int m_line_height;
125-
int m_default_line_height;
135+
css_line_height_t m_default_line_height;
126136
font_metrics m_font_metrics;
127137
int m_baseline;
128138
text_align m_text_align;
129139
int m_min_width;
130140
std::list< std::unique_ptr<line_box_item> > m_items;
131141
public:
132-
line_box(int top, int left, int right, int line_height, const font_metrics& fm, text_align align) :
142+
line_box(int top, int left, int right, const css_line_height_t& line_height, const font_metrics& fm, text_align align) :
133143
m_top(top),
134144
m_left(left),
135145
m_right(right),
136146
m_height(0),
137147
m_width(0),
138-
m_line_height(0),
139148
m_default_line_height(line_height),
140149
m_font_metrics(fm),
141150
m_baseline(0),

‎include/litehtml/types.h

Copy file name to clipboardExpand all lines: include/litehtml/types.h
+10-18Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -195,24 +195,16 @@ namespace litehtml
195195

196196
struct font_metrics
197197
{
198-
int font_size;
199-
int height;
200-
int ascent;
201-
int descent;
202-
int x_height;
203-
int ch_width;
204-
bool draw_spaces;
205-
206-
font_metrics()
207-
{
208-
font_size = 0;
209-
height = 0;
210-
ascent = 0;
211-
descent = 0;
212-
x_height = 0;
213-
ch_width = 0;
214-
draw_spaces = true;
215-
}
198+
int font_size = 0; // Font size in pixels. The same as size argument of the create_font function
199+
int height = 0; // Font height in pixels.
200+
int ascent = 0; // The distance from the baseline to the top of a line of text.
201+
int descent = 0; // The distance from the baseline to the bottom of a line of text.
202+
int x_height = 0; // Height of the symbol x
203+
int ch_width = 0; // Height of the symbol 0
204+
bool draw_spaces = true; // True to call draw text function for spaces. If False, just use space width without draw.
205+
int sub_shift = 0; // The baseline shift for subscripts.
206+
int super_shift = 0; // The baseline shift for superscripts.
207+
216208
int base_line() const { return descent; }
217209
};
218210

‎src/css_properties.cpp

Copy file name to clipboardExpand all lines: src/css_properties.cpp
+17-13Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <cmath>
44

55
#define offset(member) ((uint_ptr)&this->member - (uint_ptr)this)
6+
//#define offset(func) [](const css_properties& css) { return css.func; }
67

78
void litehtml::css_properties::compute(const html_tag* el, const document::ptr& doc)
89
{
@@ -98,6 +99,9 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr&
9899
{
99100
m_display = display_block;
100101
}
102+
} else if(el->is_replaced() && m_display == display_inline)
103+
{
104+
m_display = display_inline_block;
101105
}
102106
}
103107
// 5. Otherwise, the remaining 'display' property values apply as specified.
@@ -218,17 +222,17 @@ void litehtml::css_properties::compute(const html_tag* el, const document::ptr&
218222
m_css_text_indent = el->get_property<css_length>(_text_indent_, true, 0, offset(m_css_text_indent));
219223
doc->cvt_units(m_css_text_indent, m_font_metrics, 0);
220224

221-
m_css_line_height = el->get_property<css_length>(_line_height_, true, normal, offset(m_css_line_height));
222-
if(m_css_line_height.is_predefined())
225+
m_line_height.css_value = el->get_property<css_length>(_line_height_, true, normal, offset(m_line_height.css_value));
226+
if(m_line_height.css_value.is_predefined())
223227
{
224-
m_line_height = m_font_metrics.height;
225-
} else if(m_css_line_height.units() == css_units_none)
228+
m_line_height.computed_value = m_font_metrics.height;
229+
} else if(m_line_height.css_value.units() == css_units_none)
226230
{
227-
m_line_height = (int) std::nearbyint(m_css_line_height.val() * font_size);
231+
m_line_height.computed_value = (int) std::nearbyint(m_line_height.css_value.val() * font_size);
228232
} else
229233
{
230-
m_line_height = doc->to_pixels(m_css_line_height, m_font_metrics, m_font_metrics.font_size);
231-
m_css_line_height = (float) m_line_height;
234+
m_line_height.computed_value = doc->to_pixels(m_line_height.css_value, m_font_metrics, m_font_metrics.font_size);
235+
m_line_height.css_value = (float) m_line_height.computed_value;
232236
}
233237

234238
m_list_style_type = (list_style_type) el->get_property<int>(_list_style_type_, true, list_style_type_disc, offset(m_list_style_type));
@@ -282,7 +286,7 @@ void litehtml::css_properties::compute_font(const html_tag* el, const document::
282286
{
283287
parent_sz = doc_font_size;
284288
}
285-
289+
286290
int font_size = parent_sz;
287291

288292
if(sz.is_predefined())
@@ -348,7 +352,7 @@ void litehtml::css_properties::compute_font(const html_tag* el, const document::
348352
font_size = doc->to_pixels(sz, fm, 0);
349353
}
350354
}
351-
355+
352356
m_font_size = (float)font_size;
353357

354358
// initialize font
@@ -358,11 +362,11 @@ void litehtml::css_properties::compute_font(const html_tag* el, const document::
358362
m_text_decoration = el->get_property<string>( _text_decoration_, true, "none", offset(m_text_decoration));
359363

360364
m_font = doc->get_font(
361-
m_font_family.c_str(),
362-
font_size,
365+
m_font_family.c_str(),
366+
font_size,
363367
m_font_weight.is_predefined() ? index_value(m_font_weight.predef(), font_weight_strings).c_str() : std::to_string(m_font_weight.val()).c_str(),
364368
index_value(m_font_style, font_style_strings).c_str(),
365-
m_text_decoration.c_str(),
369+
m_text_decoration.c_str(),
366370
&m_font_metrics);
367371
}
368372

@@ -480,7 +484,7 @@ std::vector<std::tuple<litehtml::string, litehtml::string>> litehtml::css_proper
480484
ret.emplace_back("max_height", m_css_max_width.to_string());
481485
ret.emplace_back("offsets", m_css_offsets.to_string());
482486
ret.emplace_back("text_indent", m_css_text_indent.to_string());
483-
ret.emplace_back("line_height", std::to_string(m_line_height));
487+
ret.emplace_back("line_height", std::to_string(m_line_height.computed_value));
484488
ret.emplace_back("list_style_type", index_value(m_list_style_type, list_style_type_strings));
485489
ret.emplace_back("list_style_position", index_value(m_list_style_position, list_style_position_strings));
486490
ret.emplace_back("border_spacing_x", m_css_border_spacing_x.to_string());

‎src/el_style.cpp

Copy file name to clipboardExpand all lines: src/el_style.cpp
+11-2Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,17 @@ void litehtml::el_style::parse_attributes()
2121

2222
bool litehtml::el_style::appendChild(const ptr &el)
2323
{
24-
m_children.push_back(el);
25-
return true;
24+
if(el && el->is_text())
25+
{
26+
m_children.push_back(el);
27+
return true;
28+
}
29+
return false;
30+
}
31+
32+
void litehtml::el_style::compute_styles(bool /* recursive */)
33+
{
34+
css_w().set_display(display_none);
2635
}
2736

2837
litehtml::string_id litehtml::el_style::tag() const

‎src/el_text.cpp

Copy file name to clipboardExpand all lines: src/el_text.cpp
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void litehtml::el_text::compute_styles(bool /*recursive*/)
2828
element::ptr el_parent = parent();
2929
if (el_parent)
3030
{
31-
css_w().set_line_height(el_parent->css().get_line_height());
31+
css_w().line_height_w() = el_parent->css().line_height();
3232
css_w().set_font(el_parent->css().get_font());
3333
css_w().set_font_metrics(el_parent->css().get_font_metrics());
3434
css_w().set_white_space(el_parent->css().get_white_space());

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.