diff options
author | Havoc Pennington <hp@redhat.com> | 2001-04-27 23:50:03 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2001-04-27 23:50:03 +0000 |
commit | 54fe82fbb797d6c72c81e629cba28fd803df7122 (patch) | |
tree | fdc77f4e259a37146f30d96b9724477f9702b970 /pango | |
parent | 374817f27422db4a5d4c68c423607ff560e53140 (diff) | |
download | pango-54fe82fbb797d6c72c81e629cba28fd803df7122.tar.gz |
Move some fontmap stuff to pangox-private.h to access fontmap->resolution
2001-04-27 Havoc Pennington <hp@redhat.com>
* pango/pangox-fontmap.c: Move some fontmap stuff to
pangox-private.h to access fontmap->resolution in pangox.c
* pango/pangox.c (get_font_metrics_from_subfonts): multiply
avg. width by PANGO_SCALE, and consider that avg width from X is
in decipoints
* modules/basic/basic-x.c: mark some chars unknown when shaping,
with a flag PANGO_X_UNKNOWN_FLAG
* pango/pangox.c (pango_x_font_get_metrics): use lookup_lang not
lang when calling get_font_metrics_from_string
(pango_x_render): render unknown chars
* pango/pango-layout.c:
(pango_layout_set_single_paragraph_mode): add mode where we don't
break on para separators, instead we shape them and display glyphs
(pango_layout_get_single_paragraph_mode): getter for above
(pango_layout_check_lines): handle single paragraph mode
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pango-layout.c | 58 | ||||
-rw-r--r-- | pango/pango-layout.h | 4 | ||||
-rw-r--r-- | pango/pangox-fontmap.c | 34 | ||||
-rw-r--r-- | pango/pangox-private.h | 38 | ||||
-rw-r--r-- | pango/pangox.c | 203 |
5 files changed, 289 insertions, 48 deletions
diff --git a/pango/pango-layout.c b/pango/pango-layout.c index dc92dd8f..7e04e7dd 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -116,6 +116,8 @@ struct _PangoLayout guint justify : 1; guint alignment : 2; + guint single_paragraph : 1; + gint n_chars; /* Total number of characters in layout */ PangoLogAttr *log_attrs; /* Logical attributes for layout's text */ @@ -662,6 +664,44 @@ pango_layout_get_tabs (PangoLayout *layout) } /** + * pango_layout_set_single_paragraph_mode: + * @layout: a #PangoLayout + * @setting: new setting + * + * If @setting is %TRUE, do not treat newlines and similar characters + * as paragraph separators; instead, keep all text in a single paragraph, + * and display a glyph for paragraph separator characters. Used when + * you want to allow editing of newlines on a single text line. + * + **/ +void +pango_layout_set_single_paragraph_mode (PangoLayout *layout, + gboolean setting) +{ + g_return_if_fail (PANGO_IS_LAYOUT (layout)); + + layout->single_paragraph = setting; + + pango_layout_clear_lines (layout); +} +/** + * pango_layout_get_single_paragraph_mode: + * @layout: a #PangoLayout + * + * Obtains the value set by pango_layout_set_single_paragraph_mode(). + * + * Return value: %TRUE if the layout does not break paragraphs at paragraph separator characters + **/ + +gboolean +pango_layout_get_single_paragraph_mode (PangoLayout *layout) +{ + g_return_val_if_fail (PANGO_IS_LAYOUT (layout), FALSE); + + return layout->single_paragraph; +} + +/** * pango_layout_set_text: * @layout: a #PangoLayout * @text: a UTF8-string @@ -2693,11 +2733,19 @@ pango_layout_check_lines (PangoLayout *layout) const char *end; int delimiter_index, next_para_index; ParaBreakState state; - - pango_find_paragraph_boundary (start, - (layout->text + layout->length) - start, - &delimiter_index, - &next_para_index); + + if (layout->single_paragraph) + { + delimiter_index = layout->length; + next_para_index = layout->length; + } + else + { + pango_find_paragraph_boundary (start, + (layout->text + layout->length) - start, + &delimiter_index, + &next_para_index); + } g_assert (next_para_index >= delimiter_index); diff --git a/pango/pango-layout.h b/pango/pango-layout.h index 76bef0e8..1944398f 100644 --- a/pango/pango-layout.h +++ b/pango/pango-layout.h @@ -124,6 +124,10 @@ void pango_layout_set_tabs (PangoLayout *la PangoTabArray* pango_layout_get_tabs (PangoLayout *layout); +void pango_layout_set_single_paragraph_mode (PangoLayout *layout, + gboolean setting); +gboolean pango_layout_get_single_paragraph_mode (PangoLayout *layout); + void pango_layout_context_changed (PangoLayout *layout); void pango_layout_get_log_attrs (PangoLayout *layout, diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c index 8cb86a2c..360e4e6b 100644 --- a/pango/pangox-fontmap.c +++ b/pango/pangox-fontmap.c @@ -32,16 +32,7 @@ #include "pango-utils.h" #include "pangox-private.h" -#define PANGO_TYPE_X_FONT_MAP (pango_x_font_map_get_type ()) -#define PANGO_X_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_X_FONT_MAP, PangoXFontMap)) -#define PANGO_X_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_X_FONT_MAP, PangoXFontMapClass)) -#define PANGO_X_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_X_FONT_MAP)) -#define PANGO_X_IS_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_X_FONT_MAP)) -#define PANGO_X_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_X_FONT_MAP, PangoXFontMapClass)) - typedef struct _PangoXFamilyEntry PangoXFamilyEntry; -typedef struct _PangoXFontMap PangoXFontMap; -typedef struct _PangoXFontMapClass PangoXFontMapClass; typedef struct _PangoXSizeInfo PangoXSizeInfo; /* Number of freed fonts */ @@ -72,28 +63,6 @@ typedef enum XLFD_NUM_FIELDS } FontField; -struct _PangoXFontMap -{ - PangoFontMap parent_instance; - - Display *display; - - PangoXFontCache *font_cache; - GQueue *freed_fonts; - - GHashTable *families; - GHashTable *size_infos; - - GHashTable *to_atom_cache; - GHashTable *from_atom_cache; - - int n_fonts; - - double resolution; /* (points / pixel) * PANGO_SCALE */ - - Window coverage_win; -}; - struct _PangoXFontMapClass { PangoFontMapClass parent_class; @@ -155,7 +124,6 @@ const struct { { "condensed", PANGO_STRETCH_CONDENSED }, }; -static GType pango_x_font_map_get_type (void); static void pango_x_font_map_init (PangoXFontMap *fontmap); static void pango_x_font_map_class_init (PangoXFontMapClass *class); @@ -186,7 +154,7 @@ static char * pango_x_get_identifier (const char *fontname); static PangoFontClass *parent_class; /* Parent class structure for PangoXFontMap */ -static GType +GType pango_x_font_map_get_type (void) { static GType object_type = 0; diff --git a/pango/pangox-private.h b/pango/pangox-private.h index 57472b55..1549d03e 100644 --- a/pango/pangox-private.h +++ b/pango/pangox-private.h @@ -60,6 +60,41 @@ struct _PangoXFont PangoXFontEntry *entry; /* Used to remove cached fonts */ }; + +#define PANGO_TYPE_X_FONT_MAP (pango_x_font_map_get_type ()) +#define PANGO_X_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_X_FONT_MAP, PangoXFontMap)) +#define PANGO_X_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_X_FONT_MAP, PangoXFontMapClass)) +#define PANGO_X_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_X_FONT_MAP)) +#define PANGO_X_IS_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_X_FONT_MAP)) +#define PANGO_X_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_X_FONT_MAP, PangoXFontMapClass)) + +typedef struct _PangoXFontMap PangoXFontMap; +typedef struct _PangoXFontMapClass PangoXFontMapClass; + +struct _PangoXFontMap +{ + PangoFontMap parent_instance; + + Display *display; + + PangoXFontCache *font_cache; + GQueue *freed_fonts; + + GHashTable *families; + GHashTable *size_infos; + + GHashTable *to_atom_cache; + GHashTable *from_atom_cache; + + int n_fonts; + + double resolution; /* (points / pixel) * PANGO_SCALE */ + + Window coverage_win; +}; + +GType pango_x_font_map_get_type (void); + PangoXFont * pango_x_font_new (PangoFontMap *fontmap, const char *spec, int size); @@ -85,6 +120,7 @@ Atom pango_x_fontmap_atom_from_name (PangoFontMap *fontmap, const char *pango_x_fontmap_name_from_atom (PangoFontMap *fontmap, Atom atom); - +PangoGlyph pango_x_font_get_unknown_glyph (PangoFont *font, + gunichar wc); #endif /* __PANGOX_PRIVATE_H__ */ diff --git a/pango/pangox.c b/pango/pangox.c index ab042efa..f21f1b85 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -31,6 +31,8 @@ #include "pango-intset.h" #include "modules.h" +#define PANGO_X_UNKNOWN_FLAG 0x10000000 + #define PANGO_LIGATURE_HACK_DEBUG #include <config.h> @@ -442,7 +444,106 @@ pango_x_render (Display *display, for (i=0; i<glyphs->num_glyphs; i++) { - if (glyphs->glyphs[i].glyph) + if (glyphs->glyphs[i].glyph & + PANGO_X_UNKNOWN_FLAG) + { + int x1, y1, x2, y2; /* rectangle the character should go inside. */ + int baseline; + PangoFontMetrics metrics; + gunichar wc; + + pango_font_get_metrics (font, NULL, &metrics); + + x1 = (x_off + glyphs->glyphs[i].geometry.x_offset) / PANGO_SCALE; + y1 = y + (glyphs->glyphs[i].geometry.y_offset - metrics.ascent) / PANGO_SCALE; + x2 = x1 + glyphs->glyphs[i].geometry.width / PANGO_SCALE; + y2 = y1 + (metrics.ascent + metrics.descent) / PANGO_SCALE; + baseline = y1 + metrics.ascent / PANGO_SCALE; + + wc = glyphs->glyphs[i].glyph & (~PANGO_X_UNKNOWN_FLAG); + + switch (wc) + { + case '\n': + case '\r': + case 0x2028: /* Line separator */ + case 0x2029: /* Paragraph separator */ + { + /* Draw a carriage-return thingy */ + PangoRectangle up_stroke; + PangoRectangle across_stroke; + int arrowhead_top_x, arrowhead_top_y; + int arrowhead_bottom_x, arrowhead_bottom_y; + int arrowhead_point_x, arrowhead_point_y; + int xoff; + double slope; + int h; + + up_stroke.width = (x2 - x1) * 0.125; + if ((up_stroke.width % 2) == 0) + up_stroke.width -= 1; + up_stroke.height = (y2 - y1) * 0.275; + up_stroke.x = x2 - up_stroke.width; + up_stroke.y = baseline - up_stroke.height - up_stroke.width / 2 - 1; + + across_stroke.width = (x2 - x1) * 0.5; + across_stroke.height = up_stroke.width; + across_stroke.x = up_stroke.x - across_stroke.width; + across_stroke.y = up_stroke.y + up_stroke.height - across_stroke.height; + + h = across_stroke.height * 3.2; + arrowhead_top_x = across_stroke.x; + arrowhead_top_y = across_stroke.y - h; + arrowhead_bottom_x = across_stroke.x; + arrowhead_bottom_y = across_stroke.y + across_stroke.height + h; + + arrowhead_point_x = x1 + (x2 - x1) * 0.14; + arrowhead_point_y = across_stroke.y + across_stroke.height / 2; + + /* require odd size, to line up with the odd-sized stroke */ + if (((arrowhead_top_y - arrowhead_point_y) % 2) == 0) + arrowhead_top_y -= 1; + + XFillRectangle (display, d, gc, + up_stroke.x, up_stroke.y, + up_stroke.width, up_stroke.height); + + XFillRectangle (display, d, gc, + across_stroke.x, across_stroke.y, + across_stroke.width, across_stroke.height); + + slope = + (double)(arrowhead_top_x - arrowhead_point_x) / + (double)(arrowhead_top_y - arrowhead_point_y); + + xoff = arrowhead_point_x; + while (xoff <= arrowhead_top_x) + { + int half_height = ((xoff - arrowhead_point_x) / slope); + + XDrawLine (display, d, gc, + xoff, + arrowhead_point_y - half_height, + xoff, + arrowhead_point_y + half_height); + + ++xoff; + } + } + break; + + default: + + /* Here we should draw the box-with-numbers as in the + * Xft backend. The shaper never gives us a glyph that + * activates this case at the moment though, so also + * needs hacking. + */ + + break; + } + } + else if (glyphs->glyphs[i].glyph) { guint16 index = PANGO_X_GLYPH_INDEX (glyphs->glyphs[i].glyph); guint16 subfont_index = PANGO_X_GLYPH_SUBFONT (glyphs->glyphs[i].glyph); @@ -486,7 +587,52 @@ pango_x_font_get_glyph_extents (PangoFont *font, XCharStruct *cs; PangoXSubfontInfo *subfont; - if (glyph && pango_x_find_glyph (font, glyph, &subfont, &cs)) + if (glyph & PANGO_X_UNKNOWN_FLAG) + { + gunichar wc; + + wc = glyph & (~PANGO_X_UNKNOWN_FLAG); + + switch (wc) + { + case '\n': + case '\r': + case 0x2028: /* Line separator */ + case 0x2029: /* Paragraph separator */ + { + /* Size of carriage-return thingy */ + PangoFontMetrics metrics; + int w; + + pango_font_get_metrics (font, NULL, &metrics); + +#define MAGIC_FACTOR 2.1 + + w = metrics.approximate_char_width * MAGIC_FACTOR; + + if (ink_rect) + { + ink_rect->x = 0; + ink_rect->width = w; + ink_rect->y = - metrics.ascent; + ink_rect->height = metrics.ascent + metrics.descent; + } + if (logical_rect) + { + logical_rect->x = 0; + logical_rect->width = w; + logical_rect->y = - metrics.ascent; + logical_rect->height = metrics.ascent + metrics.descent; + } + } + break; + + default: + + break; + } + } + else if (glyph && pango_x_find_glyph (font, glyph, &subfont, &cs)) { if (ink_rect) { @@ -557,7 +703,7 @@ get_font_metrics_from_subfonts (PangoFont *font, GSList *tmp_list = subfonts; gboolean first = TRUE; int total_avg_widths = 0; - int n_avg_widths = 0; + int n_avg_widths = 0; Atom avg_width_atom; avg_width_atom = pango_x_fontmap_atom_from_name (xfont->fontmap, @@ -590,9 +736,28 @@ get_font_metrics_from_subfonts (PangoFont *font, } } - if (!get_int_prop (avg_width_atom, fs, &avg_width)) - avg_width = (fs->min_bounds.width + fs->max_bounds.width) / 2; - + if (get_int_prop (avg_width_atom, fs, &avg_width)) + { + /* convert decipoints --> pango units. + * Resolution is in (points * PANGO_SCALE) / pixel, + * avg_width in decipoints. + * We want pixels * PANGO_SCALE + */ + + /* Convert to points */ + avg_width = ((double) avg_width) / (double) 10.0; + /* points * PANGO_SCALE */ + avg_width *= PANGO_SCALE; + /* Convert to pixels */ + avg_width /= (double) PANGO_X_FONT_MAP (PANGO_X_FONT (font)->fontmap)->resolution; + /* Convert to pixels * PANGO_SCALE */ + avg_width *= PANGO_SCALE; + } + else + { + avg_width = PANGO_SCALE * ((fs->min_bounds.width + fs->max_bounds.width) / 2); + } + total_avg_widths += avg_width; n_avg_widths += 1; } @@ -640,7 +805,7 @@ get_font_metrics_from_string (PangoFont *font, last_shaper = NULL; last_level = 0; - + i = 0; p = start = str; while (*p) @@ -789,14 +954,14 @@ pango_x_font_get_metrics (PangoFont *font, xfont->metrics_by_lang = g_slist_prepend (xfont->metrics_by_lang, info); - get_font_metrics_from_string (font, lang, str, &info->metrics); + get_font_metrics_from_string (font, lookup_lang, str, &info->metrics); /* This is sort of a sledgehammer solution, but we cache this * stuff so not a huge deal hopefully. Get the avg. width of the * chars in "0123456789" */ context = pango_x_get_context (pango_x_fontmap_get_display (xfont->fontmap)); - pango_context_set_lang (context, lang); + pango_context_set_lang (context, lookup_lang); layout = pango_layout_new (context); pango_layout_set_text (layout, "0123456789", -1); @@ -1952,3 +2117,23 @@ pango_x_fallback_shape (PangoFont *font, p = g_utf8_next_char (p); } } + +PangoGlyph +pango_x_font_get_unknown_glyph (PangoFont *font, + gunichar wc) +{ + g_return_val_if_fail (PANGO_IS_FONT (font), 0); + + switch (wc) + { + case '\n': + case '\r': + case 0x2028: /* Line separator */ + case 0x2029: /* Paragraph separator */ + return PANGO_X_UNKNOWN_FLAG | wc; + break; + default: + return 0; + break; + } +} |