diff options
author | Ian Osgood <iano@quirkster.com> | 2006-10-14 16:09:49 -0700 |
---|---|---|
committer | Ian Osgood <iano@quirkster.com> | 2006-10-14 16:09:49 -0700 |
commit | 28067bae7f889af3c8b03eec930e59215f35dcdf (patch) | |
tree | 956707a97f70269689c7a85ce3128e806d475d5f /renderutil | |
parent | 4855f61ddb172e8f608083025775d155566979d5 (diff) |
Implement a prototype API for xcb_render_util_composite_text
This API wraps xcb_render_composite_glyphs_8/16/32, making them usable.
This currently has the limitation of not supporting lists of glyphs
longer than 252 for text_8 or 254 otherwise.
Currently untested; work into cairo or demo/rendertest.
Diffstat (limited to 'renderutil')
-rw-r--r-- | renderutil/Makefile.am | 2 | ||||
-rw-r--r-- | renderutil/glyph.c | 259 | ||||
-rw-r--r-- | renderutil/xcb_renderutil.h | 56 |
3 files changed, 316 insertions, 1 deletions
diff --git a/renderutil/Makefile.am b/renderutil/Makefile.am index 0d43b04..3188a05 100644 --- a/renderutil/Makefile.am +++ b/renderutil/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libXCBRenderUtil.la xcbinclude_HEADERS = xcb_renderutil.h -libXCBRenderUtil_la_SOURCES = cache.c util.c +libXCBRenderUtil_la_SOURCES = cache.c util.c glyph.c libXCBRenderUtil_la_CFLAGS = $(XCB_CFLAGS) $(XCB_RENDER_CFLAGS) libXCBRenderUtil_la_LIBADD = $(XCB_LIBS) $(XCB_RENDER_LIBS) diff --git a/renderutil/glyph.c b/renderutil/glyph.c new file mode 100644 index 0000000..852ed01 --- /dev/null +++ b/renderutil/glyph.c @@ -0,0 +1,259 @@ +/* Copyright © 2006 Ian Osgood + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include <stdlib.h> +#include <string.h> + +#include "xcb_renderutil.h" + +typedef struct _glyph_header_t { + uint8_t count; + uint8_t pad0[3]; + int16_t dx, dy; +} _glyph_header_t; + +/* implementation of the opaque stream */ +struct xcb_render_util_composite_text_stream_t { + /* state info */ + uint32_t glyph_size; /* 0 for unset, 1/2/4 for 8/16/32 */ + xcb_render_glyphset_t initial_glyphset; + xcb_render_glyphset_t current_glyphset; + + /* dynamically allocated stream */ + /* contents are 32-bit aligned, network byte order */ + size_t stream_len; + uint32_t *stream; + uint32_t *current; +}; + +#define CURRENT_LEN(s) (((char *)s->current - (char *)s->stream)) + +xcb_render_util_composite_text_stream_t * +xcb_render_util_composite_text_stream ( + xcb_render_glyphset_t initial_glyphset, + uint32_t total_glyphs, + uint32_t total_glyphset_changes ) +{ + xcb_render_util_composite_text_stream_t *stream; + size_t size = 32; + + /* assume worst case: each glyph has its own dx,dy */ + if (total_glyphs || total_glyphset_changes) { + size = total_glyphs * 3 * sizeof(uint32_t) + + total_glyphset_changes * 3 * sizeof(uint32_t); + } + + stream = malloc(sizeof(xcb_render_util_composite_text_stream_t)); + + stream->glyph_size = 0; + stream->initial_glyphset = initial_glyphset; + stream->current_glyphset = initial_glyphset; + + stream->stream_len = size; + stream->stream = malloc(size); + stream->current = stream->stream; + + return stream; +} + +static void +_grow_stream( xcb_render_util_composite_text_stream_t *stream, size_t increase ) +{ + size_t current_len = CURRENT_LEN(stream); + if (current_len + increase > stream->stream_len) { + uint32_t *s = realloc(stream->stream, 2 * stream->stream_len); + if (s != NULL) { + stream->stream_len *= 2; + stream->stream = s; + stream->current = stream->stream + (current_len>>2); + } + } +} + +void +xcb_render_util_glyphs_8 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + uint8_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, htons(dx), htons(dy) }; + + if (count > 252) return; /* FIXME */ + + if (stream->glyph_size != sizeof(*glyphs)) { + if (stream->glyph_size != 0) + return; + stream->glyph_size = sizeof(*glyphs); + } + _grow_stream(stream, sizeof(header) + count+3); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + memcpy(stream->current, glyphs, header.count); + stream->current += ((int)header.count+3)>>2; +} + +void +xcb_render_util_glyphs_16 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + uint16_t *glyphs ) +{ + uint16_t *current16; + _glyph_header_t header = { count, {0,0,0}, htons(dx), htons(dy) }; + + if (count > 254) return; /* FIXME */ + + if (stream->glyph_size != sizeof(*glyphs)) { + if (stream->glyph_size != 0) + return; + stream->glyph_size = sizeof(*glyphs); + } + _grow_stream(stream, sizeof(header) + count*sizeof(*glyphs)+1); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + current16 = (uint16_t *)stream->current; + while (count--) { + *current16++ = htons(*glyphs++); + } + stream->current += ((int)header.count*sizeof(*glyphs)+1)>>2; +} + +void +xcb_render_util_glyphs_32 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + uint32_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, htons(dx), htons(dy) }; + + if (count > 254) return; /* FIXME */ + + if (stream->glyph_size != sizeof(*glyphs)) { + if (stream->glyph_size != 0) + return; + stream->glyph_size = sizeof(*glyphs); + } + _grow_stream(stream, sizeof(header) + count*sizeof(*glyphs)+1); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + while (count--) { + *stream->current++ = htonl(*glyphs++); + } +} + +/* note: these glyph arrays must be swapped to network byte order */ + +void +xcb_render_util_change_glyphset ( + xcb_render_util_composite_text_stream_t *stream, + xcb_render_glyphset_t glyphset ) +{ + static _glyph_header_t header = { 255, {0,0,0}, 0, 0 }; + + if (glyphset == stream->current_glyphset) + return; + + _grow_stream(stream, 3*sizeof(uint32_t)); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + *stream->current = htonl(glyphset); + stream->current++; + + stream->current_glyphset = glyphset; +} + + +xcb_void_cookie_t +xcb_render_util_composite_text ( + xcb_connection_t *xc, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + int16_t src_x, + int16_t src_y, + xcb_render_util_composite_text_stream_t *stream ) +{ + xcb_void_cookie_t reply = { 0 }; + uint32_t stream_len = CURRENT_LEN(stream); + + switch (stream->glyph_size) + { + case 1: + reply = xcb_render_composite_glyphs_8 ( + xc, op, src, dst, mask_format, + stream->initial_glyphset, + src_x, src_y, + stream_len, + (uint8_t *)stream->stream + ); + break; + case 2: + reply = xcb_render_composite_glyphs_16 ( + xc, op, src, dst, mask_format, + stream->initial_glyphset, + src_x, src_y, + stream_len, + (uint8_t *)stream->stream + ); + break; + case 4: + reply = xcb_render_composite_glyphs_32 ( + xc, op, src, dst, mask_format, + stream->initial_glyphset, + src_x, src_y, + stream_len, + (uint8_t *)stream->stream + ); + break; + default: /* uninitialized */ + break; + } + return reply; +} + +/* FIXME: xcb_render_util_composite_text_checked */ + +void +xcb_render_util_composite_text_free ( + xcb_render_util_composite_text_stream_t *stream ) +{ + free(stream->stream); + free(stream); +} diff --git a/renderutil/xcb_renderutil.h b/renderutil/xcb_renderutil.h index d3ffb2b..c374eac 100644 --- a/renderutil/xcb_renderutil.h +++ b/renderutil/xcb_renderutil.h @@ -28,6 +28,7 @@ #include <xcb/render.h> /* FIXME: These PictFormat declarations should be in render.xml. */ +/* FIXME: update the names for the new XCB naming conventions */ #define PictFormatID (1 << 0) #define PictFormatType (1 << 1) #define PictFormatDepth (1 << 2) @@ -50,6 +51,7 @@ enum { PictStandardNUM }; + xcb_render_pictvisual_t * xcb_render_util_find_visual_format (const xcb_render_query_pict_formats_reply_t *formats, const xcb_visualid_t visual); @@ -73,4 +75,58 @@ xcb_render_util_query_formats (xcb_connection_t *c); int xcb_render_util_disconnect (xcb_connection_t *c); +/* wrappers for xcb_render_composite_glyphs_8/16/32 */ + +typedef struct xcb_render_util_composite_text_stream_t xcb_render_util_composite_text_stream_t; + +xcb_render_util_composite_text_stream_t * +xcb_render_util_composite_text_stream ( + xcb_render_glyphset_t initial_glyphset, + uint32_t total_glyphs, + uint32_t total_glyphset_changes ); + +void +xcb_render_util_glyphs_8 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + uint8_t *glyphs ); + +void +xcb_render_util_glyphs_16 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + uint16_t *glyphs ); + +void +xcb_render_util_glyphs_32 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + uint32_t *glyphs ); + +void +xcb_render_util_change_glyphset ( + xcb_render_util_composite_text_stream_t *stream, + xcb_render_glyphset_t glyphset ); + +xcb_void_cookie_t +xcb_render_util_composite_text ( + xcb_connection_t *xc, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + int16_t src_x, + int16_t src_y, + xcb_render_util_composite_text_stream_t *stream ); + +void +xcb_render_util_composite_text_free ( + xcb_render_util_composite_text_stream_t *stream ); + #endif /* XCB_RENDERUTIL */ |