diff --git a/include/cairo/font.hpp b/include/cairo/font.hpp index 5c1e0755..3029ea23 100644 --- a/include/cairo/font.hpp +++ b/include/cairo/font.hpp @@ -30,7 +30,7 @@ namespace cairo { virtual string name() const = 0; virtual string file() const = 0; virtual double offset() const = 0; - virtual double size() const = 0; + virtual double size(double dpi) const = 0; virtual cairo_font_extents_t extents() = 0; @@ -54,10 +54,10 @@ namespace cairo { */ class font_fc : public font { public: - explicit font_fc(cairo_t* cairo, FcPattern* pattern, double offset) : font(cairo, offset), m_pattern(pattern) { + explicit font_fc(cairo_t* cairo, FcPattern* pattern, double offset, double dpi_x, double dpi_y) : font(cairo, offset), m_pattern(pattern) { cairo_matrix_t fm; cairo_matrix_t ctm; - cairo_matrix_init_scale(&fm, size(), size()); + cairo_matrix_init_scale(&fm, size(dpi_x), size(dpi_y)); cairo_get_matrix(m_cairo, &ctm); auto fontface = cairo_ft_font_face_create_for_pattern(m_pattern); @@ -111,12 +111,14 @@ namespace cairo { return m_offset; } - double size() const override { + double size(double dpi) const override { bool scalable; double px; property(FC_SCALABLE, &scalable); if (scalable) { + // convert from pt to px using the provided dpi property(FC_SIZE, &px); + px = static_cast(px * dpi / 72.0 + 0.5); } else { property(FC_PIXEL_SIZE, &px); px = static_cast(px + 0.5); @@ -234,7 +236,7 @@ namespace cairo { /** * Match and create font from given fontconfig pattern */ - decltype(auto) make_font(cairo_t* cairo, string&& fontname, double offset) { + decltype(auto) make_font(cairo_t* cairo, string&& fontname, double offset, double dpi_x, double dpi_y) { static bool fc_init{false}; if (!fc_init && !(fc_init = FcInit())) { throw application_error("Could not load fontconfig"); @@ -263,7 +265,7 @@ namespace cairo { FcPatternPrint(match); #endif - return make_shared(cairo, match, offset); + return make_shared(cairo, match, offset, dpi_x, dpi_y); } } diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index bc9d78ed..e66797cc 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -121,6 +121,20 @@ renderer::renderer( m_log.trace("renderer: Load fonts"); { + double dpi_x = 96, dpi_y = 96; + if (m_conf.has(m_conf.section(), "dpi")) { + try { + // dpi specified directly as a value + dpi_x = dpi_y = m_conf.get("dpi"); + } catch (const value_error&) { + // dpi to be comptued + auto screen = m_connection.screen(); + dpi_x = screen->width_in_pixels * 25.4 / screen->width_in_millimeters; + dpi_y = screen->height_in_pixels * 25.4 / screen->height_in_millimeters; + } + } + m_log.trace("renderer: DPI is %.1fx%.1f", dpi_x, dpi_y); + auto fonts = m_conf.get_list(m_conf.section(), "font", {}); if (fonts.empty()) { m_log.warn("No fonts specified, using fallback font \"fixed\""); @@ -130,7 +144,7 @@ renderer::renderer( auto fonts_loaded = false; for (const auto& f : fonts) { vector fd{string_util::split(f, ';')}; - auto font = cairo::make_font(*m_context, string(fd[0]), fd.size() > 1 ? std::atoi(fd[1].c_str()) : 0); + auto font = cairo::make_font(*m_context, string(fd[0]), fd.size() > 1 ? std::atoi(fd[1].c_str()) : 0, dpi_x, dpi_y); m_log.info("Loaded font \"%s\" (name=%s, file=%s)", fd[0], font->name(), font->file()); *m_context << move(font); fonts_loaded = true;