diff --git a/include/cairo/font.hpp b/include/cairo/font.hpp index 170b9dd8..1681a1bd 100644 --- a/include/cairo/font.hpp +++ b/include/cairo/font.hpp @@ -112,19 +112,75 @@ namespace cairo { return m_offset; } + /** + * Calculates the font size in pixels for the given dpi + * + * We use the two font properties size and pixelsize. size is in points and + * needs to be scaled with the given dpi. pixelsize is not scaled. + * + * If both size properties are 0, we fall back to a default value of 10 + * points for scalable fonts or 10 pixel for non-scalable ones. This should + * only happen if both properties are purposefully set to 0 + * + * For scalable fonts we try to use the size property scaled according to + * the dpi. + * For non-scalable fonts we try to use the pixelsize property as-is + */ double size(double dpi) const override { bool scalable; - double px; + double fc_pixelsize = 0, fc_size = 0; + 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); + + // Size in points + property(FC_SIZE, &fc_size); + + // Size in pixels + property(FC_PIXEL_SIZE, &fc_pixelsize); + + // Fall back to a default value if the size is 0 + double pixelsize = fc_pixelsize == 0? 10 : fc_pixelsize; + double size = fc_size == 0? 10 : fc_size; + + // Font size in pixels if we use the pixelsize property + int px_pixelsize = pixelsize + 0.5; + + /* + * Font size in pixels if we use the size property. Since the size + * specifies the font size in points, this is converted to pixels + * according to the dpi given. + * One point is 1/72 inches, thus this gives us the number of 'dots' + * (or pixels) for this font + */ + int px_size = size / 72.0 * dpi + 0.5; + + if (fc_size == 0 && fc_pixelsize == 0) { + return scalable? px_size : px_pixelsize; + } + + if (scalable) { + /* + * Use the point size if it's not 0. The pixelsize is only used if the + * size property is 0 and pixelsize is not + */ + if (fc_size != 0) { + return px_size; + } + else { + return px_pixelsize; + } + } else { + /* + * Non-scalable fonts do it the other way around, here the size + * property is only used if pixelsize is 0 and size is not + */ + if (fc_pixelsize != 0) { + return px_pixelsize; + } + else { + return px_size; + } } - return px; } void use() override {