📄 pango-glyph-item.c
字号:
/* Pango * pango-glyph-item.c: Pair of PangoItem and a glyph string * * Copyright (C) 2002 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>#include <string.h>#include "pango-glyph-item.h"#include "pango-glyph-item-private.h"#include "pango-impl-utils.h"#define LTR(glyph_item) (((glyph_item)->item->analysis.level % 2) == 0)/** * pango_glyph_item_split: * @orig: a #PangoItem * @text: text to which positions in @orig apply * @split_index: byte index of position to split item, relative to the start of the item * * Modifies @orig to cover only the text after @split_index, and * returns a new item that covers the text before @split_index that * used to be in @orig. You can think of @split_index as the length of * the returned item. @split_index may not be 0, and it may not be * greater than or equal to the length of @orig (that is, there must * be at least one byte assigned to each item, you can't create a * zero-length item). * * This function is similar in function to pango_item_split() (and uses * it internally.) * * Return value: the newly allocated item representing text before * @split_index, which should be freed * with pango_glyph_item_free(). * * Since: 1.2 **/PangoGlyphItem *pango_glyph_item_split (PangoGlyphItem *orig, const char *text, int split_index){ PangoGlyphItem *new; int i; int num_glyphs; int num_remaining; int split_offset; g_return_val_if_fail (orig != NULL, NULL); g_return_val_if_fail (orig->item->length > 0, NULL); g_return_val_if_fail (split_index > 0, NULL); g_return_val_if_fail (split_index < orig->item->length, NULL); if (LTR (orig)) { for (i = 0; i < orig->glyphs->num_glyphs; i++) { if (orig->glyphs->log_clusters[i] >= split_index) break; } if (i == orig->glyphs->num_glyphs) /* No splitting necessary */ return NULL; split_index = orig->glyphs->log_clusters[i]; num_glyphs = i; } else { for (i = orig->glyphs->num_glyphs - 1; i >= 0; i--) { if (orig->glyphs->log_clusters[i] >= split_index) break; } if (i < 0) /* No splitting necessary */ return NULL; split_index = orig->glyphs->log_clusters[i]; num_glyphs = orig->glyphs->num_glyphs - 1 - i; } num_remaining = orig->glyphs->num_glyphs - num_glyphs; new = g_slice_new (PangoGlyphItem); split_offset = g_utf8_pointer_to_offset (text + orig->item->offset, text + orig->item->offset + split_index); new->item = pango_item_split (orig->item, split_index, split_offset); new->glyphs = pango_glyph_string_new (); pango_glyph_string_set_size (new->glyphs, num_glyphs); if (LTR (orig)) { memcpy (new->glyphs->glyphs, orig->glyphs->glyphs, num_glyphs * sizeof (PangoGlyphInfo)); memcpy (new->glyphs->log_clusters, orig->glyphs->log_clusters, num_glyphs * sizeof (int)); memmove (orig->glyphs->glyphs, orig->glyphs->glyphs + num_glyphs, num_remaining * sizeof (PangoGlyphInfo)); for (i = num_glyphs; i < orig->glyphs->num_glyphs; i++) orig->glyphs->log_clusters[i - num_glyphs] = orig->glyphs->log_clusters[i] - split_index; } else { memcpy (new->glyphs->glyphs, orig->glyphs->glyphs + num_remaining, num_glyphs * sizeof (PangoGlyphInfo)); memcpy (new->glyphs->log_clusters, orig->glyphs->log_clusters + num_remaining, num_glyphs * sizeof (int)); for (i = 0; i < num_remaining; i++) orig->glyphs->log_clusters[i] = orig->glyphs->log_clusters[i] - split_index; } pango_glyph_string_set_size (orig->glyphs, orig->glyphs->num_glyphs - num_glyphs); return new;}/** * pango_glyph_item_copy: * @orig: a #PangoGlyphItem, may be %NULL * * Make a deep copy an existing #PangoGlyphItem structure. * * Return value: the newly allocated #PangoGlyphItem, which should * be freed with pango_glyph_item_free(), or %NULL * if @orig was %NULL. * * Since: 1.20 **/PangoGlyphItem *pango_glyph_item_copy (PangoGlyphItem *orig){ PangoGlyphItem *result; if (orig == NULL) return NULL; result = g_slice_new (PangoGlyphItem); result->item = pango_item_copy (orig->item); result->glyphs = pango_glyph_string_copy (orig->glyphs); return result;}/** * pango_glyph_item_free: * @glyph_item: a #PangoGlyphItem, may be %NULL * * Frees a #PangoGlyphItem and memory to which it points. * * Since: 1.6 **/voidpango_glyph_item_free (PangoGlyphItem *glyph_item){ if (glyph_item == NULL) return; if (glyph_item->item) pango_item_free (glyph_item->item); if (glyph_item->glyphs) pango_glyph_string_free (glyph_item->glyphs); g_slice_free (PangoGlyphItem, glyph_item);}GTypepango_glyph_item_get_type (void){ static GType our_type = 0; if (G_UNLIKELY (our_type == 0)) our_type = g_boxed_type_register_static (I_("PangoGlyphItem"), (GBoxedCopyFunc) pango_glyph_item_copy, (GBoxedFreeFunc) pango_glyph_item_free); return our_type;}/** * _pango_glyph_item_iter_next_cluster: * @iter: a #PangoGlyphItemIter * * Advances the iterator to the next cluster in the glyph item. * * Return value: %TRUE if the iterator was advanced, %FALSE if we were already on the * last cluster. **/gboolean_pango_glyph_item_iter_next_cluster (PangoGlyphItemIter *iter){ int glyph_index = iter->end_glyph; PangoGlyphString *glyphs = iter->glyph_item->glyphs; int cluster; PangoItem *item = iter->glyph_item->item; if (LTR (iter->glyph_item)) { if (glyph_index == glyphs->num_glyphs) return FALSE; } else { if (glyph_index < 0) return FALSE; } iter->start_glyph = iter->end_glyph; iter->start_index = iter->end_index; iter->start_char = iter->end_char; if (LTR (iter->glyph_item)) { cluster = glyphs->log_clusters[glyph_index]; while (TRUE) { glyph_index++; if (glyph_index == glyphs->num_glyphs) { iter->end_index = item->offset + item->length; iter->end_char = item->num_chars; break; } if (glyphs->log_clusters[glyph_index] != cluster) { iter->end_index = item->offset + glyphs->log_clusters[glyph_index]; iter->end_char += g_utf8_strlen (iter->text + iter->start_index, iter->end_index - iter->start_index); break; } } } else /* RTL */ { cluster = glyphs->log_clusters[glyph_index]; while (TRUE) { glyph_index--; if (glyph_index < 0) { iter->end_index = item->offset + item->length; iter->end_char = item->num_chars; break; } if (glyphs->log_clusters[glyph_index] != cluster) { iter->end_index = item->offset + glyphs->log_clusters[glyph_index]; iter->end_char += g_utf8_strlen (iter->text + iter->start_index, iter->end_index - iter->start_index); break; } } } iter->end_glyph = glyph_index; return TRUE;}/** * _pango_glyph_item_iter_prev_cluster: * @iter: a #PangoGlyphItemIter * * Moves the iterator to the preceding cluster in the glyph item. * * Return value: %TRUE if the iterator was moved, %FALSE if we were already on the * first cluster. **/gboolean_pango_glyph_item_iter_prev_cluster (PangoGlyphItemIter *iter){ int glyph_index = iter->start_glyph; PangoGlyphString *glyphs = iter->glyph_item->glyphs; int cluster; PangoItem *item = iter->glyph_item->item; if (LTR (iter->glyph_item)) { if (glyph_index == 0) return FALSE; } else { if (glyph_index == glyphs->num_glyphs - 1) return FALSE; } iter->end_glyph = iter->start_glyph; iter->end_index = iter->start_index; iter->end_char = iter->start_char; if (LTR (iter->glyph_item)) { cluster = glyphs->log_clusters[glyph_index - 1]; while (TRUE) { glyph_index--; if (glyph_index == 0) { iter->start_index = item->offset; iter->start_char = 0; break; } if (glyphs->log_clusters[glyph_index] != cluster) { glyph_index++; iter->start_index = item->offset + glyphs->log_clusters[glyph_index]; iter->start_char -= g_utf8_strlen (iter->text + iter->start_index, iter->end_index - iter->start_index); break; } } } else /* RTL */ { cluster = glyphs->log_clusters[glyph_index + 1]; while (TRUE) { glyph_index++; if (glyph_index == glyphs->num_glyphs - 1) { iter->start_index = item->offset; iter->start_char = 0; break; } if (glyphs->log_clusters[glyph_index] != cluster) { glyph_index--; iter->start_index = item->offset + glyphs->log_clusters[glyph_index]; iter->start_char -= g_utf8_strlen (iter->text + iter->start_index, iter->end_index - iter->start_index); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -