summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2004-05-27 19:43:49 +0000
committerOwen Taylor <otaylor@src.gnome.org>2004-05-27 19:43:49 +0000
commit4caf16365e5eb027f14e29038c2376e9a9dcf4dc (patch)
treeda0a8722dc20179c972ac29590aa856c3c085b7e /pango
parent5ad5eff481421dbb95f450788807cd10315dc5d6 (diff)
downloadpango-4caf16365e5eb027f14e29038c2376e9a9dcf4dc.tar.gz
Add underline and strikethrough position and thickness metrics.
Thu May 27 15:32:03 2004 Owen Taylor <otaylor@redhat.com> * pango/pango-font.h pango/fonts.c: Add underline and strikethrough position and thickness metrics. * pango/pangofc-font.c: Implement underline and strikethrough position and thickness metrics. * pango/pango-fontset.c (pango_fontset_real_get_metrics): Initialize metrics from the metrics of the first font in the fontset.
Diffstat (limited to 'pango')
-rw-r--r--pango/fonts.c70
-rw-r--r--pango/pango-font.h8
-rw-r--r--pango/pango-fontset.c26
-rw-r--r--pango/pangofc-font.c75
4 files changed, 179 insertions, 0 deletions
diff --git a/pango/fonts.c b/pango/fonts.c
index aaa8c812..6535f7a9 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -1288,6 +1288,76 @@ pango_font_metrics_get_approximate_digit_width (PangoFontMetrics *metrics)
return metrics->approximate_digit_width;
}
+/**
+ * pango_font_metrics_get_underline_position:
+ * @metrics: a #PangoFontMetrics structure
+ *
+ * Gets the suggested position to draw the underline.
+ * The value returned is the distance <emphasis>above</emphasis> the
+ * baseline of the top of the underline. Since most fonts have
+ * underline positions beneath the baseline, this value is typically
+ * negative.
+ *
+ * Return value: the suggested underline position, in Pango units.
+ **/
+int
+pango_font_metrics_get_underline_position (PangoFontMetrics *metrics)
+{
+ g_return_val_if_fail (metrics != NULL, 0);
+
+ return metrics->underline_position;
+}
+
+/**
+ * pango_font_metrics_get_underline_thickness:
+ * @metrics: a #PangoFontMetrics structure
+ *
+ * Gets the suggested thickness to draw for the underline.
+ *
+ * Return value: the suggested underline thickness, in Pango units.
+ **/
+int
+pango_font_metrics_get_underline_thickness (PangoFontMetrics *metrics)
+{
+ g_return_val_if_fail (metrics != NULL, 0);
+
+ return metrics->underline_thickness;
+}
+
+/**
+ * pango_font_metrics_get_strikethrough_position:
+ * @metrics: a #PangoFontMetrics structure
+ *
+ * Gets the suggested position to draw the strikethrough.
+ * The value returned is the distance <emphasis>above</emphasis> the
+ * baseline of the top of the strikethrough.
+ *
+ * Return value: the suggested strikethrough position, in Pango units.
+ **/
+int
+pango_font_metrics_get_strikethrough_position (PangoFontMetrics *metrics)
+{
+ g_return_val_if_fail (metrics != NULL, 0);
+
+ return metrics->strikethrough_position;
+}
+
+/**
+ * pango_font_metrics_get_strikethrough_thickness:
+ * @metrics: a #PangoFontMetrics structure
+ *
+ * Gets the suggested thickness to draw for the strikethrough.
+ *
+ * Return value: the suggested strikethrough thickness, in Pango units.
+ **/
+int
+pango_font_metrics_get_strikethrough_thickness (PangoFontMetrics *metrics)
+{
+ g_return_val_if_fail (metrics != NULL, 0);
+
+ return metrics->strikethrough_thickness;
+}
+
/*
* PangoFontFamily
*/
diff --git a/pango/pango-font.h b/pango/pango-font.h
index 56b3b72f..ebe1fc87 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -159,6 +159,10 @@ int pango_font_metrics_get_ascent (PangoFontMetri
int pango_font_metrics_get_descent (PangoFontMetrics *metrics);
int pango_font_metrics_get_approximate_char_width (PangoFontMetrics *metrics);
int pango_font_metrics_get_approximate_digit_width (PangoFontMetrics *metrics);
+int pango_font_metrics_get_underline_position (PangoFontMetrics *metrics);
+int pango_font_metrics_get_underline_thickness (PangoFontMetrics *metrics);
+int pango_font_metrics_get_strikethrough_position (PangoFontMetrics *metrics);
+int pango_font_metrics_get_strikethrough_thickness (PangoFontMetrics *metrics);
#ifdef PANGO_ENABLE_BACKEND
@@ -172,6 +176,10 @@ struct _PangoFontMetrics
int descent;
int approximate_char_width;
int approximate_digit_width;
+ int underline_position;
+ int underline_thickness;
+ int strikethrough_position;
+ int strikethrough_thickness;
};
#endif /* PANGO_ENABLE_BACKEND */
diff --git a/pango/pango-fontset.c b/pango/pango-fontset.c
index e3f38920..d4aaf351 100644
--- a/pango/pango-fontset.c
+++ b/pango/pango-fontset.c
@@ -100,6 +100,29 @@ pango_fontset_foreach (PangoFontset *fontset,
PANGO_FONTSET_GET_CLASS (fontset)->foreach (fontset, func, data);
}
+static gboolean
+get_first_metrics_foreach (PangoFontset *fontset,
+ PangoFont *font,
+ gpointer data)
+{
+ PangoFontMetrics *fontset_metrics = data;
+ PangoLanguage *language = PANGO_FONTSET_GET_CLASS (fontset)->get_language (fontset);
+ PangoFontMetrics *font_metrics = pango_font_get_metrics (font, language);
+ guint save_ref_count;
+
+ /* Initialize the fontset metrics to metrics of the first font in the
+ * fontset; saving the refcount and restoring it is a bit of hack but avoids
+ * having to update this code for each metrics addition.
+ */
+ save_ref_count = fontset_metrics->ref_count;
+ *fontset_metrics = *font_metrics;
+ fontset_metrics->ref_count = save_ref_count;
+
+ pango_font_metrics_unref (font_metrics);
+
+ return TRUE; /* Stops iteration */
+}
+
static PangoFontMetrics *
pango_fontset_real_get_metrics (PangoFontset *fontset)
{
@@ -118,6 +141,9 @@ pango_fontset_real_get_metrics (PangoFontset *fontset)
metrics = pango_font_metrics_new ();
fonts_seen = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);
+ /* Initialize the metrics from the first font in the fontset */
+ pango_fontset_foreach (fontset, get_first_metrics_foreach, metrics);
+
p = sample_str;
while (*p)
{
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 18530ded..de43513d 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -26,6 +26,8 @@
#include "pango-modules.h"
#include "pango-utils.h"
+#include FT_TRUETYPE_TABLES_H
+
#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))
#define PANGO_PIXELS_26_6(d) \
(((d) >= 0) ? \
@@ -209,6 +211,28 @@ pango_fc_font_get_coverage (PangoFont *font,
fcfont->font_pattern);
}
+static void
+quantize_position (int *thickness,
+ int *position)
+{
+ int thickness_pixels = (*thickness + PANGO_SCALE / 2) / PANGO_SCALE;
+ if (thickness_pixels == 0)
+ thickness_pixels = 1;
+
+ if (thickness_pixels & 1)
+ {
+ int new_center = ((*position - *thickness / 2) & ~(PANGO_SCALE - 1)) + PANGO_SCALE / 2;
+ *position = new_center + (PANGO_SCALE * thickness_pixels) / 2;
+ }
+ else
+ {
+ int new_center = ((*position - *thickness / 2 + PANGO_SCALE / 2) & ~(PANGO_SCALE - 1));
+ *position = new_center + (PANGO_SCALE * thickness_pixels) / 2;
+ }
+
+ *thickness = thickness_pixels * PANGO_SCALE;
+}
+
/* For Xft, it would be slightly more efficient to simply to
* call Xft, and also more robust against changes in Xft.
* But for now, we simply use the same code for all backends.
@@ -220,10 +244,16 @@ static void
get_face_metrics (PangoFcFont *fcfont,
PangoFontMetrics *metrics)
{
+ FcBool hinting;
FT_Face face = pango_fc_font_lock_face (fcfont);
FcMatrix *fc_matrix;
FT_Matrix ft_matrix;
+ TT_OS2 *os2;
gboolean have_transform = FALSE;
+
+ if (FcPatternGetBool (fcfont->font_pattern,
+ FC_HINTING, 0, &hinting) != FcResultMatch)
+ hinting = FcTrue;
if (FcPatternGetMatrix (fcfont->font_pattern,
FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
@@ -256,6 +286,51 @@ get_face_metrics (PangoFcFont *fcfont,
metrics->descent = - PANGO_UNITS_26_6 (face->size->metrics.descender);
metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
}
+
+ /* Versions of FreeType < 2.1.8 get underline thickness wrong
+ * for Postscript fonts (always zero), so we need a fallback
+ */
+ if (face->underline_thickness == 0)
+ {
+ metrics->underline_thickness = (PANGO_SCALE * face->size->metrics.y_ppem) / 14;
+ metrics->underline_position = - metrics->underline_thickness;
+ }
+ else
+ {
+ FT_Fixed ft_thickness, ft_position;
+
+ ft_thickness = FT_MulFix (face->underline_thickness, face->size->metrics.y_scale);
+ metrics->underline_thickness = PANGO_UNITS_26_6 (ft_thickness);
+
+ ft_position = FT_MulFix (face->underline_position, face->size->metrics.y_scale);
+ metrics->underline_position = PANGO_UNITS_26_6 (ft_position);
+ }
+
+ os2 = FT_Get_Sfnt_Table (face, ft_sfnt_os2);
+ if (os2 && os2->version != 0xFFFF && os2->yStrikeoutSize != 0)
+ {
+ FT_Fixed ft_thickness, ft_position;
+
+ ft_thickness = FT_MulFix (os2->yStrikeoutSize, face->size->metrics.y_scale);
+ metrics->strikethrough_thickness = PANGO_UNITS_26_6 (ft_thickness);
+
+ ft_position = FT_MulFix (os2->yStrikeoutPosition, face->size->metrics.y_scale);
+ metrics->strikethrough_position = PANGO_UNITS_26_6 (ft_position);
+ }
+ else
+ {
+ metrics->strikethrough_thickness = metrics->underline_thickness;
+ metrics->strikethrough_position = (PANGO_SCALE * face->size->metrics.y_ppem) / 4;
+ }
+
+ /* If hinting is on for this font, quantize the underline and strikethrough position
+ * to integer values.
+ */
+ if (hinting)
+ {
+ quantize_position (&metrics->underline_thickness, &metrics->underline_position);
+ quantize_position (&metrics->strikethrough_thickness, &metrics->strikethrough_position);
+ }
pango_fc_font_unlock_face (fcfont);
}