[Commits] [SCM] claws branch, master, updated. 3.17.3-104-g79df8ad

ticho at claws-mail.org ticho at claws-mail.org
Tue Feb 26 00:08:27 CET 2019


The branch, master has been updated
       via  79df8adbfee87e42bd4ca6071537619289de85b5 (commit)
      from  33f351e459af8e4d203a646a649e9ab18d659ae2 (commit)

Summary of changes:
 src/plugins/litehtml_viewer/Makefile.am         |    1 +
 src/plugins/litehtml_viewer/container_linux.cpp |  163 -----------------------
 src/plugins/litehtml_viewer/container_linux.h   |   16 +--
 src/plugins/litehtml_viewer/lh_widget.h         |   14 +-
 src/plugins/litehtml_viewer/lh_widget_text.cpp  |  142 ++++++++++++++++++++
 5 files changed, 158 insertions(+), 178 deletions(-)
 create mode 100644 src/plugins/litehtml_viewer/lh_widget_text.cpp


- Log -----------------------------------------------------------------
commit 79df8adbfee87e42bd4ca6071537619289de85b5
Author: Andrej Kacian <ticho at claws-mail.org>
Date:   Mon Feb 25 23:19:24 2019 +0100

    Use Pango to render text in Litehtml plugin
    
    Since we're no longer using the "toy" cairo text API, we
    can now render all Unicode glyphs, and the code even ends
    up slightly simpler.
    
    The text-related Litehtml callbacks have been moved from
    container_linux to lh_widget class, and into a separate
    .cpp file.

diff --git a/src/plugins/litehtml_viewer/Makefile.am b/src/plugins/litehtml_viewer/Makefile.am
index d603a30..81ce766 100644
--- a/src/plugins/litehtml_viewer/Makefile.am
+++ b/src/plugins/litehtml_viewer/Makefile.am
@@ -44,6 +44,7 @@ litehtml_viewer_la_SOURCES = \
 	lh_prefs.c \
 	lh_viewer.c \
 	lh_widget.cpp \
+	lh_widget_text.cpp \
 	container_linux.h \
 	lh_prefs.h \
 	lh_viewer.h \
diff --git a/src/plugins/litehtml_viewer/container_linux.cpp b/src/plugins/litehtml_viewer/container_linux.cpp
index a2b1908..15f8836 100644
--- a/src/plugins/litehtml_viewer/container_linux.cpp
+++ b/src/plugins/litehtml_viewer/container_linux.cpp
@@ -46,169 +46,6 @@ container_linux::~container_linux(void)
 	cairo_destroy(m_temp_cr);
 }
 
-litehtml::uint_ptr container_linux::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm )
-{
-	litehtml::string_vector fonts;
-	litehtml::split_string(faceName, fonts, ",");
-	if (! fonts.empty()) {
-	    litehtml::trim(fonts[0]);
-	}
-
-	cairo_font_face_t* fnt = 0;
-
-	FcPattern *pattern = FcPatternCreate();
-	bool found = false;
-	for(litehtml::string_vector::iterator i = fonts.begin(); i != fonts.end(); i++)
-	{
-		if(FcPatternAddString(pattern, FC_FAMILY, (unsigned char *) i->c_str()))
-		{
-			found = true;
-			break;
-		}
-	}
-	if(found)
-	{
-		if(italic == litehtml::fontStyleItalic )
-		{
-			FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ITALIC);
-		} else
-		{
-			FcPatternAddInteger (pattern, FC_SLANT, FC_SLANT_ROMAN);
-		}
-
-		int fc_weight = FC_WEIGHT_NORMAL;
-		if(weight >= 0 && weight < 150)			fc_weight = FC_WEIGHT_THIN;
-		else if(weight >= 150 && weight < 250)	fc_weight = FC_WEIGHT_EXTRALIGHT;
-		else if(weight >= 250 && weight < 350)	fc_weight = FC_WEIGHT_LIGHT;
-		else if(weight >= 350 && weight < 450)	fc_weight = FC_WEIGHT_NORMAL;
-		else if(weight >= 450 && weight < 550)	fc_weight = FC_WEIGHT_MEDIUM;
-		else if(weight >= 550 && weight < 650)	fc_weight = FC_WEIGHT_SEMIBOLD;
-		else if(weight >= 650 && weight < 750)	fc_weight = FC_WEIGHT_BOLD;
-		else if(weight >= 750 && weight < 850)	fc_weight = FC_WEIGHT_EXTRABOLD;
-		else if(weight >= 950)					fc_weight = FC_WEIGHT_BLACK;
-
-		FcPatternAddInteger (pattern, FC_WEIGHT, fc_weight);
-
-		fnt = cairo_ft_font_face_create_for_pattern(pattern);
-	}
-
-	FcPatternDestroy(pattern);
-
-	cairo_font* ret = 0;
-
-	if(fm && fnt)
-	{
-		cairo_save(m_temp_cr);
-
-		cairo_set_font_face(m_temp_cr, fnt);
-		cairo_set_font_size(m_temp_cr, size);
-		cairo_font_extents_t ext;
-		cairo_font_extents(m_temp_cr, &ext);
-
-		cairo_text_extents_t tex;
-		cairo_text_extents(m_temp_cr, "x", &tex);
-
-		fm->ascent		= (int) ext.ascent;
-		fm->descent		= (int) ext.descent;
-		fm->height		= (int) (ext.ascent + ext.descent);
-		fm->x_height	= (int) tex.height;
-
-		cairo_restore(m_temp_cr);
-
-		ret = new cairo_font;
-		ret->font		= fnt;
-		ret->size		= size;
-		ret->strikeout 	= (decoration & litehtml::font_decoration_linethrough) ? true : false;
-		ret->underline	= (decoration & litehtml::font_decoration_underline) ? true : false;
-
-	}
-
-	return (litehtml::uint_ptr) ret;
-}
-
-void container_linux::delete_font( litehtml::uint_ptr hFont )
-{
-	cairo_font* fnt = (cairo_font*) hFont;
-	if(fnt)
-	{
-		cairo_font_face_destroy(fnt->font);
-		delete fnt;
-	}
-}
-
-int container_linux::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont )
-{
-	cairo_font* fnt = (cairo_font*) hFont;
-
-	cairo_save(m_temp_cr);
-
-	if (fnt) {
-	    cairo_set_font_size(m_temp_cr, fnt->size);
-	    cairo_set_font_face(m_temp_cr, fnt->font);
-	}
-	cairo_text_extents_t ext;
-	cairo_text_extents(m_temp_cr, text, &ext);
-
-	cairo_restore(m_temp_cr);
-
-	return (int) ext.x_advance;
-}
-
-void container_linux::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos )
-{
-	cairo_font* fnt = (cairo_font*) hFont;
-	cairo_t* cr		= (cairo_t*) hdc;
-	cairo_save(cr);
-
-	apply_clip(cr);
-
-	if (fnt) {
-	    cairo_set_font_face(cr, fnt->font);
-	    cairo_set_font_size(cr, fnt->size);
-	}
-	cairo_font_extents_t ext;
-	cairo_font_extents(cr, &ext);
-
-	int x = pos.left();
-	int y = pos.bottom()	- ext.descent;
-
-	set_color(cr, color);
-
-	cairo_move_to(cr, x, y);
-	cairo_show_text(cr, text);
-
-	int tw = 0;
-
-	if (fnt) {
-	    if(fnt->underline || fnt->strikeout)
-	    {
-		tw = text_width(text, hFont);
-	    }
-
-	    if(fnt->underline)
-	    {
-		cairo_set_line_width(cr, 1);
-		cairo_move_to(cr, x, y + 1.5);
-		cairo_line_to(cr, x + tw, y + 1.5);
-		cairo_stroke(cr);
-	    }
-	    if(fnt->strikeout)
-	    {
-		cairo_text_extents_t tex;
-		cairo_text_extents(cr, "x", &tex);
-
-		int ln_y = y - tex.height / 2.0;
-
-		cairo_set_line_width(cr, 1);
-		cairo_move_to(cr, x, (double) ln_y - 0.5);
-		cairo_line_to(cr, x + tw, (double) ln_y - 0.5);
-		cairo_stroke(cr);
-	    }
-	}   
-
-	cairo_restore(cr);
-}
-
 int container_linux::pt_to_px( int pt )
 {
 	GdkScreen* screen = gdk_screen_get_default();
diff --git a/src/plugins/litehtml_viewer/container_linux.h b/src/plugins/litehtml_viewer/container_linux.h
index 43a917c..8132bfb 100644
--- a/src/plugins/litehtml_viewer/container_linux.h
+++ b/src/plugins/litehtml_viewer/container_linux.h
@@ -35,14 +35,6 @@ struct cairo_clip_box
 	}
 };
 
-struct cairo_font
-{
-	cairo_font_face_t*	font;
-	int					size;
-	bool				underline;
-	bool				strikeout;
-};
-
 class container_linux :	public litehtml::document_container
 {
 	typedef std::pair<litehtml::tstring, GdkPixbuf*> image;
@@ -57,10 +49,6 @@ public:
 	container_linux(void);
 	virtual ~container_linux(void);
 
-	virtual litehtml::uint_ptr			create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm) override;
-	virtual void						delete_font(litehtml::uint_ptr hFont) override;
-	virtual int						text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont) override;
-	virtual void						draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos) override;
 	virtual int						pt_to_px(int pt) override;
 	virtual void 						load_image(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, bool redraw_on_ready) override;
 	virtual void						get_image_size(const litehtml::tchar_t* src, const litehtml::tchar_t* baseurl, litehtml::size& sz) override;
@@ -92,11 +80,11 @@ protected:
 	virtual void						draw_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color, int line_width);
 	virtual void						fill_ellipse(cairo_t* cr, int x, int y, int width, int height, const litehtml::web_color& color);
 	virtual void						rounded_rectangle( cairo_t* cr, const litehtml::position &pos, const litehtml::border_radiuses &radius );
+	void								apply_clip(cairo_t* cr);
+	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); }
 
 private:
-	void								apply_clip(cairo_t* cr);
 	void								add_path_arc(cairo_t* cr, double x, double y, double rx, double ry, double a1, double a2, bool neg);
-	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); }
 	void								draw_pixbuf(cairo_t* cr, const GdkPixbuf *bmp, int x, int y, int cx, int cy);
 	cairo_surface_t*					surface_from_pixbuf(const GdkPixbuf *bmp);
 };
diff --git a/src/plugins/litehtml_viewer/lh_widget.h b/src/plugins/litehtml_viewer/lh_widget.h
index da2dc7f..55fc56d 100644
--- a/src/plugins/litehtml_viewer/lh_widget.h
+++ b/src/plugins/litehtml_viewer/lh_widget.h
@@ -4,6 +4,13 @@
 
 #include "container_linux.h"
 
+struct pango_font
+{
+	PangoFontDescription *font;
+	bool underline;
+	bool strikethrough;
+};
+
 class lh_widget : public container_linux
 {
 	public:
@@ -20,9 +27,14 @@ class lh_widget : public container_linux
 		void import_css(litehtml::tstring& text, const litehtml::tstring& url, litehtml::tstring& baseurl);
 		void get_client_rect(litehtml::position& client) const;
 		inline const litehtml::tchar_t *get_default_font_name() const { return m_font_name; };
-		inline int get_default_font_size() const { return m_font_size; };
 		GdkPixbuf *get_image(const litehtml::tchar_t* url, bool redraw_on_ready);
 
+		inline int get_default_font_size() const { return m_font_size; };
+		litehtml::uint_ptr create_font(const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm);
+		void delete_font(litehtml::uint_ptr hFont);
+		int text_width(const litehtml::tchar_t* text, litehtml::uint_ptr hFont);
+		void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos);
+
 		void draw(cairo_t *cr);
 		void redraw();
 		void open_html(const gchar *contents);
diff --git a/src/plugins/litehtml_viewer/lh_widget_text.cpp b/src/plugins/litehtml_viewer/lh_widget_text.cpp
new file mode 100644
index 0000000..ed29055
--- /dev/null
+++ b/src/plugins/litehtml_viewer/lh_widget_text.cpp
@@ -0,0 +1,142 @@
+/*
+ * Claws Mail -- A GTK+ based, lightweight, and fast e-mail client
+ * Copyright(C) 2019 the Claws Mail Team
+ *
+ * litehtml callbacks related to text rendering
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write tothe Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+
+#include "litehtml/litehtml.h"
+
+#include "lh_widget.h"
+
+litehtml::uint_ptr lh_widget::create_font( const litehtml::tchar_t* faceName, int size, int weight, litehtml::font_style italic, unsigned int decoration, litehtml::font_metrics* fm )
+{
+	PangoFontDescription *desc =
+		pango_font_description_from_string(faceName);
+
+	pango_font_description_set_size(desc, size * PANGO_SCALE);
+	pango_font_description_set_weight(desc, (PangoWeight)weight);
+
+	if (italic == litehtml::fontStyleItalic)
+		pango_font_description_set_style(desc, PANGO_STYLE_ITALIC);
+	else
+		pango_font_description_set_style(desc, PANGO_STYLE_NORMAL);
+
+	if(fm != NULL) {
+		PangoContext *context = gtk_widget_get_pango_context(m_drawing_area);
+		PangoFontMetrics *metrics = pango_context_get_metrics(
+				context, desc,
+				pango_context_get_language(context));
+		PangoLayout *x_layout;
+		PangoRectangle rect;
+
+		x_layout = pango_layout_new(context);
+		pango_layout_set_font_description(x_layout, desc);
+		pango_layout_set_text(x_layout, "x", -1);
+		pango_layout_get_pixel_extents(x_layout, NULL, &rect);
+
+		fm->ascent		= pango_font_metrics_get_ascent(metrics) / PANGO_SCALE;
+		fm->descent		= pango_font_metrics_get_descent(metrics) / PANGO_SCALE;
+		fm->height		= fm->ascent + fm->descent;
+		fm->x_height	= rect.height;
+
+		g_object_unref(x_layout);
+		pango_font_metrics_unref(metrics);
+	}
+
+	pango_font *ret = new pango_font;
+	ret->font = desc;
+	ret->strikethrough = (decoration & litehtml::font_decoration_linethrough) ? true : false;
+	ret->underline = (decoration & litehtml::font_decoration_underline) ? true : false;
+
+	return (litehtml::uint_ptr) ret;
+}
+
+void lh_widget::delete_font( litehtml::uint_ptr hFont )
+{
+	pango_font *fnt = (pango_font *)hFont;
+
+	if (fnt != NULL) {
+		pango_font_description_free(fnt->font);
+		delete fnt;
+	}
+}
+
+int lh_widget::text_width( const litehtml::tchar_t* text, litehtml::uint_ptr hFont )
+{
+	pango_font *fnt = (pango_font *) hFont;
+	PangoContext *context = gtk_widget_get_pango_context(m_drawing_area);
+	PangoLayout *layout = pango_layout_new(context);
+	PangoRectangle rect;
+
+	if (fnt)
+		pango_layout_set_font_description(layout, fnt->font);
+
+	pango_layout_set_text(layout, text, -1);
+	pango_layout_get_pixel_extents(layout, NULL, &rect);
+
+	g_object_unref(layout);
+
+	return rect.width;
+}
+
+void lh_widget::draw_text( litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos )
+{
+	pango_font *fnt = (pango_font *)hFont;
+	cairo_t *cr = (cairo_t *)hdc;
+	PangoLayout *layout = pango_cairo_create_layout(cr);
+	PangoContext *context = pango_layout_get_context(layout);
+
+	if (fnt != NULL) {
+		/* Set font */
+		pango_layout_set_font_description(layout, fnt->font);
+
+		/* Set additional font attributes */
+		if (fnt->underline || fnt->strikethrough) {
+			PangoAttrList *attr_list = pango_attr_list_new();
+			PangoUnderline ul;
+
+			if (fnt->underline )
+				ul = PANGO_UNDERLINE_SINGLE;
+			else
+				ul = PANGO_UNDERLINE_NONE;
+
+			pango_attr_list_insert(attr_list,
+					pango_attr_underline_new(ul));
+			pango_attr_list_insert(attr_list,
+					pango_attr_strikethrough_new(fnt->strikethrough));
+
+			pango_layout_set_attributes(layout, attr_list);
+			pango_attr_list_unref(attr_list);
+		}
+	}
+
+	/* Set actual text content */
+	pango_layout_set_text(layout, text, -1);
+
+	cairo_save(cr);
+
+	/* Draw the text where it's supposed to be */
+	apply_clip(cr);
+	set_color(cr, color);
+	cairo_move_to(cr, pos.left(), pos.top());
+	pango_cairo_show_layout(cr, layout);
+
+	/* Cleanup */
+	g_object_unref(layout);
+	cairo_restore(cr);
+}

-----------------------------------------------------------------------


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list