From 80ab0233688c9df9fd48265b6f9e7ab7cd589dbc Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 19 Aug 2023 23:50:04 +0200 Subject: Initial commit --- depends/libxcb-render-util/xcb/glyph.c | 293 +++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 depends/libxcb-render-util/xcb/glyph.c (limited to 'depends/libxcb-render-util/xcb/glyph.c') diff --git a/depends/libxcb-render-util/xcb/glyph.c b/depends/libxcb-render-util/xcb/glyph.c new file mode 100644 index 0000000..d19fba6 --- /dev/null +++ b/depends/libxcb-render-util/xcb/glyph.c @@ -0,0 +1,293 @@ +/* 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#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)); + if (!stream) + return NULL; + + 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, + const uint8_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, dx, 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, + const uint16_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, dx, 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; + + memcpy(stream->current, glyphs, header.count*sizeof(*glyphs)); + stream->current += ((int)header.count*sizeof(*glyphs)+3)>>2; +} + +void +xcb_render_util_glyphs_32 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + const uint32_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, dx, 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; + + memcpy(stream->current, glyphs, header.count*sizeof(*glyphs)); + stream->current += header.count; +} + +/* 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 = glyphset; + stream->current++; + + stream->current_glyphset = glyphset; +} + +typedef xcb_void_cookie_t +(*xcb_render_composite_glyphs_func) (xcb_connection_t *c, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + xcb_render_glyphset_t glyphset, + int16_t src_x, + int16_t src_y, + uint32_t glyphcmds_len, + const uint8_t *glyphcmds); + + +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_render_composite_glyphs_func f; + + switch (stream->glyph_size) + { + case 1: + f = xcb_render_composite_glyphs_8; + break; + case 2: + f = xcb_render_composite_glyphs_16; + break; + case 4: + f = xcb_render_composite_glyphs_32; + break; + default: /* uninitialized */ + return xcb_no_operation(xc); + } + return f( + xc, op, src, dst, mask_format, + stream->initial_glyphset, + src_x, src_y, + CURRENT_LEN(stream), + (uint8_t *)stream->stream + ); +} + +xcb_void_cookie_t +xcb_render_util_composite_text_checked ( + 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_render_composite_glyphs_func f; + + switch (stream->glyph_size) + { + case 1: + f = xcb_render_composite_glyphs_8_checked; + break; + case 2: + f = xcb_render_composite_glyphs_16_checked; + break; + case 4: + f = xcb_render_composite_glyphs_32_checked; + break; + default: /* uninitialized */ + return xcb_no_operation_checked(xc); + } + return f( + xc, op, src, dst, mask_format, + stream->initial_glyphset, + src_x, src_y, + CURRENT_LEN(stream), + (uint8_t *)stream->stream + ); +} + +void +xcb_render_util_composite_text_free ( + xcb_render_util_composite_text_stream_t *stream ) +{ + free(stream->stream); + free(stream); +} -- cgit v1.2.3