X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=libspi%2Ftext.c;h=103e719c706a47afc81c29cf81bb2ee2db5d9e9d;hb=d8761880c8bd6c1c2b48749f57bab780900c274b;hp=9179a0a2c988cb666752dbb49078bb925b0d4824;hpb=c8bb006881bf32579ce674777067474c36021f26;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/libspi/text.c b/libspi/text.c index 9179a0a..103e719 100644 --- a/libspi/text.c +++ b/libspi/text.c @@ -41,56 +41,6 @@ typedef struct { gint h; } SpiTextRect; -static SpiTextRect * -_spi_text_rect_union (SpiTextRect *aggregate, SpiTextRect *subrect) -{ - if (subrect != NULL) - { - /* 'normalize' subrect */ - if (subrect->w < 0) - { - subrect->x += subrect->w; - subrect->w *= -1; - } - if (subrect->h < 0) - { - subrect->y += subrect->h; - subrect->h *= -1; - } - if (aggregate == NULL) - { - aggregate = g_new (SpiTextRect, 1); - memcpy (aggregate, subrect, sizeof (SpiTextRect)); - } - else - { - gint ax2 = aggregate->x + aggregate->w; - gint ay2 = aggregate->y + aggregate->h; - gint sx2 = subrect->x + subrect->w; - gint sy2 = subrect->y + subrect->h; - if (subrect->x < aggregate->x) - { - aggregate->w += (aggregate->x - subrect->x); - aggregate->x = subrect->x; - } - if (sx2 > ax2) - { - aggregate->w += (sx2 - ax2); - } - if (subrect->y < aggregate->y) - { - aggregate->h += (aggregate->y - subrect->y); - aggregate->y = subrect->y; - } - if (sy2 > ay2) - { - aggregate->h += (sy2 - ay2); - } - } - } - return aggregate; -} - static AtkText * get_text_from_servant (PortableServer_Servant servant) { @@ -126,7 +76,7 @@ impl_getText (PortableServer_Servant servant, } -CORBA_string +static CORBA_string impl_getTextAfterOffset (PortableServer_Servant servant, const CORBA_long offset, const @@ -309,6 +259,45 @@ impl_getAttributes (PortableServer_Servant servant, } static CORBA_string +impl_getAttributeValue (PortableServer_Servant servant, + const CORBA_long offset, + const CORBA_char *attributename, + CORBA_long * startOffset, + CORBA_long * endOffset, + CORBA_boolean * defined, + CORBA_Environment *ev) +{ + AtkAttributeSet *set; + gint intstart_offset, intend_offset; + GSList *cur_attr; + CORBA_string rv = NULL; + AtkText *text = get_text_from_servant (servant); + AtkAttribute *at; + + g_return_val_if_fail (text != NULL, CORBA_string_dup ("")); + + set = atk_text_get_run_attributes (text, offset, + &intstart_offset, &intend_offset); + *startOffset = intstart_offset; + *endOffset = intend_offset; + *defined = FALSE; + cur_attr = (GSList *) set; + while (cur_attr) + { + at = (AtkAttribute *) cur_attr->data; + if (!strcmp (at->name, attributename)) + { + rv = CORBA_string_dup (at->value); + *defined = TRUE; + break; + } + cur_attr = cur_attr->next; + } + atk_attribute_set_free (set); + return (rv ? rv : CORBA_string_dup ("")); +} + +static CORBA_string impl_getDefaultAttributes (PortableServer_Servant servant, CORBA_Environment *ev) { @@ -465,8 +454,6 @@ impl_setCaretOffset (PortableServer_Servant servant, return atk_text_set_caret_offset (text, value); } -#define SPI_TEXT_MIN_RANGE_FOR_LINE_CHECK 6 - static void impl_getRangeExtents(PortableServer_Servant servant, const CORBA_long startOffset, @@ -478,86 +465,42 @@ impl_getRangeExtents(PortableServer_Servant servant, CORBA_Environment * ev) { AtkText *text = get_text_from_servant (servant); - SpiTextRect cbounds, bounds; - int i; + AtkTextRectangle rect; g_return_if_fail (text != NULL); - atk_text_get_character_extents (text, startOffset, - &bounds.x, &bounds.y, &bounds.w, &bounds.h, - (AtkCoordType) coordType); - /* no equivalent ATK API yet, must do the hard way. :-( */ - for (i = startOffset + 1; i < endOffset; i++) - { - atk_text_get_character_extents (text, i, - &cbounds.x, &cbounds.y, &cbounds.w, &cbounds.h, - (AtkCoordType) coordType); - _spi_text_rect_union (&bounds, &cbounds); - } - - *x = bounds.x; - *y = bounds.y; - *width = bounds.w; - *height = bounds.h; + atk_text_get_range_extents (text, (gint) startOffset, (gint) endOffset, + (AtkCoordType) coordType, &rect); + *x = rect.x; + *y = rect.y; + *width = rect.width; + *height = rect.height; } +#define MAXRANGELEN 512 + static Accessibility_Text_RangeList * -_spi_text_range_seq_from_gslist (GSList *range_list) +_spi_text_range_seq_from_atkrangelist (AtkTextRange **range_list) { Accessibility_Text_RangeList *rangeList = Accessibility_Text_RangeList__alloc (); - int i, len = g_slist_length (range_list); - GSList *list = range_list; + int i, len; + + for (len = 0; len < MAXRANGELEN && range_list[len]; ++len); rangeList->_length = len; rangeList->_buffer = Accessibility_Text_RangeList_allocbuf (len); for (i = 0; i < len; ++i) { - memcpy (&rangeList->_buffer[i], list->data, sizeof (Accessibility_Text_Range)); - spi_init_any_nil (&rangeList->_buffer[i].data); - g_free (list->data); - list = g_slist_next (range_list); + rangeList->_buffer[i].startOffset = range_list[i]->start_offset; + rangeList->_buffer[i].endOffset = range_list[i]->end_offset; + rangeList->_buffer[i].content = CORBA_string_dup (range_list[i]->content); } - g_slist_free (range_list); return rangeList; } -static gboolean -_spi_bounds_contain (SpiTextRect *clip, SpiTextRect *cbounds, - Accessibility_TEXT_CLIP_TYPE xClipType, - Accessibility_TEXT_CLIP_TYPE yClipType) -{ - gint clipx2 = clip->x + clip->w; - gint clipy2 = clip->y + clip->h; - gint charx2 = cbounds->x + cbounds->w; - gint chary2 = cbounds->y + cbounds->h; - gboolean x_min_ok, y_min_ok, x_max_ok, y_max_ok; - - x_min_ok = (cbounds->x >= clip->x) || - ((charx2 >= clip->x) && - ((xClipType == Accessibility_TEXT_CLIP_NONE) || - (xClipType == Accessibility_TEXT_CLIP_MAX))); - x_max_ok = (charx2 <= clipx2) || - ((cbounds->x <= clipx2) && - ((xClipType == Accessibility_TEXT_CLIP_NONE) || - (xClipType == Accessibility_TEXT_CLIP_MIN))); - y_min_ok = (cbounds->y >= clip->y) || - ((chary2 >= clip->y) && - ((yClipType == Accessibility_TEXT_CLIP_NONE) || - (yClipType == Accessibility_TEXT_CLIP_MAX))); - y_max_ok = (chary2 <= clipy2) || - ((cbounds->y <= clipy2) && - ((yClipType == Accessibility_TEXT_CLIP_NONE) || - (yClipType == Accessibility_TEXT_CLIP_MIN))); - - if (x_min_ok && y_min_ok && x_max_ok && y_max_ok) - return TRUE; - else - return FALSE; -} - -Accessibility_Text_RangeList * +static Accessibility_Text_RangeList * impl_getBoundedRanges(PortableServer_Servant servant, const CORBA_long x, const CORBA_long y, @@ -569,64 +512,114 @@ impl_getBoundedRanges(PortableServer_Servant servant, CORBA_Environment * ev) { AtkText *text = get_text_from_servant (servant); - GSList *range_list = NULL; - SpiTextRect clip; - int startOffset = 0, endOffset = atk_text_get_character_count (text); - int curr_offset; - gint minLineStart, minLineEnd, maxLineStart, maxLineEnd; - long bounds_min_offset; - long bounds_max_offset; - - clip.x = x; - clip.y = y; - clip.w = width; - clip.h = height; - - /* for horizontal text layouts, at least, the following check helps. */ - bounds_min_offset = atk_text_get_offset_at_point (text, x, y, - (AtkCoordType) coordType); - bounds_max_offset = atk_text_get_offset_at_point (text, x + width, y + height, - (AtkCoordType) coordType); - atk_text_get_text_at_offset (text, bounds_min_offset, - ATK_TEXT_BOUNDARY_LINE_START, - &minLineStart, &minLineEnd); - atk_text_get_text_at_offset (text, bounds_max_offset, - ATK_TEXT_BOUNDARY_LINE_START, - &maxLineStart, &maxLineEnd); - startOffset = MIN (minLineStart, maxLineStart); - endOffset = MAX (minLineEnd, maxLineEnd); - - curr_offset = startOffset; - - while (curr_offset < endOffset) - { - int offset = startOffset; - SpiTextRect cbounds; - while (curr_offset < endOffset) - { - atk_text_get_character_extents (text, curr_offset, - &cbounds.x, &cbounds.y, - &cbounds.w, &cbounds.h, - (AtkCoordType) coordType); - if (!_spi_bounds_contain (&clip, &cbounds, xClipType, yClipType)) - break; - curr_offset++; - } - /* add the range to our list */ - if (curr_offset > offset) - { - Accessibility_Text_Range *range = g_malloc (sizeof (Accessibility_Text_Range)); - char *s; - range->startOffset = offset; - range->endOffset = curr_offset; - s = atk_text_get_text (text, offset, curr_offset); - range->content = CORBA_string_dup (s ? s : ""); - range_list = g_slist_append (range_list, range); - offset = curr_offset; - } - offset++; - } - return _spi_text_range_seq_from_gslist (range_list); /* frees the GSList too */ + AtkTextRange **range_list = NULL; + AtkTextRectangle rect; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + range_list = atk_text_get_bounded_ranges (text, &rect, + (AtkCoordType) coordType, + (AtkTextClipType) xClipType, + (AtkTextClipType) yClipType); + + return _spi_text_range_seq_from_atkrangelist (range_list); +} + + + +static Accessibility_AttributeSet * +impl_getAttributeRun (PortableServer_Servant servant, + const CORBA_long offset, + CORBA_long *startOffset, CORBA_long *endOffset, + const CORBA_boolean includeDefaults, + CORBA_Environment *ev){ + + AtkAttributeSet *attributes, *default_attributes = NULL; + AtkAttribute *attr = NULL; + gint intstart_offset, intend_offset; + Accessibility_AttributeSet *retval = NULL; + AtkText *text = get_text_from_servant (servant); + gint n_attributes = 0, total_attributes = 0, n_default_attributes = 0; + gint i, j; + + g_return_val_if_fail (text != NULL, NULL); + + attributes = atk_text_get_run_attributes (text, offset, + &intstart_offset, &intend_offset); + + if (attributes) total_attributes = n_attributes = g_slist_length (attributes); + + if (includeDefaults) + { + default_attributes = atk_text_get_default_attributes (text); + if (default_attributes) + n_default_attributes = g_slist_length (default_attributes); + total_attributes += n_default_attributes; + } + + *startOffset = intstart_offset; + *endOffset = intend_offset; + + retval = CORBA_sequence_CORBA_string__alloc (); + retval->_length = retval->_maximum = total_attributes; + retval->_buffer = CORBA_sequence_CORBA_string_allocbuf (total_attributes); + CORBA_sequence_set_release (retval, CORBA_TRUE); + + if (total_attributes) + { + for (i = 0; i < n_attributes; ++i) + { + attr = g_slist_nth_data (attributes, i); + retval->_buffer[i] = CORBA_string_dup (g_strconcat (attr->name, ":", attr->value, NULL)); + } + + for (j = 0; j < n_default_attributes; ++i, ++j) + { + attr = g_slist_nth_data (default_attributes, j); + retval->_buffer[i] = CORBA_string_dup (g_strconcat (attr->name, ":", attr->value, NULL)); + } + + atk_attribute_set_free (attributes); + if (default_attributes) + atk_attribute_set_free (default_attributes); + } + return retval; +} + +static Accessibility_AttributeSet * +impl_getDefaultAttributeSet (PortableServer_Servant servant, + CORBA_Environment *ev){ + AtkAttributeSet *attributes; + AtkAttribute *attr = NULL; + Accessibility_AttributeSet *retval = NULL; + AtkText *text = get_text_from_servant (servant); + gint n_attributes = 0; + gint i; + + g_return_val_if_fail (text != NULL, NULL); + + attributes = atk_text_get_default_attributes (text); + + if (attributes) + { + n_attributes = g_slist_length (attributes); + + retval = CORBA_sequence_CORBA_string__alloc (); + retval->_length = retval->_maximum = n_attributes; + retval->_buffer = CORBA_sequence_CORBA_string_allocbuf (n_attributes); + CORBA_sequence_set_release (retval, CORBA_TRUE); + + for (i = 0; i < n_attributes; ++i) + { + attr = g_slist_nth_data (attributes, i); + retval->_buffer [i] = CORBA_string_dup (g_strconcat (attr->name, ":", attr->value, NULL)); + } + atk_attribute_set_free (attributes); + } + return retval; } @@ -656,6 +649,9 @@ spi_text_class_init (SpiTextClass *klass) epv->setCaretOffset = impl_setCaretOffset; epv->getRangeExtents = impl_getRangeExtents; epv->getBoundedRanges = impl_getBoundedRanges; + epv->getAttributeValue = impl_getAttributeValue; + epv->getAttributeRun = impl_getAttributeRun; + epv->getDefaultAttributeSet = impl_getDefaultAttributeSet; } static void