[Xcb] xcb_render_util_composite_text

Ian Osgood iano at quirkster.com
Sat Oct 14 14:47:20 PDT 2006

On Oct 14, 2006, at 1:47 PM, Jamey Sharp wrote:

> Hi Ian! I love this proposal, and as far as I can tell you've  
> correctly
> understood the protocol. I think bringing this up on the xorg list  
> would
> catch the attention of more of its prospective users though.

Feel free to forward it, since I don't subscribe.
> This approach should help with PolyText8 and PolyText16 from the core
> protocol, too, as CompositeGlyphs was pretty clearly modeled after
> those -- not that anybody should be using them any more.

> On Sat, Oct 14, 2006 at 11:39:11AM -0700, Ian Osgood wrote:
>>   composite_text_stream_t stream;
>>   stream = composite_text_stream(initial_glyphset,
>> total_glyph_count, total_glyphset_changes)
> Would this assume that the glyphs are 32-bit for the purposes of  
> memory
> allocation? And, I guess, also assume that every glyph might need its
> own header with a non-zero dx or dy.

Yes, For preallocation I'd assume one 8-byte header per single glyph  
(which is padded to a minimum of 4 bytes). This seems to be what the  
professional layout engines, such as cairo, are doing anyway.
> For code-as-documentation purposes, perhaps "max_glyph_count" and
> "max_glyphset_changes"?

No, I like my names better. "Max" might get confused for the maximum  
of the counts on each glyphs request.
>>   composite_text_glyphs_8( stream, uint32_t count, uint8_t *glyphs,
>> int16_t dx, int16_t dy)
>>   composite_text_glyphs_16( stream, uint32_t count, uint16_t
>> *glyphs, int16_t dx, int16_t dy)
>>   composite_text_glyphs_32( stream, uint32_t count, uint32_t
>> *glyphs, int16_t dx, int16_t dy)
> I would have stuck the dx and dy parameters before count, since these
> mean "First move the pen by (dx,dy) pixels, then draw count glyphs."

I could live with that.  If we stuck with protocol order, it would be  
(count, dx, dy, glyphs) which is just wrong.  For reference, the  
XGlyphElt this is replacing consists of { glyphset, glyphs, count,  
dx, dy }.
> I note that this interface allows for a lot more than 254 glyphs per
> call. :-) I guess this obligates us to split the glyph sequences into
> 254-glyph groups.

Yes, for convenience to users and compatibility with existing  
XRender. (In the first test iteration, I'll simply disallow greater  
> You haven't indicated how errors should be handled: mainly, what if  
> the
> caller tries to pass in more glyphs or glyphsets than they allocated
> space for?

The initial buffer would grow, so I don't consider this an error  
condition.  Preallocation is just an optimization.
>> This would build up the stream of commands incrementally. The stream
>> is allocated in _stream and deallocated when sent.
> I wonder whether it should be deallocated when sent? The caller might
> want to composite the same stream multiple times. They might also want
> to free it without sending it, perhaps because an error occurred.

That is an excellent point.  I'll change the semantics to separate  
deallocation from sending:

   composite_text_free( stream );

> If we don't free it when sent, should we allow more glyphs to be added
> afterwards? I'm thinking no: sending the stream makes it constant.

There is nothing in my current implementation that would prevent this.
>> Disadvantages:
>> * allows incorrectly mixing 8,16,32 glyphs (though this would be
>> detected at runtime)
> We can define sensible semantics for such a mixture, and it might be
> useful. Semantically, these are all equivalent to 32-bit glyphs: the
> server zero-extends the glyph indexes. When we're handed a sequence of
> glyphs, we could check what the smallest possible representation is  
> for
> those glyphs. When we're ready to send the request, we can pick the
> smallest request type that can handle the largest glyph we've been
> handed.
> Another obvious optimization we could apply is that if the last thing
> added to the stream was a glyph sequence with fewer than 254 glyphs  
> and
> we're adding a glyph sequence with (dx,dy) == (0,0), then we can avoid
> producing a new glyph header.

Yes, we could do this (the abstraction advantage I mentioned).

My current implementation is laying out the wire protocol request  
into the stream on each call. Changing sizes mid-stream would require  
me to regeneratethe stream from scratch (doable, but tedious,  
especially since it is in network byte order).

For the first iteration, I'll just support one size and consider  
mixing an error. I don't think this will be much of a problem, since  
current users of XRenderCompositeText must check ahead of time anyway.


> Of course, you noted that this interface was nice for being close  
> to the
> wire protocol. Since these optimizations don't affect the API you've
> suggested, we could have a second constructor that disables them.
> Perhaps composite_text_stream_raw? Probably raw mode would make it a
> run-time error to mix 8-bit, 16-bit, or 32-bit glyph sequences in the
> same stream.
> --Jamey

More information about the Xcb mailing list