summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-12-19 15:49:39 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-12-19 15:49:39 +0000
commit3cdcf7d31f2a68731678f8bde4e236decb21c90a (patch)
tree438fd00eba4b44afd4cf81b6618eb68624d43e88
parentc0c70393f798be29e3835fa0abd04b15a6235562 (diff)
parent704662e39856e308ef1683be607d62db0b738708 (diff)
downloadpango-3cdcf7d31f2a68731678f8bde4e236decb21c90a.tar.gz
Merge branch 'fix-small-caps-line-height' into 'main'
Fix line height with emulated small caps Closes #622 See merge request GNOME/pango!543
-rw-r--r--pango/itemize.c17
-rw-r--r--pango/pango-item-private.h22
-rw-r--r--pango/pango-item.c47
-rw-r--r--pango/pango-item.h4
-rw-r--r--pango/pango-layout.c27
5 files changed, 103 insertions, 14 deletions
diff --git a/pango/itemize.c b/pango/itemize.c
index 6c07e4c2..6380c12f 100644
--- a/pango/itemize.c
+++ b/pango/itemize.c
@@ -1045,7 +1045,8 @@ collect_font_scale (PangoContext *context,
GList **stack,
PangoItem *item,
PangoItem *prev,
- double *scale)
+ double *scale,
+ gboolean *is_small_caps)
{
gboolean retval = FALSE;
GList *l;
@@ -1123,11 +1124,14 @@ collect_font_scale (PangoContext *context,
}
*scale = 1.0;
+ *is_small_caps = TRUE;
for (l = *stack; l; l = l->next)
{
ScaleItem *entry = l->data;
*scale *= entry->scale;
+ if (((PangoAttrInt *)entry->attr)->value != PANGO_FONT_SCALE_SMALL_CAPS)
+ *is_small_caps = FALSE;
retval = TRUE;
}
@@ -1152,11 +1156,15 @@ collect_font_scale (PangoContext *context,
static void
apply_scale_to_item (PangoContext *context,
PangoItem *item,
- double scale)
+ double scale,
+ gboolean is_small_caps)
{
PangoFontDescription *desc;
double size;
+ if (is_small_caps)
+ pango_analysis_set_size_font (&item->analysis, item->analysis.font);
+
desc = pango_font_describe (item->analysis.font);
size = scale * pango_font_description_get_size (desc);
@@ -1182,9 +1190,10 @@ apply_font_scale (PangoContext *context,
{
PangoItem *item = l->data;
double scale;
+ gboolean is_small_caps;
- if (collect_font_scale (context, &stack, item, prev, &scale))
- apply_scale_to_item (context, item, scale);
+ if (collect_font_scale (context, &stack, item, prev, &scale, &is_small_caps))
+ apply_scale_to_item (context, item, scale, is_small_caps);
prev = item;
}
diff --git a/pango/pango-item-private.h b/pango/pango-item-private.h
index 6e20953f..9d2fa805 100644
--- a/pango/pango-item-private.h
+++ b/pango/pango-item-private.h
@@ -38,6 +38,24 @@ G_BEGIN_DECLS
#define PANGO_ANALYSIS_FLAG_HAS_CHAR_OFFSET (1 << 7)
+typedef struct _PangoAnalysisPrivate PangoAnalysisPrivate;
+
+struct _PangoAnalysisPrivate
+{
+ gpointer reserved;
+ PangoFont *size_font;
+ PangoFont *font;
+
+ guint8 level;
+ guint8 gravity;
+ guint8 flags;
+
+ guint8 script;
+ PangoLanguage *language;
+
+ GSList *extra_attrs;
+};
+
typedef struct _PangoItemPrivate PangoItemPrivate;
#if defined(__x86_64__) && !defined(__ILP32__)
@@ -74,6 +92,10 @@ void pango_analysis_collect_features (const PangoAnalysis
guint length,
guint *num_features);
+void pango_analysis_set_size_font (PangoAnalysis *analysis,
+ PangoFont *font);
+PangoFont * pango_analysis_get_size_font (const PangoAnalysis *analysis);
+
GList * pango_itemize_with_font (PangoContext *context,
PangoDirection base_dir,
const char *text,
diff --git a/pango/pango-item.c b/pango/pango-item.c
index 2b2664c5..c599241f 100644
--- a/pango/pango-item.c
+++ b/pango/pango-item.c
@@ -68,6 +68,9 @@ pango_item_copy (PangoItem *item)
((PangoItemPrivate *)result)->char_offset = ((PangoItemPrivate *)item)->char_offset;
result->analysis = item->analysis;
+ if (result->analysis.lang_engine)
+ g_object_ref (result->analysis.lang_engine);
+
if (result->analysis.font)
g_object_ref (result->analysis.font);
@@ -102,6 +105,9 @@ pango_item_free (PangoItem *item)
g_slist_free (item->analysis.extra_attrs);
}
+ if (item->analysis.lang_engine)
+ g_object_unref (item->analysis.lang_engine);
+
if (item->analysis.font)
g_object_unref (item->analysis.font);
@@ -324,3 +330,44 @@ pango_analysis_collect_features (const PangoAnalysis *analysis,
}
}
}
+
+/*< private >
+ * pango_analysis_set_size_font:
+ * @analysis: a `PangoAnalysis`
+ * @font: a `PangoFont`
+ *
+ * Sets the font to use for determining the line height.
+ *
+ * This is used when scaling fonts for emulated Small Caps,
+ * to preserve the original line height.
+ */
+void
+pango_analysis_set_size_font (PangoAnalysis *analysis,
+ PangoFont *font)
+{
+ PangoAnalysisPrivate *priv = (PangoAnalysisPrivate *)analysis;
+
+ if (priv->size_font)
+ g_object_unref (priv->size_font);
+ priv->size_font = font;
+ if (priv->size_font)
+ g_object_ref (priv->size_font);
+}
+
+/*< private >
+ * pango_analysis_get_size_font:
+ * @analysis: a `PangoAnalysis`
+ *
+ * Gets the font to use for determining line height.
+ *
+ * If this returns `NULL`, use analysis->font.
+ *
+ * Returns: (nullable) (transfer none): the font
+ */
+PangoFont *
+pango_analysis_get_size_font (const PangoAnalysis *analysis)
+{
+ PangoAnalysisPrivate *priv = (PangoAnalysisPrivate *)analysis;
+
+ return priv->size_font;
+}
diff --git a/pango/pango-item.h b/pango/pango-item.h
index 8122be19..f0eebc01 100644
--- a/pango/pango-item.h
+++ b/pango/pango-item.h
@@ -61,8 +61,8 @@ typedef struct _PangoItem PangoItem;
/**
* PangoAnalysis:
- * @shape_engine: unused
- * @lang_engine: unused
+ * @shape_engine: unused, reserved
+ * @lang_engine: unused, reserved
* @font: the font for this segment.
* @level: the bidirectional level for this segment.
* @gravity: the glyph orientation for this segment (A `PangoGravity`).
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 3f11d5b0..24a1a88b 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -5518,10 +5518,7 @@ pango_layout_get_empty_extents_and_height_at_index (PangoLayout *layout,
free_font_desc = TRUE;
}
- pango_attr_iterator_get_font (&iter,
- font_desc,
- NULL,
- NULL);
+ pango_attr_iterator_get_font (&iter, font_desc, NULL, NULL);
attr = pango_attr_iterator_get (&iter, PANGO_ATTR_LINE_HEIGHT);
if (attr)
@@ -5689,11 +5686,25 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
if (height)
{
- if (!metrics)
- metrics = pango_font_get_metrics (run->item->analysis.font,
- run->item->analysis.language);
+ if (pango_analysis_get_size_font (&run->item->analysis))
+ {
+ PangoFontMetrics *height_metrics;
+
+ height_metrics = pango_font_get_metrics (pango_analysis_get_size_font (&run->item->analysis),
+ run->item->analysis.language);
+
+ *height = pango_font_metrics_get_height (height_metrics);
- *height = pango_font_metrics_get_height (metrics);
+ pango_font_metrics_unref (height_metrics);
+ }
+ else
+ {
+ if (!metrics)
+ metrics = pango_font_get_metrics (run->item->analysis.font,
+ run->item->analysis.language);
+
+ *height = pango_font_metrics_get_height (metrics);
+ }
}
y_offset = run->y_offset;