Skip to content

Commit e2c19d3

Browse files
committed
1 parent ae62afb commit e2c19d3

File tree

5 files changed

+263
-95
lines changed

5 files changed

+263
-95
lines changed

containers/cairo/cairo_container.cpp

Lines changed: 85 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
cairo_container::cairo_container(void)
77
{
8-
m_temp_dib.create(1, 1, true);
9-
m_font_link = NULL;
8+
m_temp_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2, 2);
9+
m_temp_cr = cairo_create(m_temp_surface);
10+
m_font_link = NULL;
1011
CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_ALL, IID_IMLangFontLink2, (void**) &m_font_link);
1112
}
1213

@@ -17,6 +18,8 @@ cairo_container::~cairo_container(void)
1718
{
1819
m_font_link->Release();
1920
}
21+
cairo_surface_destroy(m_temp_surface);
22+
cairo_destroy(m_temp_cr);
2023
}
2124

2225
litehtml::uint_ptr cairo_container::create_font( const wchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm )
@@ -35,15 +38,17 @@ litehtml::uint_ptr cairo_container::create_font( const wchar_t* faceName, int si
3538

3639
if(fm)
3740
{
38-
cairo_dev cr(&m_temp_dib);
41+
cairo_save(m_temp_cr);
3942

4043
cairo_font_metrics cfm;
41-
fnt->get_metrics(cr, &cfm);
44+
fnt->get_metrics(m_temp_cr, &cfm);
4245

4346
fm->ascent = cfm.ascent;
4447
fm->descent = cfm.descent;
4548
fm->height = cfm.height;
4649
fm->x_height = cfm.x_height;
50+
51+
cairo_restore(m_temp_cr);
4752
}
4853

4954
return (litehtml::uint_ptr) fnt;
@@ -61,15 +66,19 @@ void cairo_container::delete_font( litehtml::uint_ptr hFont )
6166
int cairo_container::text_width( const wchar_t* text, litehtml::uint_ptr hFont )
6267
{
6368
cairo_font* fnt = (cairo_font*) hFont;
64-
cairo_dev cr(&m_temp_dib);
65-
66-
return fnt->text_width(cr, text);
69+
70+
cairo_save(m_temp_cr);
71+
int ret = fnt->text_width(m_temp_cr, text);
72+
cairo_restore(m_temp_cr);
73+
return ret;
6774
}
6875

6976
void cairo_container::draw_text( litehtml::uint_ptr hdc, const wchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos )
7077
{
7178
cairo_font* fnt = (cairo_font*) hFont;
72-
cairo_dev cr(get_dib(hdc));
79+
cairo_t* cr = (cairo_t*) hdc;
80+
cairo_save(cr);
81+
7382
apply_clip(cr);
7483

7584
cairo_font_metrics cfm;
@@ -78,15 +87,18 @@ void cairo_container::draw_text( litehtml::uint_ptr hdc, const wchar_t* text, li
7887
int x = pos.left();
7988
int y = pos.bottom() - cfm.descent;
8089

81-
cr.set_color(color);
90+
set_color(cr, color);
8291
fnt->show_text(cr, x, y, text);
92+
93+
cairo_restore(cr);
8394
}
8495

8596
void cairo_container::fill_rect( litehtml::uint_ptr hdc, const litehtml::position& pos, const litehtml::web_color color, const litehtml::css_border_radius& radius )
8697
{
8798
if(hdc)
8899
{
89-
cairo_dev cr( get_dib(hdc) );
100+
cairo_t* cr = (cairo_t*) hdc;
101+
cairo_save(cr);
90102
apply_clip(cr);
91103

92104
if(radius.top_left_x.val())
@@ -118,8 +130,9 @@ void cairo_container::fill_rect( litehtml::uint_ptr hdc, const litehtml::positio
118130
cairo_arc(cr, pos.left() + radius.bottom_left_x.val(), pos.bottom() - radius.bottom_left_x.val(), radius.bottom_left_x.val(), M_PI / 2.0, M_PI);
119131
}
120132

121-
cr.set_color(color);
133+
set_color(cr, color);
122134
cairo_fill(cr);
135+
cairo_restore(cr);
123136
}
124137
}
125138

@@ -149,12 +162,12 @@ void cairo_container::draw_list_marker( litehtml::uint_ptr hdc, litehtml::list_s
149162
{
150163
case litehtml::list_style_type_circle:
151164
{
152-
draw_ellipse(get_dib(hdc), draw_x, draw_y, draw_width, draw_height, color, 1);
165+
draw_ellipse((cairo_t*) hdc, draw_x, draw_y, draw_width, draw_height, color, 1);
153166
}
154167
break;
155168
case litehtml::list_style_type_disc:
156169
{
157-
fill_ellipse(get_dib(hdc), draw_x, draw_y, draw_width, draw_height, color);
170+
fill_ellipse((cairo_t*) hdc, draw_x, draw_y, draw_width, draw_height, color);
158171
}
159172
break;
160173
case litehtml::list_style_type_square:
@@ -194,21 +207,24 @@ void cairo_container::get_image_size( const wchar_t* src, const wchar_t* baseurl
194207

195208
void cairo_container::draw_image( litehtml::uint_ptr hdc, const wchar_t* src, const wchar_t* baseurl, const litehtml::position& pos )
196209
{
197-
cairo_dev cr(get_dib(hdc));
210+
cairo_t* cr = (cairo_t*) hdc;
211+
cairo_save(cr);
198212
apply_clip(cr);
199213

200214
std::wstring url;
201215
make_url(src, baseurl, url);
202216
images_map::iterator img = m_images.find(url.c_str());
203217
if(img != m_images.end())
204218
{
205-
cr.draw_image(img->second, pos.x, pos.y, pos.width, pos.height);
219+
draw_txdib(cr, img->second, pos.x, pos.y, pos.width, pos.height);
206220
}
221+
cairo_restore(cr);
207222
}
208223

209224
void cairo_container::draw_background( litehtml::uint_ptr hdc, const wchar_t* image, const wchar_t* baseurl, const litehtml::position& draw_pos, const litehtml::css_position& bg_pos, litehtml::background_repeat repeat, litehtml::background_attachment attachment )
210225
{
211-
cairo_dev cr(get_dib(hdc));
226+
cairo_t* cr = (cairo_t*) hdc;
227+
cairo_save(cr);
212228
apply_clip(cr);
213229

214230
cairo_rectangle(cr, draw_pos.x, draw_pos.y, draw_pos.width, draw_pos.height);
@@ -257,7 +273,7 @@ void cairo_container::draw_background( litehtml::uint_ptr hdc, const wchar_t* im
257273
switch(repeat)
258274
{
259275
case litehtml::background_repeat_no_repeat:
260-
cr.draw_image(bgbmp, bg_x, bg_y, bgbmp->getWidth(), bgbmp->getHeight());
276+
draw_txdib(cr, bgbmp, bg_x, bg_y, bgbmp->getWidth(), bgbmp->getHeight());
261277
break;
262278

263279
case litehtml::background_repeat_repeat_x:
@@ -282,6 +298,7 @@ void cairo_container::draw_background( litehtml::uint_ptr hdc, const wchar_t* im
282298
cairo_pattern_destroy(pattern);
283299
cairo_surface_destroy(img);
284300
}
301+
cairo_restore(cr);
285302
}
286303

287304
void cairo_container::add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg)
@@ -312,7 +329,8 @@ void cairo_container::add_path_arc(cairo_t* cr, double x, double y, double rx, d
312329

313330
void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_borders& borders, const litehtml::position& draw_pos )
314331
{
315-
cairo_dev cr(get_dib(hdc));
332+
cairo_t* cr = (cairo_t*) hdc;
333+
cairo_save(cr);
316334
apply_clip(cr);
317335

318336
int bdr_top = 0;
@@ -340,7 +358,7 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
340358
// draw right border
341359
if(bdr_right)
342360
{
343-
cr.set_color(borders.right.color);
361+
set_color(cr, borders.right.color);
344362

345363
double r_top = borders.radius.top_right_x.val();
346364
double r_bottom = borders.radius.bottom_right_x.val();
@@ -405,7 +423,7 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
405423
// draw bottom border
406424
if(bdr_bottom)
407425
{
408-
cr.set_color(borders.bottom.color);
426+
set_color(cr, borders.bottom.color);
409427

410428
double r_left = borders.radius.bottom_left_x.val();
411429
double r_right = borders.radius.bottom_right_x.val();
@@ -470,7 +488,7 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
470488
// draw top border
471489
if(bdr_top)
472490
{
473-
cr.set_color(borders.top.color);
491+
set_color(cr, borders.top.color);
474492

475493
double r_left = borders.radius.top_left_x.val();
476494
double r_right = borders.radius.top_right_x.val();
@@ -535,7 +553,7 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
535553
// draw left border
536554
if(bdr_left)
537555
{
538-
cr.set_color(borders.left.color);
556+
set_color(cr, borders.left.color);
539557

540558
double r_top = borders.radius.top_left_x.val();
541559
double r_bottom = borders.radius.bottom_left_x.val();
@@ -596,6 +614,7 @@ void cairo_container::draw_borders( litehtml::uint_ptr hdc, const litehtml::css_
596614

597615
cairo_fill(cr);
598616
}
617+
cairo_restore(cr);
599618
}
600619

601620
wchar_t cairo_container::toupper( const wchar_t c )
@@ -647,35 +666,39 @@ void cairo_container::apply_clip( cairo_t* cr )
647666
}
648667
}
649668

650-
void cairo_container::draw_ellipse( simpledib::dib* dib, int x, int y, int width, int height, const litehtml::web_color& color, int line_width )
669+
void cairo_container::draw_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width )
651670
{
652-
if(!dib) return;
671+
if(!cr) return;
672+
cairo_save(cr);
653673

654-
cairo_dev cr(dib);
655674
apply_clip(cr);
656675

657676
cairo_translate (cr, x + width / 2.0, y + height / 2.0);
658677
cairo_scale (cr, width / 2.0, height / 2.0);
659678
cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
660679

661-
cr.set_color(color);
680+
set_color(cr, color);
662681
cairo_set_line_width(cr, line_width);
663682
cairo_stroke(cr);
683+
684+
cairo_restore(cr);
664685
}
665686

666-
void cairo_container::fill_ellipse( simpledib::dib* dib, int x, int y, int width, int height, const litehtml::web_color& color )
687+
void cairo_container::fill_ellipse( cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color )
667688
{
668-
if(!dib) return;
689+
if(!cr) return;
690+
cairo_save(cr);
669691

670-
cairo_dev cr(dib);
671692
apply_clip(cr);
672693

673694
cairo_translate (cr, x + width / 2.0, y + height / 2.0);
674695
cairo_scale (cr, width / 2.0, height / 2.0);
675696
cairo_arc (cr, 0, 0, 1, 0, 2 * M_PI);
676697

677-
cr.set_color(color);
698+
set_color(cr, color);
678699
cairo_fill(cr);
700+
701+
cairo_restore(cr);
679702
}
680703

681704
void cairo_container::clear_images()
@@ -695,6 +718,38 @@ const wchar_t* cairo_container::get_default_font_name()
695718
return L"Times New Roman";
696719
}
697720

721+
void cairo_container::draw_txdib( cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy )
722+
{
723+
cairo_save(cr);
724+
725+
cairo_matrix_t flib_m;
726+
cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0);
727+
728+
cairo_surface_t* img = NULL;
729+
730+
CTxDIB rbmp;
731+
732+
if(cx != bmp->getWidth() || cy != bmp->getHeight())
733+
{
734+
bmp->resample(cx, cy, &rbmp);
735+
img = cairo_image_surface_create_for_data((unsigned char*) rbmp.getBits(), CAIRO_FORMAT_ARGB32, rbmp.getWidth(), rbmp.getHeight(), rbmp.getWidth() * 4);
736+
cairo_matrix_translate(&flib_m, 0, -rbmp.getHeight());
737+
cairo_matrix_translate(&flib_m, x, -y);
738+
} else
739+
{
740+
img = cairo_image_surface_create_for_data((unsigned char*) bmp->getBits(), CAIRO_FORMAT_ARGB32, bmp->getWidth(), bmp->getHeight(), bmp->getWidth() * 4);
741+
cairo_matrix_translate(&flib_m, 0, -bmp->getHeight());
742+
cairo_matrix_translate(&flib_m, x, -y);
743+
}
744+
745+
cairo_transform(cr, &flib_m);
746+
cairo_set_source_surface(cr, img, 0, 0);
747+
cairo_paint(cr);
748+
749+
cairo_restore(cr);
750+
cairo_surface_destroy(img);
751+
}
752+
698753
//////////////////////////////////////////////////////////////////////////
699754

700755
cairo_dev::cairo_dev( simpledib::dib* dib )

containers/cairo/cairo_container.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ class cairo_container : public litehtml::document_container
3535
typedef std::map<std::wstring, CTxDIB*> images_map;
3636

3737
protected:
38-
simpledib::dib m_temp_dib;
38+
cairo_surface_t* m_temp_surface;
39+
cairo_t* m_temp_cr;
3940
images_map m_images;
4041
litehtml::position::vector m_clips;
4142
IMLangFontLink2* m_font_link;
@@ -72,14 +73,17 @@ class cairo_container : public litehtml::document_container
7273
virtual void make_url( LPCWSTR url, LPCWSTR basepath, std::wstring& out ) = 0;
7374
virtual CTxDIB* get_image(LPCWSTR url) = 0;
7475
virtual void get_client_rect(litehtml::position& client) = 0;
76+
void clear_images();
7577

7678
protected:
77-
virtual void draw_ellipse(simpledib::dib* dib, int x, int y, int width, int height, const litehtml::web_color& color, int line_width);
78-
virtual void fill_ellipse(simpledib::dib* dib, int x, int y, int width, int height, const litehtml::web_color& color);
79+
virtual void draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width);
80+
virtual void fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color);
7981

8082
private:
8183
simpledib::dib* get_dib(litehtml::uint_ptr hdc) { return (simpledib::dib*) hdc; }
8284
void apply_clip(cairo_t* cr);
83-
void clear_images();
8485
void add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg);
86+
87+
void set_color(cairo_t* cr, litehtml::web_color color) { cairo_set_source_rgba(cr, color.red / 255.0, color.green / 255.0, color.blue / 255.0, color.alpha / 255.0); }
88+
void draw_txdib(cairo_t* cr, CTxDIB* bmp, int x, int y, int cx, int cy);
8589
};

litehtml/el_table.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ int litehtml::el_table::render( int x, int y, int max_width )
314314
m_pos.width = table_width;
315315
m_pos.height = top;
316316

317-
return min_table_width;
317+
return table_width;//min_table_width;
318318
}
319319

320320
bool litehtml::el_table::appendChild( litehtml::element* el )

0 commit comments

Comments
 (0)