⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cairo-ps-surface.c

📁 按照官方的说法:Cairo is a vector graphics library with cross-device output support. 翻译过来
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* FIXME: Figure out document structure convention for fonts */    _cairo_output_stream_printf (surface->final_stream,				 "%% _cairo_ps_surface_emit_truetype_font_subset\n");    _cairo_output_stream_printf (surface->final_stream,				 "11 dict begin\n"				 "/FontType 42 def\n"				 "/FontName /CairoFont-%d-%d def\n"				 "/PaintType 0 def\n"				 "/FontMatrix [ 1 0 0 1 0 0 ] def\n"				 "/FontBBox [ 0 0 0 0 ] def\n"				 "/Encoding 256 array def\n"				 "0 1 255 { Encoding exch /.notdef put } for\n",				 font_subset->font_id,				 font_subset->subset_id);    /* FIXME: Figure out how subset->x_max etc maps to the /FontBBox */    for (i = 1; i < font_subset->num_glyphs; i++)	_cairo_output_stream_printf (surface->final_stream,				     "Encoding %d /g%d put\n", i, i);    _cairo_output_stream_printf (surface->final_stream,				 "/CharStrings %d dict dup begin\n"				 "/.notdef 0 def\n",				 font_subset->num_glyphs);    for (i = 1; i < font_subset->num_glyphs; i++)	_cairo_output_stream_printf (surface->final_stream,				     "/g%d %d def\n", i, i);    _cairo_output_stream_printf (surface->final_stream,				 "end readonly def\n");    /* FIXME: We need to break up fonts bigger than 64k so we don't     * exceed string size limitation.  At glyph boundaries.  Stupid     * postscript. */    _cairo_output_stream_printf (surface->final_stream,				 "/sfnts [<");    _cairo_output_stream_write_hex_string (surface->final_stream,					   subset.data, subset.data_length);    _cairo_output_stream_printf (surface->final_stream,				 ">] def\n"				 "FontName currentdict end definefont pop\n");    _cairo_truetype_subset_fini (&subset);    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_ps_surface_emit_outline_glyph_data (cairo_ps_surface_t	*surface,					   cairo_scaled_font_t	*scaled_font,					   unsigned long	 glyph_index){    cairo_scaled_glyph_t *scaled_glyph;    cairo_status_t status;    status = _cairo_scaled_glyph_lookup (scaled_font,					 glyph_index,					 CAIRO_SCALED_GLYPH_INFO_METRICS|					 CAIRO_SCALED_GLYPH_INFO_PATH,					 &scaled_glyph);    if (status)	return status;    _cairo_output_stream_printf (surface->final_stream,				 "0 0 %f %f %f %f setcachedevice\n",				 _cairo_fixed_to_double (scaled_glyph->bbox.p1.x),				 -_cairo_fixed_to_double (scaled_glyph->bbox.p2.y),				 _cairo_fixed_to_double (scaled_glyph->bbox.p2.x),				 -_cairo_fixed_to_double (scaled_glyph->bbox.p1.y));    /* We're filling not stroking, so we pass CAIRO_LINE_CAP_ROUND. */    status = _cairo_ps_surface_emit_path (surface,					  surface->final_stream,					  scaled_glyph->path,					  CAIRO_LINE_CAP_ROUND);    _cairo_output_stream_printf (surface->final_stream,				 "F\n");    return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_ps_surface_emit_bitmap_glyph_data (cairo_ps_surface_t	*surface,					  cairo_scaled_font_t	*scaled_font,					  unsigned long	 glyph_index){    cairo_scaled_glyph_t *scaled_glyph;    cairo_status_t status;    cairo_image_surface_t *image;    unsigned char *row, *byte;    int rows, cols, bytes_per_row;    status = _cairo_scaled_glyph_lookup (scaled_font,					 glyph_index,					 CAIRO_SCALED_GLYPH_INFO_METRICS|					 CAIRO_SCALED_GLYPH_INFO_SURFACE,					 &scaled_glyph);    image = scaled_glyph->surface;    assert (image->format == CAIRO_FORMAT_A1);    _cairo_output_stream_printf (surface->final_stream,				 "0 0 %f %f %f %f setcachedevice\n",				 _cairo_fixed_to_double (scaled_glyph->bbox.p1.x),				 - _cairo_fixed_to_double (scaled_glyph->bbox.p2.y),				 _cairo_fixed_to_double (scaled_glyph->bbox.p2.x),				 - _cairo_fixed_to_double (scaled_glyph->bbox.p1.y));    _cairo_output_stream_printf (surface->final_stream,				 "<<\n"				 "   /ImageType 1\n"				 "   /Width %d\n"				 "   /Height %d\n"				 "   /ImageMatrix [%f %f %f %f %f %f]\n"				 "   /Decode [1 0]\n"				 "   /BitsPerComponent 1\n",				 image->width,				 image->height,				 image->base.device_transform.xx,				 image->base.device_transform.yx,				 image->base.device_transform.xy,				 image->base.device_transform.yy,				 image->base.device_transform.x0,				 - image->base.device_transform.y0);    _cairo_output_stream_printf (surface->final_stream,				 "   /DataSource   {<");    bytes_per_row = (image->width + 7) / 8;    for (row = image->data, rows = image->height; rows; row += image->stride, rows--) {	for (byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {	    unsigned char output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);	    _cairo_output_stream_printf (surface->final_stream, "%02x ", output_byte);	}	_cairo_output_stream_printf (surface->final_stream, "\n   ");    }    _cairo_output_stream_printf (surface->final_stream,				 "   >}\n");    _cairo_output_stream_printf (surface->final_stream,				 ">>\n");    _cairo_output_stream_printf (surface->final_stream,				 "imagemask\n");    return CAIRO_STATUS_SUCCESS;}static void_cairo_ps_surface_emit_glyph (cairo_ps_surface_t	*surface,			      cairo_scaled_font_t	*scaled_font,			      unsigned long		 scaled_font_glyph_index,			      unsigned int		 subset_glyph_index){    cairo_status_t	    status;    _cairo_output_stream_printf (surface->final_stream,				 "\t\t{ %% %d\n", subset_glyph_index);    status = _cairo_ps_surface_emit_outline_glyph_data (surface,							scaled_font,							scaled_font_glyph_index);    if (status == CAIRO_INT_STATUS_UNSUPPORTED)	status = _cairo_ps_surface_emit_bitmap_glyph_data (surface,							   scaled_font,							   scaled_font_glyph_index);    _cairo_output_stream_printf (surface->final_stream,				 "\t\t}\n");    if (status)	_cairo_surface_set_error (&surface->base, status);}static cairo_status_t_cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t		*surface,					  cairo_scaled_font_subset_t	*font_subset){    cairo_matrix_t matrix;    int i;    _cairo_output_stream_printf (surface->final_stream,				 "%% _cairo_ps_surface_emit_type3_font_subset\n");    _cairo_output_stream_printf (surface->final_stream,				 "/CairoFont-%d-%d <<\n",				 font_subset->font_id,				 font_subset->subset_id);    matrix = font_subset->scaled_font->scale;    cairo_matrix_invert (&matrix);    _cairo_output_stream_printf (surface->final_stream,				 "\t/FontType\t3\n"				 "\t/FontMatrix\t[%f %f %f %f 0 0]\n"				 "\t/Encoding\t[0]\n"				 "\t/FontBBox\t[0 0 10 10]\n"				 "\t/Glyphs [\n",				 matrix.xx,				 matrix.yx,				 -matrix.xy,				 -matrix.yy);    for (i = 0; i < font_subset->num_glyphs; i++) {	_cairo_ps_surface_emit_glyph (surface,				      font_subset->scaled_font,				      font_subset->glyphs[i], i);    }    _cairo_output_stream_printf (surface->final_stream,				 "\t]\n"				 "\t/BuildChar {\n"				 "\t\texch /Glyphs get\n"				 "\t\texch get exec\n"				 "\t}\n"				 ">> definefont pop\n");    return CAIRO_STATUS_SUCCESS;}static void_cairo_ps_surface_emit_font_subset (cairo_scaled_font_subset_t	*font_subset,				    void			*closure){    cairo_ps_surface_t *surface = closure;    cairo_status_t status;    status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset);    if (status != CAIRO_INT_STATUS_UNSUPPORTED)	return;    status = _cairo_ps_surface_emit_truetype_font_subset (surface, font_subset);    if (status != CAIRO_INT_STATUS_UNSUPPORTED)	return;    status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset);    if (status != CAIRO_INT_STATUS_UNSUPPORTED)	return;}static cairo_status_t_cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface){    cairo_status_t status;    _cairo_output_stream_printf (surface->final_stream,				 "%% _cairo_ps_surface_emit_font_subsets\n");    status = _cairo_scaled_font_subsets_foreach (surface->font_subsets,						 _cairo_ps_surface_emit_font_subset,						 surface);    _cairo_scaled_font_subsets_destroy (surface->font_subsets);    surface->font_subsets = NULL;    return status;}static void_cairo_ps_surface_emit_body (cairo_ps_surface_t *surface){    char    buf[4096];    int	    n;    rewind (surface->tmpfile);    while ((n = fread (buf, 1, sizeof (buf), surface->tmpfile)) > 0)	_cairo_output_stream_write (surface->final_stream, buf, n);}static void_cairo_ps_surface_emit_footer (cairo_ps_surface_t *surface){    _cairo_output_stream_printf (surface->final_stream,				 "%%%%Trailer\n"				 "%%%%EOF\n");}static cairo_surface_t *_cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,					      double		     width,					      double		     height){    cairo_status_t status;    cairo_ps_surface_t *surface = NULL;    surface = malloc (sizeof (cairo_ps_surface_t));    if (surface == NULL) {	status = CAIRO_STATUS_NO_MEMORY;	goto CLEANUP;    }    _cairo_surface_init (&surface->base, &cairo_ps_surface_backend,			 CAIRO_CONTENT_COLOR_ALPHA);    surface->final_stream = stream;    surface->tmpfile = tmpfile ();    if (surface->tmpfile == NULL)	goto CLEANUP_SURFACE;    surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile);    status = _cairo_output_stream_get_status (surface->stream);    if (status)	goto CLEANUP_TMPFILE;    surface->font_subsets = _cairo_scaled_font_subsets_create (PS_SURFACE_MAX_GLYPHS_PER_FONT);    if (! surface->font_subsets)	goto CLEANUP_OUTPUT_STREAM;    surface->width  = width;    surface->height = height;    surface->max_width = width;    surface->max_height = height;    surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;    surface->num_pages = 0;    _cairo_array_init (&surface->dsc_header_comments, sizeof (char *));    _cairo_array_init (&surface->dsc_setup_comments, sizeof (char *));    _cairo_array_init (&surface->dsc_page_setup_comments, sizeof (char *));    surface->dsc_comment_target = &surface->dsc_header_comments;    return _cairo_paginated_surface_create (&surface->base,					    CAIRO_CONTENT_COLOR_ALPHA,					    width, height,					    &cairo_ps_surface_paginated_backend); CLEANUP_OUTPUT_STREAM:    _cairo_output_stream_destroy (surface->stream); CLEANUP_TMPFILE:    fclose (surface->tmpfile); CLEANUP_SURFACE:    free (surface); CLEANUP:    _cairo_error (CAIRO_STATUS_NO_MEMORY);    return (cairo_surface_t*) &_cairo_surface_nil;}/** * cairo_ps_surface_create: * @filename: a filename for the PS output (must be writable) * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) * * Creates a PostScript surface of the specified size in points to be * written to @filename. See cairo_ps_surface_create_for_stream() for * a more flexible mechanism for handling the PostScript output than * simply writing it to a named file. * * Note that the size of individual pages of the PostScript output can * vary. See cairo_ps_surface_set_size(). * * Return value: a pointer to the newly created surface. The caller * owns the surface and should call cairo_surface_destroy when done * with it. * * This function always returns a valid pointer, but it will return a * pointer to a "nil" surface if an error such as out of memory * occurs. You can use cairo_surface_status() to check for this. * * Since: 1.2 **/cairo_surface_t *cairo_ps_surface_create (const char		*filename,			 double			 width_in_points,			 double			 height_in_points){    cairo_status_t status;    cairo_output_stream_t *stream;    stream = _cairo_output_stream_create_for_filename (filename);    status = _cairo_output_stream_get_status (stream);    if (status) {	_cairo_error (status);	return (cairo_surface_t*) &_cairo_surface_nil;    }    return _cairo_ps_surface_create_for_stream_internal (stream,							 width_in_points,							 height_in_points);}/** * cairo_ps_surface_create_for_stream: * @write_func: a #cairo_write_func_t to accept the output data * @closure: the closure argument for @write_func * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) * * Creates a PostScript surface of the specified size in points to be * written incrementally to the stream represented by @write_func and * @closure. See cairo_ps_surface_create() for a more convenient way * to simply direct the PostScript output to a named file. * * Note that the size of individual pages of the PostScript * output can vary. See cairo_ps_surface_set_size(). * * Return value: a pointer to the newly created surface. The caller * owns the surface and should call cairo_surface_destroy when done * with it. * * This function always returns a valid pointer, but it will return a * pointer to a "nil" surface if an error such as out of memory * occurs. You can use cairo_surface_status() to check for this. * * Since: 1.2 */cairo_surface_t *cairo_ps_surface_create_for_stream (cairo_write_func_t	write_func,				    void	       *closure,				    double		width_in_points,				    double		height_in_points){    cairo_status_t status;    cairo_output_stream_t *stream;    stream = _cairo_output_stream_create (write_func, NULL, closure);    status = _cairo_output_stream_get_status (stream);    if (status) {	_cairo_error (status);	return (cairo_surface_t*) &_cairo_surface_nil;    }    return _cairo_ps_surface_create_for_stream_internal (stream,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -