diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2007-08-01 18:52:01 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2007-08-01 18:52:01 +0000 |
commit | ba509b999343fa28c01806f76c92eae61aff58fd (patch) | |
tree | 461b8a6e5ae57e8ef946965ada0d253da14fee53 /pango | |
parent | abab095b9d4ba1a0e41f100eb31840c86bf52b8a (diff) | |
download | pango-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
Diffstat (limited to 'pango')
-rw-r--r-- | pango/Makefile.am | 1 | ||||
-rw-r--r-- | pango/glyphstring.c | 305 | ||||
-rw-r--r-- | pango/mapping.c | 328 | ||||
-rw-r--r-- | pango/pango-layout.c | 2 |
4 files changed, 306 insertions, 330 deletions
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 |