summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2007-08-01 18:52:01 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2007-08-01 18:52:01 +0000
commitba509b999343fa28c01806f76c92eae61aff58fd (patch)
tree461b8a6e5ae57e8ef946965ada0d253da14fee53
parentabab095b9d4ba1a0e41f100eb31840c86bf52b8a (diff)
downloadpango-ba509b999343fa28c01806f76c92eae61aff58fd.tar.gz
Move contents of mapping.c to glyphstring.c where they belong.
2007-08-01 Behdad Esfahbod <behdad@gnome.org> * pango/Makefile.am: * pango/glyphstring.c (pango_glyph_string_index_to_x), (pango_glyph_string_x_to_index): * pango/mapping.c: Move contents of mapping.c to glyphstring.c where they belong. * pango/pango-layout.c (pango_layout_line_x_to_index): Fix typo. svn path=/trunk/; revision=2389
-rw-r--r--ChangeLog11
-rw-r--r--pango/Makefile.am1
-rw-r--r--pango/glyphstring.c305
-rw-r--r--pango/mapping.c328
-rw-r--r--pango/pango-layout.c2
5 files changed, 317 insertions, 330 deletions
diff --git a/ChangeLog b/ChangeLog
index c6addea3..2ce78874 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2007-08-01 Behdad Esfahbod <behdad@gnome.org>
+ * pango/Makefile.am:
+ * pango/glyphstring.c (pango_glyph_string_index_to_x),
+ (pango_glyph_string_x_to_index):
+ * pango/mapping.c:
+ Move contents of mapping.c to glyphstring.c where they belong.
+
+ * pango/pango-layout.c (pango_layout_line_x_to_index):
+ Fix typo.
+
+2007-08-01 Behdad Esfahbod <behdad@gnome.org>
+
Bug 451682 – Cursor positioning for Sinhala is broken
Based on patch from Harshula
diff --git a/pango/Makefile.am b/pango/Makefile.am
index 8f73ebd7..015c3d50 100644
--- a/pango/Makefile.am
+++ b/pango/Makefile.am
@@ -64,7 +64,6 @@ libpango_1_0_la_SOURCES = \
ellipsize.c \
fonts.c \
glyphstring.c \
- mapping.c \
modules.c \
pango-attributes.c \
pango-color.c \
diff --git a/pango/glyphstring.c b/pango/glyphstring.c
index 0fcbb229..7bf383a7 100644
--- a/pango/glyphstring.c
+++ b/pango/glyphstring.c
@@ -358,3 +358,308 @@ pango_glyph_string_get_logical_widths (PangoGlyphString *glyphs,
}
}
+/* The initial implementation here is script independent,
+ * but it might actually need to be virtualized into the
+ * rendering modules. Otherwise, we probably will end up
+ * enforcing unnatural cursor behavior for some languages.
+ *
+ * The only distinction that Uniscript makes is whether
+ * cursor positioning is allowed within clusters or not.
+ */
+
+/**
+ * pango_glyph_string_index_to_x:
+ * @glyphs: the glyphs return from pango_shape()
+ * @text: the text for the run
+ * @length: the number of bytes (not characters) in @text.
+ * @analysis: the analysis information return from pango_itemize()
+ * @index_: the byte index within @text
+ * @trailing: whether we should compute the result for the beginning
+ * or end of the character.
+ * @x_pos: location to store result
+ *
+ * Converts from character position to x position. (X position
+ * is measured from the left edge of the run). Character positions
+ * are computed by dividing up each cluster into equal portions.
+ */
+
+void
+pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
+ char *text,
+ int length,
+ PangoAnalysis *analysis,
+ int index,
+ gboolean trailing,
+ int *x_pos)
+{
+ int i;
+ int start_xpos = 0;
+ int end_xpos = 0;
+ int width = 0;
+
+ int start_index = -1;
+ int end_index = -1;
+
+ int cluster_chars = 0;
+ int cluster_offset = 0;
+
+ char *p;
+
+ g_return_if_fail (glyphs != NULL);
+ g_return_if_fail (length >= 0);
+ g_return_if_fail (length == 0 || text != NULL);
+
+ if (!x_pos) /* Allow the user to do the useless */
+ return;
+
+ if (glyphs->num_glyphs == 0)
+ {
+ *x_pos = 0;
+ return;
+ }
+
+ /* Calculate the starting and ending character positions
+ * and x positions for the cluster
+ */
+ if (analysis->level % 2) /* Right to left */
+ {
+ for (i = glyphs->num_glyphs - 1; i >= 0; i--)
+ width += glyphs->glyphs[i].geometry.width;
+
+ for (i = glyphs->num_glyphs - 1; i >= 0; i--)
+ {
+ if (glyphs->log_clusters[i] > index)
+ {
+ end_index = glyphs->log_clusters[i];
+ end_xpos = width;
+ break;
+ }
+
+ if (glyphs->log_clusters[i] != start_index)
+ {
+ start_index = glyphs->log_clusters[i];
+ start_xpos = width;
+ }
+
+ width -= glyphs->glyphs[i].geometry.width;
+ }
+ }
+ else /* Left to right */
+ {
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ {
+ if (glyphs->log_clusters[i] > index)
+ {
+ end_index = glyphs->log_clusters[i];
+ end_xpos = width;
+ break;
+ }
+
+ if (glyphs->log_clusters[i] != start_index)
+ {
+ start_index = glyphs->log_clusters[i];
+ start_xpos = width;
+ }
+
+ width += glyphs->glyphs[i].geometry.width;
+ }
+ }
+
+ if (end_index == -1)
+ {
+ end_index = length;
+ end_xpos = (analysis->level % 2) ? 0 : width;
+ }
+
+ /* Calculate offset of character within cluster */
+
+ p = text + start_index;
+ while (p < text + end_index)
+ {
+ if (p < text + index)
+ cluster_offset++;
+ cluster_chars++;
+ p = g_utf8_next_char (p);
+ }
+
+ if (trailing)
+ cluster_offset += 1;
+
+ *x_pos = ((cluster_chars - cluster_offset) * start_xpos +
+ cluster_offset * end_xpos) / cluster_chars;
+}
+
+/**
+ * pango_glyph_string_x_to_index:
+ * @glyphs: the glyphs return from pango_shape()
+ * @text: the text for the run
+ * @length: the number of bytes (not characters) in text.
+ * @analysis: the analysis information return from pango_itemize()
+ * @x_pos: the x offset (in #PangoGlyphUnit)
+ * @index_: location to store calculated byte index within @text
+ * @trailing: location to store a integer indicating where
+ * whether the user clicked on the leading or trailing
+ * edge of the character.
+ *
+ * Convert from x offset to character position. Character positions
+ * are computed by dividing up each cluster into equal portions.
+ * In scripts where positioning within a cluster is not allowed
+ * (such as Thai), the returned value may not be a valid cursor
+ * position; the caller must combine the result with the logical
+ * attributes for the text to compute the valid cursor position.
+ */
+void
+pango_glyph_string_x_to_index (PangoGlyphString *glyphs,
+ char *text,
+ int length,
+ PangoAnalysis *analysis,
+ int x_pos,
+ int *index,
+ gboolean *trailing)
+{
+ int i;
+ int start_xpos = 0;
+ int end_xpos = 0;
+ int width = 0;
+
+ int start_index = -1;
+ int end_index = -1;
+
+ int cluster_chars = 0;
+ char *p;
+
+ gboolean found = FALSE;
+
+ /* Find the cluster containing the position */
+
+ width = 0;
+
+ if (analysis->level % 2) /* Right to left */
+ {
+ for (i = glyphs->num_glyphs - 1; i >= 0; i--)
+ width += glyphs->glyphs[i].geometry.width;
+
+ for (i = glyphs->num_glyphs - 1; i >= 0; i--)
+ {
+ if (glyphs->log_clusters[i] != start_index)
+ {
+ if (found)
+ {
+ end_index = glyphs->log_clusters[i];
+ end_xpos = width;
+ break;
+ }
+ else
+ {
+ start_index = glyphs->log_clusters[i];
+ start_xpos = width;
+ }
+ }
+
+ width -= glyphs->glyphs[i].geometry.width;
+
+ if (width <= x_pos && x_pos < width + glyphs->glyphs[i].geometry.width)
+ found = TRUE;
+ }
+ }
+ else /* Left to right */
+ {
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ {
+ if (glyphs->log_clusters[i] != start_index)
+ {
+ if (found)
+ {
+ end_index = glyphs->log_clusters[i];
+ end_xpos = width;
+ break;
+ }
+ else
+ {
+ start_index = glyphs->log_clusters[i];
+ start_xpos = width;
+ }
+ }
+
+ if (width <= x_pos && x_pos < width + glyphs->glyphs[i].geometry.width)
+ found = TRUE;
+
+ width += glyphs->glyphs[i].geometry.width;
+ }
+ }
+
+ if (end_index == -1)
+ {
+ end_index = length;
+ end_xpos = (analysis->level % 2) ? 0 : width;
+ }
+
+ /* Calculate number of chars within cluster */
+ p = text + start_index;
+ while (p < text + end_index)
+ {
+ p = g_utf8_next_char (p);
+ cluster_chars++;
+ }
+
+ if (start_xpos == end_xpos)
+ {
+ if (index)
+ *index = start_index;
+ if (trailing)
+ *trailing = 0;
+ }
+ else
+ {
+ double cp = ((double)(x_pos - start_xpos) * cluster_chars) / (end_xpos - start_xpos);
+
+ /* LTR and right-to-left have to be handled separately
+ * here because of the edge condition when we are exactly
+ * at a pixel boundary; end_xpos goes with the next
+ * character for LTR, with the previous character for RTL.
+ */
+ if (start_xpos < end_xpos) /* Left-to-right */
+ {
+ if (index)
+ {
+ char *p = text + start_index;
+ int i = 0;
+
+ while (i + 1 <= cp)
+ {
+ p = g_utf8_next_char (p);
+ i++;
+ }
+
+ *index = (p - text);
+ }
+
+ if (trailing)
+ *trailing = (cp - (int)cp >= 0.5) ? 1 : 0;
+ }
+ else /* Right-to-left */
+ {
+ if (index)
+ {
+ char *p = text + start_index;
+ int i = 0;
+
+ while (i + 1 < cp)
+ {
+ p = g_utf8_next_char (p);
+ i++;
+ }
+
+ *index = (p - text);
+ }
+
+ if (trailing)
+ {
+ double cp_flip = cluster_chars - cp;
+ *trailing = (cp_flip - (int)cp_flip >= 0.5) ? 0 : 1;
+ }
+ }
+ }
+}
+
+
diff --git a/pango/mapping.c b/pango/mapping.c
deleted file mode 100644
index 7000b69c..00000000
--- a/pango/mapping.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* Pango
- * mapping.c:
- *
- * Copyright (C) 1999 Red Hat Software
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-
-/* The initial implementation here is script independent,
- * but it might actually need to be virtualized into the
- * rendering modules. Otherwise, we probably will end up
- * enforcing unnatural cursor behavior for some languages.
- *
- * The only distinction that Uniscript makes is whether
- * cursor positioning is allowed within clusters or not.
- */
-
-#include "pango-glyph.h"
-
-/**
- * pango_glyph_string_index_to_x:
- * @glyphs: the glyphs return from pango_shape()
- * @text: the text for the run
- * @length: the number of bytes (not characters) in @text.
- * @analysis: the analysis information return from pango_itemize()
- * @index_: the byte index within @text
- * @trailing: whether we should compute the result for the beginning
- * or end of the character.
- * @x_pos: location to store result
- *
- * Converts from character position to x position. (X position
- * is measured from the left edge of the run). Character positions
- * are computed by dividing up each cluster into equal portions.
- */
-
-void
-pango_glyph_string_index_to_x (PangoGlyphString *glyphs,
- char *text,
- int length,
- PangoAnalysis *analysis,
- int index,
- gboolean trailing,
- int *x_pos)
-{
- int i;
- int start_xpos = 0;
- int end_xpos = 0;
- int width = 0;
-
- int start_index = -1;
- int end_index = -1;
-
- int cluster_chars = 0;
- int cluster_offset = 0;
-
- char *p;
-
- g_return_if_fail (glyphs != NULL);
- g_return_if_fail (length >= 0);
- g_return_if_fail (length == 0 || text != NULL);
-
- if (!x_pos) /* Allow the user to do the useless */
- return;
-
- if (glyphs->num_glyphs == 0)
- {
- *x_pos = 0;
- return;
- }
-
- /* Calculate the starting and ending character positions
- * and x positions for the cluster
- */
- if (analysis->level % 2) /* Right to left */
- {
- for (i = glyphs->num_glyphs - 1; i >= 0; i--)
- width += glyphs->glyphs[i].geometry.width;
-
- for (i = glyphs->num_glyphs - 1; i >= 0; i--)
- {
- if (glyphs->log_clusters[i] > index)
- {
- end_index = glyphs->log_clusters[i];
- end_xpos = width;
- break;
- }
-
- if (glyphs->log_clusters[i] != start_index)
- {
- start_index = glyphs->log_clusters[i];
- start_xpos = width;
- }
-
- width -= glyphs->glyphs[i].geometry.width;
- }
- }
- else /* Left to right */
- {
- for (i = 0; i < glyphs->num_glyphs; i++)
- {
- if (glyphs->log_clusters[i] > index)
- {
- end_index = glyphs->log_clusters[i];
- end_xpos = width;
- break;
- }
-
- if (glyphs->log_clusters[i] != start_index)
- {
- start_index = glyphs->log_clusters[i];
- start_xpos = width;
- }
-
- width += glyphs->glyphs[i].geometry.width;
- }
- }
-
- if (end_index == -1)
- {
- end_index = length;
- end_xpos = (analysis->level % 2) ? 0 : width;
- }
-
- /* Calculate offset of character within cluster */
-
- p = text + start_index;
- while (p < text + end_index)
- {
- if (p < text + index)
- cluster_offset++;
- cluster_chars++;
- p = g_utf8_next_char (p);
- }
-
- if (trailing)
- cluster_offset += 1;
-
- *x_pos = ((cluster_chars - cluster_offset) * start_xpos +
- cluster_offset * end_xpos) / cluster_chars;
-}
-
-/**
- * pango_glyph_string_x_to_index:
- * @glyphs: the glyphs return from pango_shape()
- * @text: the text for the run
- * @length: the number of bytes (not characters) in text.
- * @analysis: the analysis information return from pango_itemize()
- * @x_pos: the x offset (in #PangoGlyphUnit)
- * @index_: location to store calculated byte index within @text
- * @trailing: location to store a integer indicating where
- * whether the user clicked on the leading or trailing
- * edge of the character.
- *
- * Convert from x offset to character position. Character positions
- * are computed by dividing up each cluster into equal portions.
- * In scripts where positioning within a cluster is not allowed
- * (such as Thai), the returned value may not be a valid cursor
- * position; the caller must combine the result with the logical
- * attributes for the text to compute the valid cursor position.
- */
-void
-pango_glyph_string_x_to_index (PangoGlyphString *glyphs,
- char *text,
- int length,
- PangoAnalysis *analysis,
- int x_pos,
- int *index,
- gboolean *trailing)
-{
- int i;
- int start_xpos = 0;
- int end_xpos = 0;
- int width = 0;
-
- int start_index = -1;
- int end_index = -1;
-
- int cluster_chars = 0;
- char *p;
-
- gboolean found = FALSE;
-
- /* Find the cluster containing the position */
-
- width = 0;
-
- if (analysis->level % 2) /* Right to left */
- {
- for (i = glyphs->num_glyphs - 1; i >= 0; i--)
- width += glyphs->glyphs[i].geometry.width;
-
- for (i = glyphs->num_glyphs - 1; i >= 0; i--)
- {
- if (glyphs->log_clusters[i] != start_index)
- {
- if (found)
- {
- end_index = glyphs->log_clusters[i];
- end_xpos = width;
- break;
- }
- else
- {
- start_index = glyphs->log_clusters[i];
- start_xpos = width;
- }
- }
-
- width -= glyphs->glyphs[i].geometry.width;
-
- if (width <= x_pos && x_pos < width + glyphs->glyphs[i].geometry.width)
- found = TRUE;
- }
- }
- else /* Left to right */
- {
- for (i = 0; i < glyphs->num_glyphs; i++)
- {
- if (glyphs->log_clusters[i] != start_index)
- {
- if (found)
- {
- end_index = glyphs->log_clusters[i];
- end_xpos = width;
- break;
- }
- else
- {
- start_index = glyphs->log_clusters[i];
- start_xpos = width;
- }
- }
-
- if (width <= x_pos && x_pos < width + glyphs->glyphs[i].geometry.width)
- found = TRUE;
-
- width += glyphs->glyphs[i].geometry.width;
- }
- }
-
- if (end_index == -1)
- {
- end_index = length;
- end_xpos = (analysis->level % 2) ? 0 : width;
- }
-
- /* Calculate number of chars within cluster */
- p = text + start_index;
- while (p < text + end_index)
- {
- p = g_utf8_next_char (p);
- cluster_chars++;
- }
-
- if (start_xpos == end_xpos)
- {
- if (index)
- *index = start_index;
- if (trailing)
- *trailing = 0;
- }
- else
- {
- double cp = ((double)(x_pos - start_xpos) * cluster_chars) / (end_xpos - start_xpos);
-
- /* LTR and right-to-left have to be handled separately
- * here because of the edge condition when we are exactly
- * at a pixel boundary; end_xpos goes with the next
- * character for LTR, with the previous character for RTL.
- */
- if (start_xpos < end_xpos) /* Left-to-right */
- {
- if (index)
- {
- char *p = text + start_index;
- int i = 0;
-
- while (i + 1 <= cp)
- {
- p = g_utf8_next_char (p);
- i++;
- }
-
- *index = (p - text);
- }
-
- if (trailing)
- *trailing = (cp - (int)cp >= 0.5) ? 1 : 0;
- }
- else /* Right-to-left */
- {
- if (index)
- {
- char *p = text + start_index;
- int i = 0;
-
- while (i + 1 < cp)
- {
- p = g_utf8_next_char (p);
- i++;
- }
-
- *index = (p - text);
- }
-
- if (trailing)
- {
- double cp_flip = cluster_chars - cp;
- *trailing = (cp_flip - (int)cp_flip >= 0.5) ? 0 : 1;
- }
- }
- }
-}
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 8066c646..5ed398a6 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3889,7 +3889,7 @@ pango_layout_line_x_to_index (PangoLayoutLine *line,
}
while (last_offset > first_offset && !layout->log_attrs[last_offset].is_cursor_position);
- /* This is a HACK. If a program only keeps track if cursor (etc)
+ /* This is a HACK. If a program only keeps track of cursor (etc)
* indices and not the trailing flag, then the trailing index of the
* last character on a wrapped line is identical to the leading
* index of the next line. So, we fake it and set the trailing flag