summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2004-03-01 15:23:15 +0000
committerOwen Taylor <otaylor@src.gnome.org>2004-03-01 15:23:15 +0000
commit509868236b87e04a9367630bf9c441e5d1399698 (patch)
tree18a36e76e9942738fd16d278ba4e7cea1c26aad9
parentfa8ac6be9ea65de7f4f0c15ff68c0ff9ddb4b189 (diff)
downloadpango-509868236b87e04a9367630bf9c441e5d1399698.tar.gz
Patch from Dov Grobgeld to add auto-direction to PangoLayout (more of
Fri Feb 27 11:23:21 2004 Owen Taylor <otaylor@redhat.com> Patch from Dov Grobgeld to add auto-direction to PangoLayout (more of #70451) * examples/pangofttopgm.c: Add --no-auto-dir argument. * pango-layout.[ch]: Add pango_layout_set_auto_dir() defaulting to TRUE; resolve paragraph direction within a layout by propagating base direction downwards from paragraph to paragraph. * pango-context.[ch]: Add pango_itemize_with_base_dir() which overrides the base direction from the PangoContext. Mon Mar 1 10:01:58 2004 Owen Taylor <otaylor@redhat.com> * docs/tmpl/text-attributes.sgml: Document %PANGO_UNDERLINE_ERROR. * pango/pangofc-fontmap.c: Pango*Fc*FontmapPrivate. Make compile.
-rw-r--r--ChangeLog21
-rw-r--r--ChangeLog.pre-1-1021
-rw-r--r--ChangeLog.pre-1-421
-rw-r--r--ChangeLog.pre-1-621
-rw-r--r--ChangeLog.pre-1-821
-rw-r--r--docs/pango-sections.txt2
-rw-r--r--docs/tmpl/text-attributes.sgml5
-rw-r--r--examples/pangoft2topgm.c5
-rw-r--r--examples/renderdemo.c5
-rw-r--r--pango/pango-context.c72
-rw-r--r--pango/pango-context.h20
-rw-r--r--pango/pango-layout.c229
-rw-r--r--pango/pango-layout.h4
-rw-r--r--pango/pangofc-fontmap.c2
14 files changed, 368 insertions, 81 deletions
diff --git a/ChangeLog b/ChangeLog
index c2e1d4e7..a668c886 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+Fri Feb 27 11:23:21 2004 Owen Taylor <otaylor@redhat.com>
+
+ Patch from Dov Grobgeld to add auto-direction to PangoLayout
+ (more of #70451)
+
+ * examples/pangofttopgm.c: Add --no-auto-dir argument.
+
+ * pango-layout.[ch]: Add pango_layout_set_auto_dir()
+ defaulting to TRUE; resolve paragraph direction within
+ a layout by propagating base direction downwards
+ from paragraph to paragraph.
+
+ * pango-context.[ch]: Add pango_itemize_with_base_dir()
+ which overrides the base direction from the PangoContext.
+
+Mon Mar 1 10:01:58 2004 Owen Taylor <otaylor@redhat.com>
+
+ * docs/tmpl/text-attributes.sgml: Document %PANGO_UNDERLINE_ERROR.
+
+ * pango/pangofc-fontmap.c: Pango*Fc*FontmapPrivate. Make compile.
+
2004-03-01 Murray Cumming <murrayc@murrayc.com>
* pango/pango-attributes.h: Removed trailing commas from the
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index c2e1d4e7..a668c886 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,24 @@
+Fri Feb 27 11:23:21 2004 Owen Taylor <otaylor@redhat.com>
+
+ Patch from Dov Grobgeld to add auto-direction to PangoLayout
+ (more of #70451)
+
+ * examples/pangofttopgm.c: Add --no-auto-dir argument.
+
+ * pango-layout.[ch]: Add pango_layout_set_auto_dir()
+ defaulting to TRUE; resolve paragraph direction within
+ a layout by propagating base direction downwards
+ from paragraph to paragraph.
+
+ * pango-context.[ch]: Add pango_itemize_with_base_dir()
+ which overrides the base direction from the PangoContext.
+
+Mon Mar 1 10:01:58 2004 Owen Taylor <otaylor@redhat.com>
+
+ * docs/tmpl/text-attributes.sgml: Document %PANGO_UNDERLINE_ERROR.
+
+ * pango/pangofc-fontmap.c: Pango*Fc*FontmapPrivate. Make compile.
+
2004-03-01 Murray Cumming <murrayc@murrayc.com>
* pango/pango-attributes.h: Removed trailing commas from the
diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4
index c2e1d4e7..a668c886 100644
--- a/ChangeLog.pre-1-4
+++ b/ChangeLog.pre-1-4
@@ -1,3 +1,24 @@
+Fri Feb 27 11:23:21 2004 Owen Taylor <otaylor@redhat.com>
+
+ Patch from Dov Grobgeld to add auto-direction to PangoLayout
+ (more of #70451)
+
+ * examples/pangofttopgm.c: Add --no-auto-dir argument.
+
+ * pango-layout.[ch]: Add pango_layout_set_auto_dir()
+ defaulting to TRUE; resolve paragraph direction within
+ a layout by propagating base direction downwards
+ from paragraph to paragraph.
+
+ * pango-context.[ch]: Add pango_itemize_with_base_dir()
+ which overrides the base direction from the PangoContext.
+
+Mon Mar 1 10:01:58 2004 Owen Taylor <otaylor@redhat.com>
+
+ * docs/tmpl/text-attributes.sgml: Document %PANGO_UNDERLINE_ERROR.
+
+ * pango/pangofc-fontmap.c: Pango*Fc*FontmapPrivate. Make compile.
+
2004-03-01 Murray Cumming <murrayc@murrayc.com>
* pango/pango-attributes.h: Removed trailing commas from the
diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6
index c2e1d4e7..a668c886 100644
--- a/ChangeLog.pre-1-6
+++ b/ChangeLog.pre-1-6
@@ -1,3 +1,24 @@
+Fri Feb 27 11:23:21 2004 Owen Taylor <otaylor@redhat.com>
+
+ Patch from Dov Grobgeld to add auto-direction to PangoLayout
+ (more of #70451)
+
+ * examples/pangofttopgm.c: Add --no-auto-dir argument.
+
+ * pango-layout.[ch]: Add pango_layout_set_auto_dir()
+ defaulting to TRUE; resolve paragraph direction within
+ a layout by propagating base direction downwards
+ from paragraph to paragraph.
+
+ * pango-context.[ch]: Add pango_itemize_with_base_dir()
+ which overrides the base direction from the PangoContext.
+
+Mon Mar 1 10:01:58 2004 Owen Taylor <otaylor@redhat.com>
+
+ * docs/tmpl/text-attributes.sgml: Document %PANGO_UNDERLINE_ERROR.
+
+ * pango/pangofc-fontmap.c: Pango*Fc*FontmapPrivate. Make compile.
+
2004-03-01 Murray Cumming <murrayc@murrayc.com>
* pango/pango-attributes.h: Removed trailing commas from the
diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8
index c2e1d4e7..a668c886 100644
--- a/ChangeLog.pre-1-8
+++ b/ChangeLog.pre-1-8
@@ -1,3 +1,24 @@
+Fri Feb 27 11:23:21 2004 Owen Taylor <otaylor@redhat.com>
+
+ Patch from Dov Grobgeld to add auto-direction to PangoLayout
+ (more of #70451)
+
+ * examples/pangofttopgm.c: Add --no-auto-dir argument.
+
+ * pango-layout.[ch]: Add pango_layout_set_auto_dir()
+ defaulting to TRUE; resolve paragraph direction within
+ a layout by propagating base direction downwards
+ from paragraph to paragraph.
+
+ * pango-context.[ch]: Add pango_itemize_with_base_dir()
+ which overrides the base direction from the PangoContext.
+
+Mon Mar 1 10:01:58 2004 Owen Taylor <otaylor@redhat.com>
+
+ * docs/tmpl/text-attributes.sgml: Document %PANGO_UNDERLINE_ERROR.
+
+ * pango/pangofc-fontmap.c: Pango*Fc*FontmapPrivate. Make compile.
+
2004-03-01 Murray Cumming <murrayc@murrayc.com>
* pango/pango-attributes.h: Removed trailing commas from the
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index b5bb99d0..5fa5dab8 100644
--- a/docs/pango-sections.txt
+++ b/docs/pango-sections.txt
@@ -389,6 +389,8 @@ pango_layout_get_spacing
pango_layout_set_spacing
pango_layout_set_justify
pango_layout_get_justify
+pango_layout_set_auto_dir
+pango_layout_get_auto_dir
pango_layout_set_alignment
pango_layout_get_alignment
pango_layout_set_tabs
diff --git a/docs/tmpl/text-attributes.sgml b/docs/tmpl/text-attributes.sgml
index 4707232f..aa8445cd 100644
--- a/docs/tmpl/text-attributes.sgml
+++ b/docs/tmpl/text-attributes.sgml
@@ -322,6 +322,11 @@ of underlining.
single characters, such as for keyboard
accelerators. %PANGO_UNDERLINE_SINGLE should
be used for extended portions of text.
+@PANGO_UNDERLINE_ERROR: a wavy underline should be drawn below.
+ This underline is typically used to indicate
+ an error such as a possilble mispelling; in some
+ cases an contrasting color may automatically
+ be used.
<!-- ##### MACRO PANGO_TYPE_UNDERLINE ##### -->
<para>
diff --git a/examples/pangoft2topgm.c b/examples/pangoft2topgm.c
index 60f93468..277dec51 100644
--- a/examples/pangoft2topgm.c
+++ b/examples/pangoft2topgm.c
@@ -54,6 +54,7 @@ static char *opt_output = NULL;
static int opt_margin = 10;
static int opt_markup = FALSE;
static gboolean opt_rtl = FALSE;
+static gboolean opt_auto_dir = TRUE;
static char *opt_text = NULL;
static gboolean opt_waterfall = FALSE;
static int opt_width = -1;
@@ -106,6 +107,8 @@ make_layout(PangoContext *context,
else
pango_layout_set_text (layout, text, -1);
+ pango_layout_set_auto_dir (layout, opt_auto_dir);
+
font_description = get_font_description ();
if (size > 0)
pango_font_description_set_size (font_description, size * PANGO_SCALE);
@@ -240,6 +243,8 @@ int main(int argc, char *argv[])
gboolean do_convert = FALSE;
static const ArgDesc args[] = {
+ { "no-auto-dir","Don't set layout direction according to contents",
+ ARG_NOBOOL, &opt_auto_dir },
{ "display", "Show output using ImageMagick",
ARG_BOOL, &opt_display },
{ "dpi", "Set the dpi'",
diff --git a/examples/renderdemo.c b/examples/renderdemo.c
index 60f93468..277dec51 100644
--- a/examples/renderdemo.c
+++ b/examples/renderdemo.c
@@ -54,6 +54,7 @@ static char *opt_output = NULL;
static int opt_margin = 10;
static int opt_markup = FALSE;
static gboolean opt_rtl = FALSE;
+static gboolean opt_auto_dir = TRUE;
static char *opt_text = NULL;
static gboolean opt_waterfall = FALSE;
static int opt_width = -1;
@@ -106,6 +107,8 @@ make_layout(PangoContext *context,
else
pango_layout_set_text (layout, text, -1);
+ pango_layout_set_auto_dir (layout, opt_auto_dir);
+
font_description = get_font_description ();
if (size > 0)
pango_font_description_set_size (font_description, size * PANGO_SCALE);
@@ -240,6 +243,8 @@ int main(int argc, char *argv[])
gboolean do_convert = FALSE;
static const ArgDesc args[] = {
+ { "no-auto-dir","Don't set layout direction according to contents",
+ ARG_NOBOOL, &opt_auto_dir },
{ "display", "Show output using ImageMagick",
ARG_BOOL, &opt_display },
{ "dpi", "Set the dpi'",
diff --git a/pango/pango-context.c b/pango/pango-context.c
index e0c67879..51a467d3 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -592,12 +592,12 @@ static void
itemize_state_init (ItemizeState *state,
PangoContext *context,
const char *text,
+ PangoDirection base_dir,
int start_index,
int length,
PangoAttrList *attrs,
PangoAttrIterator *cached_iter)
{
- PangoDirection base_dir;
gunichar *text_ucs4;
long n_chars;
@@ -613,8 +613,6 @@ itemize_state_init (ItemizeState *state,
/* First, apply the bidirectional algorithm to break
* the text into directional runs.
*/
- base_dir = context->base_dir;
-
text_ucs4 = g_utf8_to_ucs4_fast (text + start_index, length, &n_chars);
state->embedding_levels = g_new (guint8, n_chars);
pango_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
@@ -1069,10 +1067,61 @@ itemize_state_finish (ItemizeState *state)
}
/**
+ * pango_itemize_with_base_dir:
+ * @context: a structure holding information that affects
+ the itemization process.
+ * @text: the text to itemize.
+ * @start_index: first byte in @text to process
+ * @length: the number of bytes (not characters) to process
+ * after @start_index.
+ * This must be >= 0.
+ * @base_dir: base direction to use for bidirectional processing
+ * @attrs: the set of attributes that apply to @text.
+ * @cached_iter: Cached attribute iterator, or NULL
+ *
+ * Like pango_itemize(), but the base direction to use when
+ * computing bidirectional levels (see pango_context_set_base_dir ()),
+ * is specified explicitely rather than gotten from the #PangoContext.
+ *
+ * Return value: a GList of PangoItem structures.
+ */
+GList *
+pango_itemize_with_base_dir (PangoContext *context,
+ PangoDirection base_dir,
+ const char *text,
+ int start_index,
+ int length,
+ PangoAttrList *attrs,
+ PangoAttrIterator *cached_iter)
+{
+ ItemizeState state;
+
+ g_return_val_if_fail (context != NULL, NULL);
+ g_return_val_if_fail (start_index >= 0, NULL);
+ g_return_val_if_fail (length >= 0, NULL);
+ g_return_val_if_fail (length == 0 || text != NULL, NULL);
+
+ if (length == 0)
+ return NULL;
+
+ itemize_state_init (&state, context, text, base_dir, start_index, length,
+ attrs, cached_iter);
+
+ do
+ itemize_state_process_run (&state);
+ while (itemize_state_next (&state));
+
+ itemize_state_finish (&state);
+
+ return g_list_reverse (state.result);
+}
+
+/**
* pango_itemize:
* @context: a structure holding information that affects
the itemization process.
* @text: the text to itemize.
+ * @base_dir: base direction to use for BiDi algorithm.
* @start_index: first byte in @text to process
* @length: the number of bytes (not characters) to process
* after @start_index.
@@ -1101,26 +1150,13 @@ pango_itemize (PangoContext *context,
PangoAttrList *attrs,
PangoAttrIterator *cached_iter)
{
- ItemizeState state;
-
g_return_val_if_fail (context != NULL, NULL);
g_return_val_if_fail (start_index >= 0, NULL);
g_return_val_if_fail (length >= 0, NULL);
g_return_val_if_fail (length == 0 || text != NULL, NULL);
- if (length == 0)
- return NULL;
-
- itemize_state_init (&state, context, text, start_index, length,
- attrs, cached_iter);
-
- do
- itemize_state_process_run (&state);
- while (itemize_state_next (&state));
-
- itemize_state_finish (&state);
-
- return g_list_reverse (state.result);
+ return pango_itemize_with_base_dir (context, context->base_dir,
+ text, start_index, length, attrs, cached_iter);
}
/**
diff --git a/pango/pango-context.h b/pango/pango-context.h
index 078e841f..878c3c28 100644
--- a/pango/pango-context.h
+++ b/pango/pango-context.h
@@ -82,13 +82,19 @@ PangoDirection pango_context_get_base_dir (PangoContext
* consistent shaping/language engine and bidrectional level.
* Returns a GList of PangoItem's
*/
-GList *pango_itemize (PangoContext *context,
- const char *text,
- int start_index,
- int length,
- PangoAttrList *attrs,
- PangoAttrIterator *cached_iter);
-
+GList *pango_itemize (PangoContext *context,
+ const char *text,
+ int start_index,
+ int length,
+ PangoAttrList *attrs,
+ PangoAttrIterator *cached_iter);
+GList *pango_itemize_with_base_dir (PangoContext *context,
+ PangoDirection base_dir,
+ const char *text,
+ int start_index,
+ int length,
+ PangoAttrList *attrs,
+ PangoAttrIterator *cached_iter);
G_END_DECLS
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index c09d238f..ae5580b3 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -117,6 +117,7 @@ struct _PangoLayout
guint alignment : 2;
guint single_paragraph : 1;
+ guint auto_dir : 1;
gint n_chars; /* Total number of characters in layout */
PangoLogAttr *log_attrs; /* Logical attributes for layout's text */
@@ -203,6 +204,7 @@ pango_layout_init (PangoLayout *layout)
layout->alignment = PANGO_ALIGN_LEFT;
layout->justify = FALSE;
+ layout->auto_dir = TRUE;
layout->log_attrs = NULL;
layout->lines = NULL;
@@ -591,6 +593,63 @@ pango_layout_get_justify (PangoLayout *layout)
}
/**
+ * pango_layout_set_auto_dir:
+ * @layout: a #PangoLayout
+ * @auto_dir: if %TRUE, compute the bidirectional base direction
+ * from the layout's contents.
+ *
+ * Sets whether to calculate the bidirectional base direction
+ * for the layout according to the contents of the layout;
+ * when this flag is on (the default), then paragraphs in
+ @layout that begin with strong right-to-left characters
+ * (Arabic and Hebrew principally), will have right-to-left
+ * layout, paragraphs with letters from other scripts will
+ * have left-to-right layout. Paragraphs with only neutral
+ * characters get their direction from the surrounding paragraphs.
+ *
+ * When %FALSE, the choice between left-to-right and
+ * right-to-left layout is done by according to the base direction
+ * of the layout's #PangoContext. (See pango_context_set_base_dir()).
+ *
+ * When the auto-computed direction or a paragraph differs from the
+ * base direction of the context, then the interpretation of
+ * %PANGO_ALIGN_LEFT and %PANGO_ALIGN_RIGHT are swapped.
+ **/
+void
+pango_layout_set_auto_dir (PangoLayout *layout,
+ gboolean auto_dir)
+{
+ g_return_if_fail (PANGO_IS_LAYOUT (layout));
+
+ auto_dir = auto_dir != FALSE;
+
+ if (auto_dir != layout->auto_dir)
+ {
+ layout->auto_dir = auto_dir;
+ pango_layout_clear_lines (layout);
+ }
+}
+
+/**
+ * pango_layout_get_auto_dir:
+ * @layout: a #PangoLayout
+ *
+ * Gets whether to calculate the bidirectional base direction
+ * for the layout according to the contents of the layout.
+ * See pango_layout_set_auto_dir().
+ *
+ * Return value: if %TRUE, the bidirectional base direction
+ * is computed from the layout's contents.
+ **/
+gboolean
+pango_layout_get_auto_dir (PangoLayout *layout)
+{
+ g_return_val_if_fail (PANGO_IS_LAYOUT (layout), FALSE);
+
+ return layout->auto_dir;
+}
+
+/**
* pango_layout_set_alignment:
* @layout: a #PangoLayout
* @alignment: the new alignment
@@ -1222,7 +1281,6 @@ pango_layout_move_cursor_visually (PangoLayout *layout,
int *new_index,
int *new_trailing)
{
- PangoDirection base_dir;
PangoLayoutLine *line = NULL;
PangoLayoutLine *prev_line;
PangoLayoutLine *next_line;
@@ -1243,12 +1301,10 @@ pango_layout_move_cursor_visually (PangoLayout *layout,
pango_layout_check_lines (layout);
- base_dir = pango_context_get_base_dir (layout->context);
-
/* Find the line the old cursor is on */
line = pango_layout_index_to_line (layout, old_index,
NULL, &prev_line, &next_line);
-
+
start_offset = g_utf8_pointer_to_offset (layout->text, layout->text + line->start_index);
while (old_trailing--)
@@ -1267,14 +1323,14 @@ pango_layout_move_cursor_visually (PangoLayout *layout,
/* Handling movement between lines */
if (vis_pos == 0 && direction < 0)
{
- if (base_dir == PANGO_DIRECTION_LTR)
+ if (line->resolved_dir == PANGO_DIRECTION_LTR)
off_start = TRUE;
else
off_end = TRUE;
}
else if (vis_pos == n_vis && direction > 0)
{
- if (base_dir == PANGO_DIRECTION_LTR)
+ if (line->resolved_dir == PANGO_DIRECTION_LTR)
off_end = TRUE;
else
off_start = TRUE;
@@ -1550,7 +1606,6 @@ pango_layout_line_get_vis2log_map (PangoLayoutLine *line,
gboolean strong)
{
PangoLayout *layout = line->layout;
- PangoDirection base_dir = pango_context_get_base_dir (layout->context);
PangoDirection prev_dir;
PangoDirection cursor_dir;
GSList *tmp_list;
@@ -1565,16 +1620,16 @@ pango_layout_line_get_vis2log_map (PangoLayoutLine *line,
result = g_new (int, n_chars + 1);
if (strong)
- cursor_dir = base_dir;
+ cursor_dir = line->resolved_dir;
else
- cursor_dir = (base_dir == PANGO_DIRECTION_LTR) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
+ cursor_dir = (line->resolved_dir == PANGO_DIRECTION_LTR) ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
/* Handle the first visual position
*/
- if (base_dir == cursor_dir)
- result[0] = base_dir == PANGO_DIRECTION_LTR ? 0 : end - start;
+ if (line->resolved_dir == cursor_dir)
+ result[0] = line->resolved_dir == PANGO_DIRECTION_LTR ? 0 : end - start;
- prev_dir = base_dir;
+ prev_dir = line->resolved_dir;
pos = 0;
tmp_list = line->runs;
while (tmp_list)
@@ -1630,8 +1685,8 @@ pango_layout_line_get_vis2log_map (PangoLayoutLine *line,
/* And the last visual position
*/
- if ((cursor_dir == base_dir) || (prev_dir == base_dir))
- result[pos] = base_dir == PANGO_DIRECTION_LTR ? end - start : 0;
+ if ((cursor_dir == line->resolved_dir) || (prev_dir == line->resolved_dir))
+ result[pos] = line->resolved_dir == PANGO_DIRECTION_LTR ? end - start : 0;
return result;
}
@@ -1704,7 +1759,6 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
PangoRectangle *strong_pos,
PangoRectangle *weak_pos)
{
- PangoDirection base_dir;
PangoDirection dir1, dir2;
PangoRectangle line_rect;
PangoLayoutLine *layout_line = NULL; /* Quiet GCC */
@@ -1714,8 +1768,6 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
g_return_if_fail (layout != NULL);
g_return_if_fail (index >= 0 && index <= layout->length);
- base_dir = pango_context_get_base_dir (layout->context);
-
layout_line = pango_layout_index_to_line_and_extents (layout, index,
&line_rect);
@@ -1724,8 +1776,8 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
/* Examine the trailing edge of the character before the cursor */
if (index == layout_line->start_index)
{
- dir1 = base_dir;
- if (base_dir == PANGO_DIRECTION_LTR)
+ dir1 = layout_line->resolved_dir;
+ if (layout_line->resolved_dir == PANGO_DIRECTION_LTR)
x1_trailing = 0;
else
x1_trailing = line_rect.width;
@@ -1740,8 +1792,8 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
/* Examine the leading edge of the character after the cursor */
if (index >= layout_line->start_index + layout_line->length)
{
- dir2 = base_dir;
- if (base_dir == PANGO_DIRECTION_LTR)
+ dir2 = layout_line->resolved_dir;
+ if (layout_line->resolved_dir == PANGO_DIRECTION_LTR)
x2 = line_rect.width;
else
x2 = 0;
@@ -1756,7 +1808,7 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
{
strong_pos->x = line_rect.x;
- if (dir1 == base_dir)
+ if (dir1 == layout_line->resolved_dir)
strong_pos->x += x1_trailing;
else
strong_pos->x += x2;
@@ -1770,7 +1822,7 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
{
weak_pos->x = line_rect.x;
- if (dir1 == base_dir)
+ if (dir1 == layout_line->resolved_dir)
weak_pos->x += x2;
else
weak_pos->x += x1_trailing;
@@ -1781,6 +1833,24 @@ pango_layout_get_cursor_pos (PangoLayout *layout,
}
}
+static PangoAlignment
+get_alignment (PangoLayout *layout,
+ PangoLayoutLine *line)
+{
+ PangoAlignment alignment = layout->alignment;
+
+ if (line->layout->auto_dir &&
+ line->resolved_dir != pango_context_get_base_dir (layout->context))
+ {
+ if (alignment == PANGO_ALIGN_LEFT)
+ alignment = PANGO_ALIGN_RIGHT;
+ else if (alignment == PANGO_ALIGN_RIGHT)
+ alignment = PANGO_ALIGN_LEFT;
+ }
+
+ return alignment;
+}
+
static void
get_x_offset (PangoLayout *layout,
PangoLayoutLine *line,
@@ -1788,10 +1858,12 @@ get_x_offset (PangoLayout *layout,
int line_width,
int *x_offset)
{
+ PangoAlignment alignment = get_alignment (layout, line);
+
/* Alignment */
- if (layout->alignment == PANGO_ALIGN_RIGHT)
+ if (alignment == PANGO_ALIGN_RIGHT)
*x_offset = layout_width - line_width;
- else if (layout->alignment == PANGO_ALIGN_CENTER)
+ else if (alignment == PANGO_ALIGN_CENTER)
*x_offset = (layout_width - line_width) / 2;
else
*x_offset = 0;
@@ -1805,14 +1877,14 @@ get_x_offset (PangoLayout *layout,
* knowing whether left/right is the "normal" thing for this text
*/
- if (layout->alignment == PANGO_ALIGN_CENTER)
+ if (alignment == PANGO_ALIGN_CENTER)
return;
if (line->is_paragraph_start)
{
if (layout->indent > 0)
{
- if (layout->alignment == PANGO_ALIGN_LEFT)
+ if (alignment == PANGO_ALIGN_LEFT)
*x_offset += layout->indent;
else
*x_offset -= layout->indent;
@@ -1822,7 +1894,7 @@ get_x_offset (PangoLayout *layout,
{
if (layout->indent < 0)
{
- if (layout->alignment == PANGO_ALIGN_LEFT)
+ if (alignment == PANGO_ALIGN_LEFT)
*x_offset -= layout->indent;
else
*x_offset += layout->indent;
@@ -1880,7 +1952,8 @@ pango_layout_get_extents_internal (PangoLayout *layout,
GSList *line_list;
int y_offset = 0;
int width;
-
+ gboolean need_width = FALSE;
+
g_return_if_fail (layout != NULL);
pango_layout_check_lines (layout);
@@ -1890,7 +1963,28 @@ pango_layout_get_extents_internal (PangoLayout *layout,
* x_offsets if we are computing the ink_rect or individual line extents.
*/
width = layout->width;
- if (width == -1 && layout->alignment != PANGO_ALIGN_LEFT && (ink_rect || line_extents))
+
+ /* If one of the lines of the layout is not left aligned, then we need
+ * the width of the width to calculate line x-offsets; this requires
+ * looping through the lines for layout->auto_dir.
+ */
+ if (layout->auto_dir)
+ {
+ line_list = layout->lines;
+ while (line_list)
+ {
+ PangoLayoutLine *line = line_list->data;
+
+ if (get_alignment (layout, line) != PANGO_ALIGN_LEFT)
+ need_width = TRUE;
+
+ line_list = line_list->next;
+ }
+ }
+ else if (layout->alignment != PANGO_ALIGN_LEFT)
+ need_width = TRUE;
+
+ if (width == -1 && need_width && (ink_rect || line_extents))
{
PangoRectangle overall_logical;
@@ -2482,6 +2576,7 @@ typedef struct _ParaBreakState ParaBreakState;
struct _ParaBreakState
{
GList *items; /* This paragraph turned into items */
+ PangoDirection base_dir; /* Current resolved base direction */
gboolean first_line; /* TRUE if this is the first line of the paragraph */
int line_start_index; /* Start index of line in layout->text */
@@ -2731,6 +2826,7 @@ process_line (PangoLayout *layout,
line = pango_layout_line_new (layout);
line->start_index = state->line_start_index;
line->is_paragraph_start = state->first_line;
+ line->resolved_dir = state->base_dir;
if (state->first_line)
state->remaining_width = (layout->indent >= 0) ? layout->width - layout->indent : layout->width;
@@ -2945,6 +3041,7 @@ pango_layout_check_lines (PangoLayout *layout)
PangoAttrList *attrs;
PangoAttrList *no_shape_attrs;
PangoAttrIterator *iter;
+ PangoDirection prev_base_dir = PANGO_DIRECTION_NEUTRAL, base_dir = PANGO_DIRECTION_NEUTRAL;
if (layout->lines)
return;
@@ -2965,6 +3062,16 @@ pango_layout_check_lines (PangoLayout *layout)
start_offset = 0;
start = layout->text;
+
+ /* Find the first strong direction of the text */
+ if (layout->auto_dir)
+ {
+ prev_base_dir = pango_find_base_dir (layout->text, layout->length);
+ if (prev_base_dir == PANGO_DIRECTION_NEUTRAL)
+ prev_base_dir = pango_context_get_base_dir (layout->context);
+ }
+ else
+ base_dir = pango_context_get_base_dir (layout->context);
do
{
@@ -2987,7 +3094,18 @@ pango_layout_check_lines (PangoLayout *layout)
}
g_assert (next_para_index >= delimiter_index);
-
+
+ if (layout->auto_dir)
+ {
+ base_dir = pango_find_base_dir (start, delimiter_index);
+
+ /* Propagate the base direction for neutral paragraphs */
+ if (base_dir == PANGO_DIRECTION_NEUTRAL)
+ base_dir = prev_base_dir;
+ else
+ prev_base_dir = base_dir;
+ }
+
end = start + delimiter_index;
delim_len = next_para_index - delimiter_index;
@@ -3000,12 +3118,13 @@ pango_layout_check_lines (PangoLayout *layout)
g_assert (delim_len < 4); /* PS is 3 bytes */
g_assert (delim_len >= 0);
- state.items = pango_itemize (layout->context,
- layout->text,
- start - layout->text,
- end - start,
- attrs,
- iter);
+ state.items = pango_itemize_with_base_dir (layout->context,
+ base_dir,
+ layout->text,
+ start - layout->text,
+ end - start,
+ attrs,
+ iter);
get_items_log_attrs (start, state.items,
layout->log_attrs + start_offset,
@@ -3014,6 +3133,7 @@ pango_layout_check_lines (PangoLayout *layout)
if (state.items)
{
state.first_line = TRUE;
+ state.base_dir = base_dir;
state.start_offset = start_offset;
state.line_start_index = start - layout->text;
@@ -3029,7 +3149,8 @@ pango_layout_check_lines (PangoLayout *layout)
empty_line = pango_layout_line_new (layout);
empty_line->start_index = start - layout->text;
- empty_line->is_paragraph_start = TRUE;
+ empty_line->is_paragraph_start = TRUE;
+ empty_line->resolved_dir = base_dir;
layout->lines = g_slist_prepend (layout->lines,
empty_line);
@@ -3133,7 +3254,6 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
gint last_offset;
gint end_index; /* end iterator for line */
gint end_offset; /* end iterator for line */
- PangoDirection base_dir;
PangoLayout *layout;
gint last_trailing;
gboolean suppress_last_trailing;
@@ -3146,8 +3266,6 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
layout = line->layout;
- base_dir = pango_context_get_base_dir (layout->context);
-
/* Find the last index in the line
*/
first_index = line->start_index;
@@ -3218,10 +3336,10 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
{
/* pick the leftmost char */
if (index)
- *index = (base_dir == PANGO_DIRECTION_LTR) ? first_index : last_index;
+ *index = (line->resolved_dir == PANGO_DIRECTION_LTR) ? first_index : last_index;
/* and its leftmost edge */
if (trailing)
- *trailing = (base_dir == PANGO_DIRECTION_LTR || suppress_last_trailing) ? 0 : last_trailing;
+ *trailing = (line->resolved_dir == PANGO_DIRECTION_LTR || suppress_last_trailing) ? 0 : last_trailing;
return FALSE;
}
@@ -3308,11 +3426,11 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
/* pick the rightmost char */
if (index)
- *index = (base_dir == PANGO_DIRECTION_LTR) ? last_index : first_index;
+ *index = (line->resolved_dir == PANGO_DIRECTION_LTR) ? last_index : first_index;
/* and its rightmost edge */
if (trailing)
- *trailing = (base_dir == PANGO_DIRECTION_LTR && !suppress_last_trailing) ? last_trailing : 0;
+ *trailing = (line->resolved_dir == PANGO_DIRECTION_LTR && !suppress_last_trailing) ? last_trailing : 0;
return FALSE;
}
@@ -3351,7 +3469,6 @@ pango_layout_line_get_x_ranges (PangoLayoutLine *line,
int **ranges,
int *n_ranges)
{
- PangoDirection base_dir;
PangoRectangle logical_rect;
gint line_start_index = 0;
GSList *tmp_list;
@@ -3359,15 +3476,16 @@ pango_layout_line_get_x_ranges (PangoLayoutLine *line,
int accumulated_width = 0;
int x_offset;
int width;
-
+ PangoAlignment alignment;
+
g_return_if_fail (line != NULL);
g_return_if_fail (line->layout != NULL);
g_return_if_fail (start_index <= end_index);
- base_dir = pango_context_get_base_dir (line->layout->context);
+ alignment = get_alignment (line->layout, line);
width = line->layout->width;
- if (width == -1 && line->layout->alignment != PANGO_ALIGN_LEFT)
+ if (width == -1 && alignment != PANGO_ALIGN_LEFT)
{
pango_layout_get_extents (line->layout, NULL, &logical_rect);
width = logical_rect.width;
@@ -3389,8 +3507,8 @@ pango_layout_line_get_x_ranges (PangoLayoutLine *line,
*ranges = g_new (int, 2 * (2 + g_slist_length (line->runs)));
if (x_offset > 0 &&
- ((base_dir == PANGO_DIRECTION_LTR && start_index < line_start_index) ||
- (base_dir == PANGO_DIRECTION_RTL && end_index > line_start_index + line->length)))
+ ((line->resolved_dir == PANGO_DIRECTION_LTR && start_index < line_start_index) ||
+ (line->resolved_dir == PANGO_DIRECTION_RTL && end_index > line_start_index + line->length)))
{
if (ranges)
{
@@ -3454,8 +3572,8 @@ pango_layout_line_get_x_ranges (PangoLayoutLine *line,
}
if (x_offset + logical_rect.width < line->layout->width &&
- ((base_dir == PANGO_DIRECTION_LTR && end_index > line_start_index + line->length) ||
- (base_dir == PANGO_DIRECTION_RTL && start_index < line_start_index)))
+ ((line->resolved_dir == PANGO_DIRECTION_LTR && end_index > line_start_index + line->length) ||
+ (line->resolved_dir == PANGO_DIRECTION_RTL && start_index < line_start_index)))
{
if (ranges)
{
@@ -3735,8 +3853,9 @@ pango_layout_line_new (PangoLayout *layout)
private->line.runs = 0;
private->line.length = 0;
- /* Note that we leave start_index and is_paragraph_start uninitialized */
-
+ /* Note that we leave start_index, resolved_dir, and is_paragraph_start
+ * uninitialized */
+
return (PangoLayoutLine *) private;
}
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index b490cedd..4d11cdf3 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -55,6 +55,7 @@ struct _PangoLayoutLine
gint length; /* length of line in bytes */
GSList *runs;
guint is_paragraph_start : 1; /* TRUE if this is the first line of the paragraph */
+ guint resolved_dir : 3; /* Resolved direction of line */
};
#define PANGO_TYPE_LAYOUT (pango_layout_get_type ())
@@ -111,6 +112,9 @@ int pango_layout_get_spacing (PangoLayout *la
void pango_layout_set_justify (PangoLayout *layout,
gboolean justify);
gboolean pango_layout_get_justify (PangoLayout *layout);
+void pango_layout_set_auto_dir (PangoLayout *layout,
+ gboolean auto_dir);
+gboolean pango_layout_get_auto_dir (PangoLayout *layout);
void pango_layout_set_alignment (PangoLayout *layout,
PangoAlignment alignment);
PangoAlignment pango_layout_get_alignment (PangoLayout *layout);
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index db17e49c..f3e44ecc 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -198,7 +198,7 @@ pango_fc_font_map_class_init (PangoFontMapClass *class)
class->list_families = pango_fc_font_map_list_families;
class->shape_engine_type = PANGO_RENDER_TYPE_FC;
- g_type_class_add_private (object_class, sizeof (PangoFontMapPrivate));
+ g_type_class_add_private (object_class, sizeof (PangoFcFontMapPrivate));
}
static guint