summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2001-04-27 23:50:03 +0000
committerHavoc Pennington <hp@src.gnome.org>2001-04-27 23:50:03 +0000
commit54fe82fbb797d6c72c81e629cba28fd803df7122 (patch)
treefdc77f4e259a37146f30d96b9724477f9702b970 /pango
parent374817f27422db4a5d4c68c423607ff560e53140 (diff)
downloadpango-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.c58
-rw-r--r--pango/pango-layout.h4
-rw-r--r--pango/pangox-fontmap.c34
-rw-r--r--pango/pangox-private.h38
-rw-r--r--pango/pangox.c203
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;
+ }
+}