static cairo_status_t _cairo_base85_stream_write (cairo_output_stream_t *base, const unsigned char *data, unsigned int length) { cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base; const unsigned char *ptr = data; unsigned char five_tuple[5]; cairo_bool_t is_zero; while (length) { stream->four_tuple[stream->pending++] = *ptr++; length--; if (stream->pending == 4) { _expand_four_tuple_to_five (stream->four_tuple, five_tuple, &is_zero); if (is_zero) _cairo_output_stream_write (stream->output, "z", 1); else _cairo_output_stream_write (stream->output, five_tuple, 5); stream->pending = 0; } } return _cairo_output_stream_get_status (stream->output); }
static cairo_status_t _cairo_xml_emit_type42_font (cairo_xml_t *xml, cairo_scaled_font_t *scaled_font) { const cairo_scaled_font_backend_t *backend; cairo_output_stream_t *base64_stream; cairo_output_stream_t *zlib_stream; cairo_status_t status, status2; unsigned long size; uint32_t len; uint8_t *buf; backend = scaled_font->backend; if (backend->load_truetype_table == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; size = 0; status = backend->load_truetype_table (scaled_font, 0, 0, NULL, &size); if (unlikely (status)) return status; buf = malloc (size); if (unlikely (buf == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = backend->load_truetype_table (scaled_font, 0, 0, buf, &size); if (unlikely (status)) { free (buf); return status; } _cairo_xml_printf_start (xml, "<font type='42' flags='%d' index='0'>", _cairo_ft_scaled_font_get_load_flags (scaled_font)); base64_stream = _cairo_base64_stream_create (xml->stream); len = size; _cairo_output_stream_write (base64_stream, &len, sizeof (len)); zlib_stream = _cairo_deflate_stream_create (base64_stream); _cairo_output_stream_write (zlib_stream, buf, size); free (buf); status2 = _cairo_output_stream_destroy (zlib_stream); if (status == CAIRO_STATUS_SUCCESS) status = status2; status2 = _cairo_output_stream_destroy (base64_stream); if (status == CAIRO_STATUS_SUCCESS) status = status2; _cairo_xml_printf_end (xml, "</font>"); return status; }
/* Emit hexstring bytes up to either the end of the ASCII hexstring or the number * of columns remaining. */ static int _word_wrap_stream_count_hexstring_up_to (word_wrap_stream_t *stream, const unsigned char *data, int length) { const unsigned char *s = data; int count = 0; cairo_bool_t newline = FALSE; while (length--) { count++; stream->column++; if (*s == '>') { stream->state = WRAP_STATE_DELIMITER; break; } if (stream->column > stream->max_column) { newline = TRUE; break; } s++; } if (count) _cairo_output_stream_write (stream->output, data, count); if (newline) { _cairo_output_stream_printf (stream->output, "\n"); stream->column = 0; } return count; }
static cairo_status_t cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src, cairo_gl_var_type_t mask, cairo_gl_var_type_t dest, char **out) { cairo_output_stream_t *stream = _cairo_memory_stream_create (); unsigned char *source; unsigned int length; cairo_status_t status; cairo_gl_shader_emit_variable (stream, src, CAIRO_GL_TEX_SOURCE); cairo_gl_shader_emit_variable (stream, mask, CAIRO_GL_TEX_MASK); _cairo_output_stream_printf (stream, "void main()\n" "{\n" " gl_Position = ftransform();\n"); cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE); cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK); _cairo_output_stream_write (stream, "}\n\0", 3); status = _cairo_memory_stream_destroy (stream, &source, &length); if (unlikely (status)) return status; *out = (char *) source; return CAIRO_STATUS_SUCCESS; }
static void cairo_deflate_stream_deflate (cairo_deflate_stream_t *stream, cairo_bool_t flush) { int ret; cairo_bool_t finished; do { ret = deflate (&stream->zlib_stream, flush ? Z_FINISH : Z_NO_FLUSH); if (flush || stream->zlib_stream.avail_out == 0) { _cairo_output_stream_write (stream->output, stream->output_buf, BUFFER_SIZE - stream->zlib_stream.avail_out); stream->zlib_stream.next_out = stream->output_buf; stream->zlib_stream.avail_out = BUFFER_SIZE; } finished = TRUE; if (stream->zlib_stream.avail_in != 0) finished = FALSE; if (flush && ret != Z_STREAM_END) finished = FALSE; } while (!finished); stream->zlib_stream.next_in = stream->input_buf; }
_cairo_xml_printf (cairo_xml_t *xml, const char *fmt, ...) { va_list ap; char indent[80]; int len; len = MIN (xml->indent, ARRAY_LENGTH (indent)); memset (indent, ' ', len); _cairo_output_stream_write (xml->stream, indent, len); va_start (ap, fmt); _cairo_output_stream_vprintf (xml->stream, fmt, ap); va_end (ap); _cairo_output_stream_write (xml->stream, "\n", 1); }
static cairo_status_t cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src_type, cairo_gl_var_type_t mask_type, cairo_bool_t src_use_atlas, cairo_bool_t mask_use_atlas, cairo_bool_t use_coverage, cairo_gl_var_type_t dest, char **out) { cairo_output_stream_t *stream = _cairo_memory_stream_create (); unsigned char *source; unsigned long length; cairo_status_t status; cairo_gl_shader_emit_variable (stream, src_type, CAIRO_GL_TEX_SOURCE, src_use_atlas); cairo_gl_shader_emit_variable (stream, mask_type, CAIRO_GL_TEX_MASK, mask_use_atlas); if (use_coverage) cairo_gl_shader_dcl_coverage (stream); _cairo_output_stream_printf (stream, "attribute vec4 Vertex;\n" "attribute vec4 Color;\n" "attribute vec4 Coverage;\n" "attribute vec4 MultiTexCoord0;\n" "attribute vec4 MultiTexCoord1;\n" "attribute vec2 StartCoords0;\n" "attribute vec2 StartCoords1;\n" "attribute vec2 StopCoords0;\n" "attribute vec2 StopCoords1;\n" "uniform mat4 ModelViewProjectionMatrix;\n" "void main()\n" "{\n" " gl_Position = ModelViewProjectionMatrix * Vertex;\n"); cairo_gl_shader_emit_vertex (stream, src_type, CAIRO_GL_TEX_SOURCE); cairo_gl_shader_emit_vertex (stream, mask_type, CAIRO_GL_TEX_MASK); if (use_coverage) cairo_gl_shader_def_coverage (stream); if (src_use_atlas) cairo_gl_shader_def_use_atlas (stream, src_type, CAIRO_GL_TEX_SOURCE); if (mask_use_atlas) cairo_gl_shader_def_use_atlas (stream, mask_type, CAIRO_GL_TEX_MASK); _cairo_output_stream_write (stream, "}\n\0", 3); status = _cairo_memory_stream_destroy (stream, &source, &length); if (unlikely (status)) return status; *out = (char *) source; return CAIRO_STATUS_SUCCESS; }
_cairo_xml_printf_end (cairo_xml_t *xml, const char *fmt, ...) { if (fmt != NULL) { va_list ap; va_start (ap, fmt); _cairo_output_stream_vprintf (xml->stream, fmt, ap); va_end (ap); } _cairo_output_stream_write (xml->stream, "\n", 1); }
static cairo_status_t _cairo_base85_stream_close (cairo_output_stream_t *base) { cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base; unsigned char five_tuple[5]; if (stream->pending) { memset (stream->four_tuple + stream->pending, 0, 4 - stream->pending); _expand_four_tuple_to_five (stream->four_tuple, five_tuple, NULL); _cairo_output_stream_write (stream->output, five_tuple, stream->pending + 1); } return _cairo_output_stream_get_status (stream->output); }
static cairo_status_t _word_wrap_stream_write (cairo_output_stream_t *base, const unsigned char *data, unsigned int length) { word_wrap_stream_t *stream = (word_wrap_stream_t *) base; int count; while (length) { switch (stream->state) { case WRAP_STATE_WORD: count = _word_wrap_stream_count_word_up_to (stream, data, length); break; case WRAP_STATE_HEXSTRING: count = _word_wrap_stream_count_hexstring_up_to (stream, data, length); break; case WRAP_STATE_STRING: count = _word_wrap_stream_count_string_up_to (stream, data, length); break; case WRAP_STATE_DELIMITER: count = 1; stream->column++; if (*data == '\n' || stream->column >= stream->max_column) { _cairo_output_stream_printf (stream->output, "\n"); stream->column = 0; } if (*data == '<') { stream->state = WRAP_STATE_HEXSTRING; } else if (*data == '(') { stream->state = WRAP_STATE_STRING; } else if (!_cairo_isspace (*data)) { stream->state = WRAP_STATE_WORD; } if (*data != '\n') _cairo_output_stream_write (stream->output, data, 1); break; default: ASSERT_NOT_REACHED; count = length; break; } data += count; length -= count; } return _cairo_output_stream_get_status (stream->output); }
static cairo_status_t cairo_gl_shader_get_fragment_source (GLuint tex_target, cairo_gl_shader_in_t in, cairo_gl_operand_type_t src, cairo_gl_operand_type_t mask, cairo_gl_operand_type_t dest, char **out) { cairo_output_stream_t *stream = _cairo_memory_stream_create (); unsigned char *source; unsigned int length; cairo_status_t status; cairo_gl_shader_emit_color (stream, tex_target, src, CAIRO_GL_TEX_SOURCE); cairo_gl_shader_emit_color (stream, tex_target, mask, CAIRO_GL_TEX_MASK); _cairo_output_stream_printf (stream, "void main()\n" "{\n"); switch (in) { case CAIRO_GL_SHADER_IN_COUNT: default: ASSERT_NOT_REACHED; case CAIRO_GL_SHADER_IN_NORMAL: _cairo_output_stream_printf (stream, " gl_FragColor = get_source() * get_mask().a;\n"); break; case CAIRO_GL_SHADER_IN_CA_SOURCE: _cairo_output_stream_printf (stream, " gl_FragColor = get_source() * get_mask();\n"); break; case CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA: _cairo_output_stream_printf (stream, " gl_FragColor = get_source().a * get_mask();\n"); break; } _cairo_output_stream_write (stream, "}\n\0", 3); status = _cairo_memory_stream_destroy (stream, &source, &length); if (unlikely (status)) return status; *out = (char *) source; return CAIRO_STATUS_SUCCESS; }
/* Count up to either the end of the string or the number of columns * remaining. */ static int _word_wrap_stream_count_string_up_to (word_wrap_stream_t *stream, const unsigned char *data, int length) { const unsigned char *s = data; int count = 0; cairo_bool_t newline = FALSE; while (length--) { count++; stream->column++; if (!stream->in_escape) { if (*s == ')') { stream->state = WRAP_STATE_DELIMITER; break; } if (*s == '\\') { stream->in_escape = TRUE; stream->escape_digits = 0; } else if (stream->column > stream->max_column) { newline = TRUE; break; } } else { if (!_cairo_isdigit(*s) || ++stream->escape_digits == 3) stream->in_escape = FALSE; } s++; } if (count) _cairo_output_stream_write (stream->output, data, count); if (newline) { _cairo_output_stream_printf (stream->output, "\\\n"); stream->column = 0; } return count; }
/* Emit word bytes up to the next delimiter character */ static int _word_wrap_stream_count_word_up_to (word_wrap_stream_t *stream, const unsigned char *data, int length) { const unsigned char *s = data; int count = 0; while (length--) { if (_cairo_isspace (*s) || *s == '<' || *s == '(') { stream->state = WRAP_STATE_DELIMITER; break; } count++; stream->column++; s++; } if (count) _cairo_output_stream_write (stream->output, data, count); return count; }
static cairo_status_t cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx, cairo_gl_shader_in_t in, cairo_gl_operand_t *src, cairo_gl_operand_t *mask, cairo_bool_t use_coverage, cairo_gl_operand_type_t dest_type, char **out) { cairo_output_stream_t *stream = _cairo_memory_stream_create (); unsigned char *source; unsigned long length; cairo_status_t status; const char *coverage_str; _cairo_output_stream_printf (stream, "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n"); _cairo_gl_shader_emit_wrap (ctx, stream, src, CAIRO_GL_TEX_SOURCE); _cairo_gl_shader_emit_wrap (ctx, stream, mask, CAIRO_GL_TEX_MASK); if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { if (_cairo_gl_shader_needs_border_fade (src)) _cairo_gl_shader_emit_border_fade (stream, src, CAIRO_GL_TEX_SOURCE); if (_cairo_gl_shader_needs_border_fade (mask)) _cairo_gl_shader_emit_border_fade (stream, mask, CAIRO_GL_TEX_MASK); } cairo_gl_shader_emit_color (stream, ctx, src, CAIRO_GL_TEX_SOURCE); cairo_gl_shader_emit_color (stream, ctx, mask, CAIRO_GL_TEX_MASK); coverage_str = ""; if (use_coverage) { _cairo_output_stream_printf (stream, "varying float coverage;\n"); coverage_str = " * coverage"; } _cairo_output_stream_printf (stream, "void main()\n" "{\n"); switch (in) { case CAIRO_GL_SHADER_IN_COUNT: default: ASSERT_NOT_REACHED; case CAIRO_GL_SHADER_IN_NORMAL: _cairo_output_stream_printf (stream, " gl_FragColor = get_source() * get_mask().a%s;\n", coverage_str); break; case CAIRO_GL_SHADER_IN_CA_SOURCE: _cairo_output_stream_printf (stream, " gl_FragColor = get_source() * get_mask()%s;\n", coverage_str); break; case CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA: _cairo_output_stream_printf (stream, " gl_FragColor = get_source().a * get_mask()%s;\n", coverage_str); break; } _cairo_output_stream_write (stream, "}\n\0", 3); status = _cairo_memory_stream_destroy (stream, &source, &length); if (unlikely (status)) return status; *out = (char *) source; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _write_func (void *closure, const unsigned char *data, unsigned len) { _cairo_output_stream_write (closure, data, len); return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _word_wrap_stream_write (cairo_output_stream_t *base, const unsigned char *data, unsigned int length) { word_wrap_stream_t *stream = (word_wrap_stream_t *) base; cairo_bool_t newline; int word; while (length) { if (*data == '<') { stream->in_hexstring = TRUE; stream->empty_hexstring = TRUE; stream->last_write_was_space = FALSE; data++; length--; _cairo_output_stream_printf (stream->output, "<"); stream->column++; } else if (*data == '>') { stream->in_hexstring = FALSE; stream->last_write_was_space = FALSE; data++; length--; _cairo_output_stream_printf (stream->output, ">"); stream->column++; } else if (_cairo_isspace (*data)) { newline = (*data == '\n' || *data == '\r'); if (! newline && stream->column >= stream->max_column) { _cairo_output_stream_printf (stream->output, "\n"); stream->column = 0; } _cairo_output_stream_write (stream->output, data, 1); data++; length--; if (newline) { stream->column = 0; } else stream->column++; stream->last_write_was_space = TRUE; } else { if (stream->in_hexstring) { word = _count_hexstring_up_to (data, length, MAX (stream->max_column - stream->column, 0)); } else { word = _count_word_up_to (data, length); } /* Don't wrap if this word is a continuation of a non hex * string word from a previous call to write. */ if (stream->column + word >= stream->max_column) { if (stream->last_write_was_space || (stream->in_hexstring && !stream->empty_hexstring)) { _cairo_output_stream_printf (stream->output, "\n"); stream->column = 0; } } _cairo_output_stream_write (stream->output, data, word); data += word; length -= word; stream->column += word; stream->last_write_was_space = FALSE; if (stream->in_hexstring) stream->empty_hexstring = FALSE; } } return _cairo_output_stream_get_status (stream->output); }