📄 atktext.c
字号:
}}/** * atk_text_get_range_extents: * @text: an #AtkText * @start_offset: The offset of the first text character for which boundary * information is required. * @end_offset: The offset of the text character after the last character * for which boundary information is required. * @coord_type: Specify whether coordinates are relative to the screen or widget window. * @rect: A pointer to a AtkTextRectangle which is filled in by this function. * * Get the bounding box for text within the specified range. **/voidatk_text_get_range_extents (AtkText *text, gint start_offset, gint end_offset, AtkCoordType coord_type, AtkTextRectangle *rect){ AtkTextIface *iface; g_return_if_fail (ATK_IS_TEXT (text)); g_return_if_fail (rect); if (start_offset < 0 || start_offset >= end_offset) return; iface = ATK_TEXT_GET_IFACE (text); if (iface->get_range_extents) (*(iface->get_range_extents)) (text, start_offset, end_offset, coord_type, rect);}/** * atk_text_get_bounded_ranges: * @text: an #AtkText * @rect: An AtkTextRectagle giving the dimensions of the bounding box. * @coord_type: Specify whether coordinates are relative to the screen or widget window. * @x_clip_type: Specify the horizontal clip type. * @y_clip_type: Specify the vertical clip type. * * Get the ranges of text in the specified bounding box. * * Returns: Array of AtkTextRange. The last element of the array returned * by this function will be NULL. **/AtkTextRange**atk_text_get_bounded_ranges (AtkText *text, AtkTextRectangle *rect, AtkCoordType coord_type, AtkTextClipType x_clip_type, AtkTextClipType y_clip_type){ AtkTextIface *iface; g_return_val_if_fail (ATK_IS_TEXT (text), NULL); g_return_val_if_fail (rect, NULL); iface = ATK_TEXT_GET_IFACE (text); if (iface->get_bounded_ranges) return (*(iface->get_bounded_ranges)) (text, rect, coord_type, x_clip_type, y_clip_type); else return NULL;}/** * atk_attribute_set_free: * @attrib_set: The #AtkAttributeSet to free * * Frees the memory used by an #AtkAttributeSet, including all its * #AtkAttributes. **/voidatk_attribute_set_free (AtkAttributeSet *attrib_set){ GSList *temp; temp = attrib_set; while (temp != NULL) { AtkAttribute *att; att = temp->data; g_free (att->name); g_free (att->value); g_free (att); temp = temp->next; } g_slist_free (attrib_set);}/** * atk_text_attribute_register: * @name: a name string * * Associate @name with a new #AtkTextAttribute * * Returns: an #AtkTextAttribute associated with @name **/AtkTextAttributeatk_text_attribute_register (const gchar *name){ g_return_val_if_fail (name, ATK_TEXT_ATTR_INVALID); if (!extra_attributes) extra_attributes = g_ptr_array_new (); g_ptr_array_add (extra_attributes, g_strdup (name)); return extra_attributes->len + ATK_TEXT_ATTR_LAST_DEFINED;}/** * atk_text_attribute_get_name: * @attr: The #AtkTextAttribute whose name is required * * Gets the name corresponding to the #AtkTextAttribute * * Returns: a string containing the name; this string should not be freed **/G_CONST_RETURN gchar*atk_text_attribute_get_name (AtkTextAttribute attr){ GTypeClass *type_class; GEnumValue *value; gchar *name = NULL; type_class = g_type_class_ref (ATK_TYPE_TEXT_ATTRIBUTE); g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL); value = g_enum_get_value (G_ENUM_CLASS (type_class), attr); if (value) { name = value->value_nick; } else { if (extra_attributes) { gint n = attr; n -= ATK_TEXT_ATTR_LAST_DEFINED + 1; if (n < extra_attributes->len) name = g_ptr_array_index (extra_attributes, n); } } g_type_class_unref (type_class); return name;}/** * atk_text_attribute_for_name: * @name: a string which is the (non-localized) name of an ATK text attribute. * * Get the #AtkTextAttribute type corresponding to a text attribute name. * * Returns: the #AtkTextAttribute enumerated type corresponding to the specifiedname, * or #ATK_TEXT_ATTRIBUTE_INVALID if no matching text attribute is found. **/AtkTextAttributeatk_text_attribute_for_name (const gchar *name){ GTypeClass *type_class; GEnumValue *value; AtkTextAttribute type = ATK_TEXT_ATTR_INVALID; g_return_val_if_fail (name, ATK_TEXT_ATTR_INVALID); type_class = g_type_class_ref (ATK_TYPE_TEXT_ATTRIBUTE); g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_TEXT_ATTR_INVALID); value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name); if (value) { type = value->value; } else { gint i; if (extra_attributes) { for (i = 0; i < extra_attributes->len; i++) { gchar *extra_attribute = (gchar *)g_ptr_array_index (extra_attributes, i); g_return_val_if_fail (extra_attribute, ATK_TEXT_ATTR_INVALID); if (strcmp (name, extra_attribute) == 0) { type = i + 1 + ATK_TEXT_ATTR_LAST_DEFINED; break; } } } } g_type_class_unref (type_class); return type;}/** * atk_text_attribute_get_value: * @attr: The #AtkTextAttribute for which a value is required * @index_: The index of the required value * * Gets the value for the index of the #AtkTextAttribute * * Returns: a string containing the value; this string should not be freed; * NULL is returned if there are no values maintained for the attr value. **/G_CONST_RETURN gchar*atk_text_attribute_get_value (AtkTextAttribute attr, gint index){ switch (attr) { case ATK_TEXT_ATTR_INVISIBLE: case ATK_TEXT_ATTR_EDITABLE: case ATK_TEXT_ATTR_BG_FULL_HEIGHT: case ATK_TEXT_ATTR_STRIKETHROUGH: case ATK_TEXT_ATTR_BG_STIPPLE: case ATK_TEXT_ATTR_FG_STIPPLE: g_assert (index >= 0 && index < 2); return bool[index]; case ATK_TEXT_ATTR_UNDERLINE: g_assert (index >= 0 && index < 4); return underline[index]; case ATK_TEXT_ATTR_WRAP_MODE: g_assert (index >= 0 && index < 3); return wrap_mode[index]; case ATK_TEXT_ATTR_DIRECTION: g_assert (index >= 0 && index < 3); return direction[index]; case ATK_TEXT_ATTR_JUSTIFICATION: g_assert (index >= 0 && index < 3); return justification[index]; case ATK_TEXT_ATTR_STRETCH: g_assert (index >= 0 && index < 9); return stretch[index]; case ATK_TEXT_ATTR_VARIANT: g_assert (index >= 0 && index < 2); return variant[index]; case ATK_TEXT_ATTR_STYLE: g_assert (index >= 0 && index < 3); return style[index]; default: return NULL; }}static voidatk_text_rectangle_union (AtkTextRectangle *src1, AtkTextRectangle *src2, AtkTextRectangle *dest){ gint dest_x, dest_y; dest_x = MIN (src1->x, src2->x); dest_y = MIN (src1->y, src2->y); dest->width = MAX (src1->x + src1->width, src2->x + src2->width) - dest_x; dest->height = MAX (src1->y + src1->height, src2->y + src2->height) - dest_y; dest->x = dest_x; dest->y = dest_y;}static gbooleanatk_text_rectangle_contain (AtkTextRectangle *clip, AtkTextRectangle *bounds, AtkTextClipType x_clip_type, AtkTextClipType y_clip_type){ gboolean x_min_ok, x_max_ok, y_min_ok, y_max_ok; x_min_ok = (bounds->x >= clip->x) || ((bounds->x + bounds->width >= clip->x) && ((x_clip_type == ATK_TEXT_CLIP_NONE) || (x_clip_type == ATK_TEXT_CLIP_MAX))); x_max_ok = (bounds->x + bounds->width <= clip->x + clip->width) || ((bounds->x <= clip->x + clip->width) && ((x_clip_type == ATK_TEXT_CLIP_NONE) || (x_clip_type == ATK_TEXT_CLIP_MIN))); y_min_ok = (bounds->y >= clip->y) || ((bounds->y + bounds->height >= clip->y) && ((y_clip_type == ATK_TEXT_CLIP_NONE) || (y_clip_type == ATK_TEXT_CLIP_MAX))); y_max_ok = (bounds->y + bounds->height <= clip->y + clip->height) || ((bounds->y <= clip->y + clip->height) && ((y_clip_type == ATK_TEXT_CLIP_NONE) || (y_clip_type == ATK_TEXT_CLIP_MIN))); return (x_min_ok && x_max_ok && y_min_ok && y_max_ok); }static void atk_text_real_get_range_extents (AtkText *text, gint start_offset, gint end_offset, AtkCoordType coord_type, AtkTextRectangle *rect){ gint i; AtkTextRectangle cbounds, bounds; atk_text_get_character_extents (text, start_offset, &bounds.x, &bounds.y, &bounds.width, &bounds.height, coord_type); for (i = start_offset + 1; i < end_offset; i++) { atk_text_get_character_extents (text, i, &cbounds.x, &cbounds.y, &cbounds.width, &cbounds.height, coord_type); atk_text_rectangle_union (&bounds, &cbounds, &bounds); } rect->x = bounds.x; rect->y = bounds.y; rect->width = bounds.width; rect->height = bounds.height;}static AtkTextRange**atk_text_real_get_bounded_ranges (AtkText *text, AtkTextRectangle *rect, AtkCoordType coord_type, AtkTextClipType x_clip_type, AtkTextClipType y_clip_type){ gint bounds_min_offset, bounds_max_offset; gint min_line_start, min_line_end; gint max_line_start, max_line_end; gchar *line; gint curr_offset; gint offset; gint num_ranges = 0; gint range_size = 1; AtkTextRectangle cbounds; AtkTextRange **range; range = NULL; bounds_min_offset = atk_text_get_offset_at_point (text, rect->x, rect->y, coord_type); bounds_max_offset = atk_text_get_offset_at_point (text, rect->x + rect->width, rect->y + rect->height, coord_type); if (bounds_min_offset == 0 && bounds_min_offset == bounds_max_offset) return NULL; line = atk_text_get_text_at_offset (text, bounds_min_offset, ATK_TEXT_BOUNDARY_LINE_START, &min_line_start, &min_line_end); g_free (line); line = atk_text_get_text_at_offset (text, bounds_max_offset, ATK_TEXT_BOUNDARY_LINE_START, &max_line_start, &max_line_end); g_free (line); bounds_min_offset = MIN (min_line_start, max_line_start); bounds_max_offset = MAX (min_line_end, max_line_end); curr_offset = bounds_min_offset; while (curr_offset < bounds_max_offset) { offset = curr_offset; while (curr_offset < bounds_max_offset) { atk_text_get_character_extents (text, curr_offset, &cbounds.x, &cbounds.y, &cbounds.width, &cbounds.height, coord_type); if (!atk_text_rectangle_contain (rect, &cbounds, x_clip_type, y_clip_type)) break; curr_offset++; } if (curr_offset > offset) { AtkTextRange *one_range = g_new (AtkTextRange, 1); one_range->start_offset = offset; one_range->end_offset = curr_offset; one_range->content = atk_text_get_text (text, offset, curr_offset); atk_text_get_range_extents (text, offset, curr_offset, coord_type, &one_range->bounds); if (num_ranges >= range_size - 1) { range_size *= 2; range = g_realloc (range, range_size * sizeof (gpointer)); } range[num_ranges] = one_range; num_ranges++; } curr_offset++; if (range) range[num_ranges] = NULL; } return range;}/** * atk_text_free_ranges: * @ranges: A pointer to an array of #AtkTextRange which is to be freed. * * Frees the memory associated with an array of AtkTextRange. It is assumed * that the array was returned by the function atk_text_get_bounded_ranges * and is NULL terminated. **/voidatk_text_free_ranges (AtkTextRange **ranges){ if (ranges) { while (*ranges) { AtkTextRange *range; range = *ranges; *ranges++; g_free (range->content); g_free (ranges); } g_free (ranges); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -