📄 pango-attributes.c
字号:
tmp_list = list->attributes; while (tmp_list) { PangoAttribute *attr = tmp_list->data; if (attr->start_index <= upos) { if (attr->end_index > upos) attr->end_index = CLAMP_ADD (attr->end_index, ulen); } else { /* This could result in a zero length attribute if it * gets squashed up against G_MAXUINT, but deleting such * an element could (in theory) suprise the caller, so * we don't delete it. */ attr->start_index = CLAMP_ADD (attr->start_index, ulen); attr->end_index = CLAMP_ADD (attr->end_index, ulen); } tmp_list = tmp_list->next; } tmp_list = other->attributes; while (tmp_list) { PangoAttribute *attr = pango_attribute_copy (tmp_list->data); attr->start_index = CLAMP_ADD (attr->start_index, upos); attr->end_index = CLAMP_ADD (attr->end_index, upos); /* Same as above, the attribute could be squashed to zero-length; here * pango_attr_list_change() will take care of deleting it. */ pango_attr_list_change (list, attr); tmp_list = tmp_list->next; }#undef CLAMP_ADD}/** * pango_attr_list_get_iterator: * @list: a #PangoAttrList * * Create a iterator initialized to the beginning of the list. * @list must not be modified until this iterator is freed. * * Return value: the newly allocated #PangoAttrIterator, which should * be freed with pango_attr_iterator_destroy(). **/PangoAttrIterator *pango_attr_list_get_iterator (PangoAttrList *list){ PangoAttrIterator *iterator; g_return_val_if_fail (list != NULL, NULL); iterator = g_slice_new (PangoAttrIterator); iterator->next_attribute = list->attributes; iterator->attribute_stack = NULL; iterator->start_index = 0; iterator->end_index = 0; if (!pango_attr_iterator_next (iterator)) iterator->end_index = G_MAXUINT; return iterator;}/** * pango_attr_iterator_range: * @iterator: a #PangoAttrIterator * @start: location to store the start of the range * @end: location to store the end of the range * * Get the range of the current segment. Note that the * stored return values are signed, not unsigned like * the values in #PangoAttribute. To deal with this API * oversight, stored return values that wouldn't fit into * a signed integer are clamped to %G_MAXINT. **/voidpango_attr_iterator_range (PangoAttrIterator *iterator, gint *start, gint *end){ g_return_if_fail (iterator != NULL); if (start) *start = MIN (iterator->start_index, G_MAXINT); if (end) *end = MIN (iterator->end_index, G_MAXINT);}/** * pango_attr_iterator_next: * @iterator: a #PangoAttrIterator * * Advance the iterator until the next change of style. * * Return value: %FALSE if the iterator is at the end of the list, otherwise %TRUE **/gbooleanpango_attr_iterator_next (PangoAttrIterator *iterator){ GList *tmp_list; g_return_val_if_fail (iterator != NULL, FALSE); if (!iterator->next_attribute && !iterator->attribute_stack) return FALSE; iterator->start_index = iterator->end_index; iterator->end_index = G_MAXUINT; tmp_list = iterator->attribute_stack; while (tmp_list) { GList *next = tmp_list->next; PangoAttribute *attr = tmp_list->data; if (attr->end_index == iterator->start_index) { iterator->attribute_stack = g_list_remove_link (iterator->attribute_stack, tmp_list); g_list_free_1 (tmp_list); } else { iterator->end_index = MIN (iterator->end_index, attr->end_index); } tmp_list = next; } while (iterator->next_attribute && ((PangoAttribute *)iterator->next_attribute->data)->start_index == iterator->start_index) { if (((PangoAttribute *)iterator->next_attribute->data)->end_index > iterator->start_index) { iterator->attribute_stack = g_list_prepend (iterator->attribute_stack, iterator->next_attribute->data); iterator->end_index = MIN (iterator->end_index, ((PangoAttribute *)iterator->next_attribute->data)->end_index); } iterator->next_attribute = iterator->next_attribute->next; } if (iterator->next_attribute) iterator->end_index = MIN (iterator->end_index, ((PangoAttribute *)iterator->next_attribute->data)->start_index); return TRUE;}/** * pango_attr_iterator_copy: * @iterator: a #PangoAttrIterator. * * Copy a #PangoAttrIterator * * Return value: the newly allocated #PangoAttrIterator, which should * be freed with pango_attr_iterator_destroy(). **/PangoAttrIterator *pango_attr_iterator_copy (PangoAttrIterator *iterator){ PangoAttrIterator *copy; g_return_val_if_fail (iterator != NULL, NULL); copy = g_slice_new (PangoAttrIterator); *copy = *iterator; copy->attribute_stack = g_list_copy (iterator->attribute_stack); return copy;}/** * pango_attr_iterator_destroy: * @iterator: a #PangoAttrIterator. * * Destroy a #PangoAttrIterator and free all associated memory. **/voidpango_attr_iterator_destroy (PangoAttrIterator *iterator){ g_return_if_fail (iterator != NULL); g_list_free (iterator->attribute_stack); g_slice_free (PangoAttrIterator, iterator);}/** * pango_attr_iterator_get: * @iterator: a #PangoAttrIterator * @type: the type of attribute to find. * * Find the current attribute of a particular type at the iterator * location. When multiple attributes of the same type overlap, * the attribute whose range starts closest to the current location * is used. * * Return value: the current attribute of the given type, or %NULL * if no attribute of that type applies to the current * location. **/PangoAttribute *pango_attr_iterator_get (PangoAttrIterator *iterator, PangoAttrType type){ GList *tmp_list; g_return_val_if_fail (iterator != NULL, NULL); tmp_list = iterator->attribute_stack; while (tmp_list) { PangoAttribute *attr = tmp_list->data; if (attr->klass->type == type) return attr; tmp_list = tmp_list->next; } return NULL;}/** * pango_attr_iterator_get_font: * @iterator: a #PangoAttrIterator * @desc: a #PangoFontDescription to fill in with the current values. * The family name in this structure will be set using * pango_font_description_set_family_static() using values from * an attribute in the #PangoAttrList associated with the iterator, * so if you plan to keep it around, you must call: * <literal>pango_font_description_set_family (desc, pango_font_description_get_family (desc))</literal>. * @language: if non-%NULL, location to store language tag for item, or %NULL * if none is found. * @extra_attrs: if non-%NULL, location in which to store a list of non-font * attributes at the the current position; only the highest priority * value of each attribute will be added to this list. In order * to free this value, you must call pango_attribute_destroy() on * each member. * * Get the font and other attributes at the current iterator position. **/voidpango_attr_iterator_get_font (PangoAttrIterator *iterator, PangoFontDescription *desc, PangoLanguage **language, GSList **extra_attrs){ GList *tmp_list1; GSList *tmp_list2; PangoFontMask mask = 0; gboolean have_language = FALSE; gdouble scale = 0; gboolean have_scale = FALSE; g_return_if_fail (iterator != NULL); g_return_if_fail (desc != NULL); if (language) *language = NULL; if (extra_attrs) *extra_attrs = NULL; tmp_list1 = iterator->attribute_stack; while (tmp_list1) { PangoAttribute *attr = tmp_list1->data; tmp_list1 = tmp_list1->next; switch (attr->klass->type) { case PANGO_ATTR_FONT_DESC: { PangoFontMask new_mask = pango_font_description_get_set_fields (((PangoAttrFontDesc *)attr)->desc) & ~mask; mask |= new_mask; pango_font_description_unset_fields (desc, new_mask); pango_font_description_merge_static (desc, ((PangoAttrFontDesc *)attr)->desc, FALSE); break; } case PANGO_ATTR_FAMILY: if (!(mask & PANGO_FONT_MASK_FAMILY)) { mask |= PANGO_FONT_MASK_FAMILY; pango_font_description_set_family (desc, ((PangoAttrString *)attr)->value); } break; case PANGO_ATTR_STYLE: if (!(mask & PANGO_FONT_MASK_STYLE)) { mask |= PANGO_FONT_MASK_STYLE; pango_font_description_set_style (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_VARIANT: if (!(mask & PANGO_FONT_MASK_VARIANT)) { mask |= PANGO_FONT_MASK_VARIANT; pango_font_description_set_variant (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_WEIGHT: if (!(mask & PANGO_FONT_MASK_WEIGHT)) { mask |= PANGO_FONT_MASK_WEIGHT; pango_font_description_set_weight (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_STRETCH: if (!(mask & PANGO_FONT_MASK_STRETCH)) { mask |= PANGO_FONT_MASK_STRETCH; pango_font_description_set_stretch (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_SIZE: if (!(mask & PANGO_FONT_MASK_SIZE)) { mask |= PANGO_FONT_MASK_SIZE; pango_font_description_set_size (desc, ((PangoAttrSize *)attr)->size); } break; case PANGO_ATTR_ABSOLUTE_SIZE: if (!(mask & PANGO_FONT_MASK_SIZE)) { mask |= PANGO_FONT_MASK_SIZE; pango_font_description_set_absolute_size (desc, ((PangoAttrSize *)attr)->size); } break; case PANGO_ATTR_SCALE: if (!have_scale) { have_scale = TRUE; scale = ((PangoAttrFloat *)attr)->value; } break; case PANGO_ATTR_LANGUAGE: if (language) { if (!have_language) { have_language = TRUE; *language = ((PangoAttrLanguage *)attr)->value; } } break; default: if (extra_attrs) { gboolean found = FALSE; tmp_list2 = *extra_attrs; while (tmp_list2) { PangoAttribute *old_attr = tmp_list2->data; if (attr->klass->type == old_attr->klass->type) { found = TRUE; break; } tmp_list2 = tmp_list2->next; } if (!found) *extra_attrs = g_slist_prepend (*extra_attrs, pango_attribute_copy (attr)); } } } if (have_scale) pango_font_description_set_size (desc, scale * pango_font_description_get_size (desc));}/** * pango_attr_list_filter: * @list: a #PangoAttrList * @func: callback function; returns %TRUE if an attribute * should be filtered out. * @data: Data to be passed to @func * * Given a #PangoAttrList and callback function, removes any elements * of @list for which @func returns %TRUE and inserts them into * a new list. * * Return value: the new #PangoAttrList or %NULL if * no attributes of the given types were found. * * Since: 1.2 **/PangoAttrList *pango_attr_list_filter (PangoAttrList *list, PangoAttrFilterFunc func, gpointer data){ PangoAttrList *new = NULL; GSList *tmp_list; GSList *prev; g_return_val_if_fail (list != NULL, NULL); tmp_list = list->attributes; prev = NULL; while (tmp_list) { GSList *next = tmp_list->next; PangoAttribute *tmp_attr = tmp_list->data; if ((*func) (tmp_attr, data)) { if (!tmp_list->next) list->attributes_tail = prev; if (prev) prev->next = tmp_list->next; else list->attributes = tmp_list->next; tmp_list->next = NULL; if (!new) { new = pango_attr_list_new (); new->attributes = new->attributes_tail = tmp_list; } else { new->attributes_tail->next = tmp_list; new->attributes_tail = tmp_list; } goto next_attr; } prev = tmp_list; next_attr: tmp_list = next; } return new;}/** * pango_attr_iterator_get_attrs: * @iterator: a #PangoAttrIterator * * Gets a list of all attributes at the current position of the * iterator. * * Return value: a list of all attributes for the current range. * To free this value, call pango_attribute_destroy() on * each value and g_slist_free() on the list. * * Since: 1.2 **/GSList *pango_attr_iterator_get_attrs (PangoAttrIterator *iterator){ GSList *attrs = NULL; GList *tmp_list; for (tmp_list = iterator->attribute_stack; tmp_list; tmp_list = tmp_list->next) { PangoAttribute *attr = tmp_list->data; GSList *tmp_list2; gboolean found = FALSE; for (tmp_list2 = attrs; tmp_list2; tmp_list2 = tmp_list2->next) { PangoAttribute *old_attr = tmp_list2->data; if (attr->klass->type == old_attr->klass->type) { found = TRUE; break; } } if (!found) attrs = g_slist_prepend (attrs, pango_attribute_copy (attr)); } return attrs;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -