📄 pango-attributes.c
字号:
return pango_attr_int_new (&klass, (int)gravity);}/** * pango_attr_gravity_hint_new: * @hint: the gravity hint value. * * Create a new gravity hint attribute. * * Return value: the newly allocated #PangoAttribute, which should be * freed with pango_attribute_destroy(). * * Since: 1.16 **/PangoAttribute *pango_attr_gravity_hint_new (PangoGravityHint hint){ static const PangoAttrClass klass = { PANGO_ATTR_GRAVITY_HINT, pango_attr_int_copy, pango_attr_int_destroy, pango_attr_int_equal }; return pango_attr_int_new (&klass, (int)hint);}/* * Attribute List */GTypepango_attr_list_get_type (void){ static GType our_type = 0; if (G_UNLIKELY (our_type == 0)) our_type = g_boxed_type_register_static (I_("PangoAttrList"), (GBoxedCopyFunc) pango_attr_list_copy, (GBoxedFreeFunc) pango_attr_list_unref); return our_type;}/** * pango_attr_list_new: * * Create a new empty attribute list with a reference count of one. * * Return value: the newly allocated #PangoAttrList, which should * be freed with pango_attr_list_unref(). **/PangoAttrList *pango_attr_list_new (void){ PangoAttrList *list = g_slice_new (PangoAttrList); list->ref_count = 1; list->attributes = NULL; list->attributes_tail = NULL; return list;}/** * pango_attr_list_ref: * @list: a #PangoAttrList * * Increase the reference count of the given attribute list by one. * * Return value: The attribute list passed in * * Since: 1.10 **/PangoAttrList *pango_attr_list_ref (PangoAttrList *list){ g_return_val_if_fail (list != NULL, NULL); list->ref_count++; return list;}/** * pango_attr_list_unref: * @list: a #PangoAttrList * * Decrease the reference count of the given attribute list by one. * If the result is zero, free the attribute list and the attributes * it contains. **/voidpango_attr_list_unref (PangoAttrList *list){ GSList *tmp_list; g_return_if_fail (list != NULL); g_return_if_fail (list->ref_count > 0); list->ref_count--; if (list->ref_count == 0) { tmp_list = list->attributes; while (tmp_list) { PangoAttribute *attr = tmp_list->data; tmp_list = tmp_list->next; attr->klass->destroy (attr); } g_slist_free (list->attributes); g_slice_free (PangoAttrList, list); }}/** * pango_attr_list_copy: * @list: a #PangoAttrList * * Copy @list and return an identical new list. * * Return value: the newly allocated #PangoAttrList, with a * reference count of one, which should * be freed with pango_attr_list_unref(). **/PangoAttrList *pango_attr_list_copy (PangoAttrList *list){ PangoAttrList *new; GSList *iter; GSList *new_attrs; g_return_val_if_fail (list != NULL, NULL); new = pango_attr_list_new (); iter = list->attributes; new_attrs = NULL; while (iter != NULL) { new_attrs = g_slist_prepend (new_attrs, pango_attribute_copy (iter->data)); iter = g_slist_next (iter); } /* we're going to reverse the nodes, so head becomes tail */ new->attributes_tail = new_attrs; new->attributes = g_slist_reverse (new_attrs); return new;}static voidpango_attr_list_insert_internal (PangoAttrList *list, PangoAttribute *attr, gboolean before){ GSList *tmp_list, *prev, *link; guint start_index = attr->start_index; if (!list->attributes) { list->attributes = g_slist_prepend (NULL, attr); list->attributes_tail = list->attributes; } else if (((PangoAttribute *)list->attributes_tail->data)->start_index < start_index || (!before && ((PangoAttribute *)list->attributes_tail->data)->start_index == start_index)) { g_slist_append (list->attributes_tail, attr); list->attributes_tail = list->attributes_tail->next; g_assert (list->attributes_tail); } else { prev = NULL; tmp_list = list->attributes; while (1) { PangoAttribute *tmp_attr = tmp_list->data; if (tmp_attr->start_index > start_index || (before && tmp_attr->start_index == start_index)) { link = g_slist_alloc (); link->next = tmp_list; link->data = attr; if (prev) prev->next = link; else list->attributes = link; if (!tmp_list) list->attributes_tail = link; break; } prev = tmp_list; tmp_list = tmp_list->next; } }}/** * pango_attr_list_insert: * @list: a #PangoAttrList * @attr: the attribute to insert. Ownership of this value is * assumed by the list. * * Insert the given attribute into the #PangoAttrList. It will * be inserted after all other attributes with a matching * @start_index. **/voidpango_attr_list_insert (PangoAttrList *list, PangoAttribute *attr){ g_return_if_fail (list != NULL); g_return_if_fail (attr != NULL); pango_attr_list_insert_internal (list, attr, FALSE);}/** * pango_attr_list_insert_before: * @list: a #PangoAttrList * @attr: the attribute to insert. Ownership of this value is * assumed by the list. * * Insert the given attribute into the #PangoAttrList. It will * be inserted before all other attributes with a matching * @start_index. **/voidpango_attr_list_insert_before (PangoAttrList *list, PangoAttribute *attr){ g_return_if_fail (list != NULL); g_return_if_fail (attr != NULL); pango_attr_list_insert_internal (list, attr, TRUE);}/** * pango_attr_list_change: * @list: a #PangoAttrList * @attr: the attribute to insert. Ownership of this value is * assumed by the list. * * Insert the given attribute into the #PangoAttrList. It will * replace any attributes of the same type on that segment * and be merged with any adjoining attributes that are identical. * * This function is slower than pango_attr_list_insert() for * creating a attribute list in order (potentially much slower * for large lists). However, pango_attr_list_insert() is not * suitable for continually changing a set of attributes * since it never removes or combines existing attributes. **/voidpango_attr_list_change (PangoAttrList *list, PangoAttribute *attr){ GSList *tmp_list, *prev, *link; guint start_index = attr->start_index; guint end_index = attr->end_index; g_return_if_fail (list != NULL); if (start_index == end_index) /* empty, nothing to do */ { pango_attribute_destroy (attr); return; } tmp_list = list->attributes; prev = NULL; while (1) { PangoAttribute *tmp_attr; if (!tmp_list || ((PangoAttribute *)tmp_list->data)->start_index > start_index) { /* We need to insert a new attribute */ link = g_slist_alloc (); link->next = tmp_list; link->data = attr; if (prev) prev->next = link; else list->attributes = link; if (!tmp_list) list->attributes_tail = link; prev = link; tmp_list = prev->next; break; } tmp_attr = tmp_list->data; if (tmp_attr->klass->type == attr->klass->type && tmp_attr->end_index >= start_index) { /* We overlap with an existing attribute */ if (pango_attribute_equal (tmp_attr, attr)) { /* We can merge the new attribute with this attribute */ if (tmp_attr->end_index >= end_index) { /* We are totally overlapping the previous attribute. * No action is needed. */ pango_attribute_destroy (attr); return; } tmp_attr->end_index = end_index; pango_attribute_destroy (attr); attr = tmp_attr; prev = tmp_list; tmp_list = tmp_list->next; break; } else { /* Split, truncate, or remove the old attribute */ if (tmp_attr->end_index > attr->end_index) { PangoAttribute *end_attr = pango_attribute_copy (tmp_attr); end_attr->start_index = attr->end_index; pango_attr_list_insert (list, end_attr); } if (tmp_attr->start_index == attr->start_index) { pango_attribute_destroy (tmp_attr); tmp_list->data = attr; prev = tmp_list; tmp_list = tmp_list->next; break; } else { tmp_attr->end_index = attr->start_index; } } } prev = tmp_list; tmp_list = tmp_list->next; } /* At this point, prev points to the list node with attr in it, * tmp_list points to prev->next. */ g_assert (prev->data == attr); g_assert (prev->next == tmp_list); /* We now have the range inserted into the list one way or the * other. Fix up the remainder */ while (tmp_list) { PangoAttribute *tmp_attr = tmp_list->data; if (tmp_attr->start_index > end_index) break; else if (tmp_attr->klass->type == attr->klass->type) { if (tmp_attr->end_index <= attr->end_index || pango_attribute_equal (tmp_attr, attr)) { /* We can merge the new attribute with this attribute. */ attr->end_index = MAX (end_index, tmp_attr->end_index); pango_attribute_destroy (tmp_attr); prev->next = tmp_list->next; if (!prev->next) list->attributes_tail = prev; g_slist_free_1 (tmp_list); tmp_list = prev->next; continue; } else { /* Trim the start of this attribute that it begins at the end * of the new attribute. This may involve moving * it in the list to maintain the required non-decreasing * order of start indices */ GSList *tmp_list2; GSList *prev2; tmp_attr->start_index = attr->end_index; tmp_list2 = tmp_list->next; prev2 = tmp_list; while (tmp_list2) { PangoAttribute *tmp_attr2 = tmp_list2->data; if (tmp_attr2->start_index >= tmp_attr->start_index) break; prev2 = tmp_list2; tmp_list2 = tmp_list2->next; } /* Now remove and insert before tmp_list2. We'll * hit this attribute again later, but that's harmless. */ if (prev2 != tmp_list) { GSList *old_next = tmp_list->next; prev->next = old_next; prev2->next = tmp_list; tmp_list->next = tmp_list2; if (!tmp_list->next) list->attributes_tail = tmp_list; tmp_list = old_next; continue; } } } prev = tmp_list; tmp_list = tmp_list->next; }}/** * pango_attr_list_splice: * @list: a #PangoAttrList * @other: another #PangoAttrList * @pos: the position in @list at which to insert @other * @len: the length of the spliced segment. (Note that this * must be specified since the attributes in @other * may only be present at some subsection of this range) * * This function opens up a hole in @list, fills it in with attributes from * the left, and then merges @other on top of the hole. * * This operation is equivalent to stretching every attribute * that applies at position @pos in @list by an amount @len, * and then calling pango_attr_list_change() with a copy * of each attribute in @other in sequence (offset in position by @pos). * * This operation proves useful for, for instance, inserting * a pre-edit string in the middle of an edit buffer. **/voidpango_attr_list_splice (PangoAttrList *list, PangoAttrList *other, gint pos, gint len){ GSList *tmp_list; guint upos, ulen; g_return_if_fail (list != NULL); g_return_if_fail (other != NULL); g_return_if_fail (pos >= 0); g_return_if_fail (len >= 0); upos = (guint)pos; ulen = (guint)len;/* This definition only works when a and b are unsigned; overflow * isn't defined in the C standard for signed integers */#define CLAMP_ADD(a,b) (((a) + (b) < (a)) ? G_MAXUINT : (a) + (b))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -