lh_prefs.c \
lh_viewer.c \
lh_widget.cpp \
+ lh_widget_text.cpp \
container_linux.h \
lh_prefs.h \
lh_viewer.h \
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();
}
};
-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;
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;
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);
};
#include "container_linux.h"
+struct pango_font
+{
+ PangoFontDescription *font;
+ bool underline;
+ bool strikethrough;
+};
+
class lh_widget : public container_linux
{
public:
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);
--- /dev/null
+/*
+ * 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);
+}