Re: AtkText attributes



Peter Korn says:
>
> > [...discussion about attributes and text ranges...]
> 
> I think the basic tension here is between efficiency and complexity.  It's
> inefficient to look at attributes a single character at a time, but simple. 
> It's more efficient to look at ranges of characters (or runs as they are often
> called), but then we run into interface complexity problems if we want to convey
> all of the attribute information.
>
> Perhaps there is a third way?  What about enumerating the unique attribute runs
> and then allowing the AT to get information about those runs, in addition to
> doing so a character at a time?  Thus, the text:
> 
>  <font="times">This <bold>bold, <italic>itali</bold>ziced </italic> text</font>
> 
> would contain 5 runs: [0-4], [5-10], [11-15], [16-21], and [22-26].

Yes, but many of the attributes overlap runs.  Therefore I'm not sure it is 
reasonable to refer to a run as a "unique attribute run".  Perhaps it is more
accurate to say that each run is a "unique set of attributes run".  For example
run [5-10] has both a "font" setting and is "bolded". 

As you point out below, it is necessary with this scheme for the user to loop
over every single run before the desired one in order to get a complete list of
attributes that are set.  

Let's say I'm personally interested in the attributes on text [18-24]

   I would have to first call a function to find out that my section of interest
   falls between two runs [16-21] and [22-26].  Once this was established I would
   have to loop over all the runs before these to find out what attributes are set.
   
   So I would first notice that the "font" is set in the first run [0-4].  I would 
   notice that "bold" is turned on in the second run [5-10].  I would notice that
   "italic" is turned on in the third run [11-15].  I would notice bold is turned
   off in the fourth run [16-21].  Thus I could certainly compute that the "font"
   and "italic" attributes still apply to the fourth run (the first that I am
   interested in).  So now I know the answer for [18-21] (remember I was originally
   interested in [18-24].  So now I just have to check that last run from 22-26
   to see that just the "font" applies to [22-24].  So now I know the answer.

Isn't this a lot of work to ask the calling program to do?  It seems to me that
it would make the API much easier to use if this work were done inside the API.
For example:

   I call the function saying I am interested in the text from 18-21.  I am
   returned perhaps an array of two structures which have the following info:
   
      struct[0]->attribute = font
      struct[0]->value     = times
      struct[0]->start     = 0
      struct[0]->end       = 26
      struct[1]->attribute = style
      struct[1]->value     = italics
      struct[1]->start     = 11
      struct[1]->end       = 21
      
   Using this data it is very easy for me to see what attributes apply to the
   text that I am interested in.  I can quickly see that the font attribute 
   applies to all of the text between 18-21 and that the italics style applies
   to just 18-21.

   Does this seem like an overly burdened interface to you?
   
This is just a small example.  Obviously the data that must be trudged through
can get huge...so it seems like it would be most efficient to put this logic
in one place so the calling program doesn't have to deal with so much work.
Besides, it is more likely that the code can be properly optimized if it is
in one place.

> An AT gets the following information when querying about text attributes for a
> given character index: the attributes for that index, and the range containing
> that index of similarly attributed text.  Thus, to acquire all of the
> information for the full string, the at would start at index 0, get the
> attribute set and range [0-4], then ask for character index 5 (getting
> attributes and range [5-10]), etc.  If a screen reader were doing an attribute
> search (a feature of outSPOKEN for Windows), they might start from the caret and
> go in run chunks.

The idea of searching is something I had not thought about.  My proposed solution
of returning the array of structures is a little ugly since it requires the user
to request the range from the caret to the end of the buffer and then search on
the results.  The idea of looping over each "unique set of attributes run" 
resolves this issue but forces the calling function to keep track of everything.

If we go with the idea of returning the array of structures, a way to provide
this sort of funtionality would be to add another function that has a "search_for"
argument instead of an "end_range" argument.  This would give the caller access
to a speed efficient attribute search mechanism.

> Another benefit of this approach is that it layers nicely on top of the Java
> Accessibility API which doesn't provide range information: all ranges are simply
> the index in question (so if you ask about index 5, the range you get back is
> [5-5]).  So this approach would work well in the AT SPI.

But the current API lets you ask for the attributes over a range, not just at a
specific index (like 5 in your example above).
 
Brian





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]