📄 cairo-pdf-surface.c
字号:
cairo_rectangle_int16_t *rectangle){ cairo_pdf_surface_t *surface = abstract_surface; rectangle->x = 0; rectangle->y = 0; /* XXX: The conversion to integers here is pretty bogus, (not to * mention the aribitray limitation of width to a short(!). We * may need to come up with a better interface for get_size. */ rectangle->width = (int) ceil (surface->width); rectangle->height = (int) ceil (surface->height); return CAIRO_STATUS_SUCCESS;}typedef struct _pdf_path_info { cairo_output_stream_t *output; cairo_matrix_t *ctm_inverse;} pdf_path_info_t;static cairo_status_t_cairo_pdf_path_move_to (void *closure, cairo_point_t *point){ pdf_path_info_t *info = closure; double x = _cairo_fixed_to_double (point->x); double y = _cairo_fixed_to_double (point->y); if (info->ctm_inverse) cairo_matrix_transform_point (info->ctm_inverse, &x, &y); _cairo_output_stream_printf (info->output, "%f %f m ", x, y); return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_pdf_path_line_to (void *closure, cairo_point_t *point){ pdf_path_info_t *info = closure; double x = _cairo_fixed_to_double (point->x); double y = _cairo_fixed_to_double (point->y); if (info->ctm_inverse) cairo_matrix_transform_point (info->ctm_inverse, &x, &y); _cairo_output_stream_printf (info->output, "%f %f l ", x, y); return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_pdf_path_curve_to (void *closure, cairo_point_t *b, cairo_point_t *c, cairo_point_t *d){ pdf_path_info_t *info = closure; double bx = _cairo_fixed_to_double (b->x); double by = _cairo_fixed_to_double (b->y); double cx = _cairo_fixed_to_double (c->x); double cy = _cairo_fixed_to_double (c->y); double dx = _cairo_fixed_to_double (d->x); double dy = _cairo_fixed_to_double (d->y); if (info->ctm_inverse) { cairo_matrix_transform_point (info->ctm_inverse, &bx, &by); cairo_matrix_transform_point (info->ctm_inverse, &cx, &cy); cairo_matrix_transform_point (info->ctm_inverse, &dx, &dy); } _cairo_output_stream_printf (info->output, "%f %f %f %f %f %f c ", bx, by, cx, cy, dx, dy); return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_pdf_path_close_path (void *closure){ pdf_path_info_t *info = closure; _cairo_output_stream_printf (info->output, "h\r\n"); return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_pdf_surface_intersect_clip_path (void *abstract_surface, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_antialias_t antialias){ cairo_pdf_surface_t *surface = abstract_surface; cairo_status_t status; const char *pdf_operator; pdf_path_info_t info; if (path == NULL) { if (surface->has_clip) _cairo_output_stream_printf (surface->output, "Q\r\n"); surface->has_clip = FALSE; return CAIRO_STATUS_SUCCESS; } if (!surface->has_clip) { _cairo_output_stream_printf (surface->output, "q "); surface->has_clip = TRUE; } info.output = surface->output; info.ctm_inverse = NULL; status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_pdf_path_move_to, _cairo_pdf_path_line_to, _cairo_pdf_path_curve_to, _cairo_pdf_path_close_path, &info); switch (fill_rule) { case CAIRO_FILL_RULE_WINDING: pdf_operator = "W"; break; case CAIRO_FILL_RULE_EVEN_ODD: pdf_operator = "W*"; break; default: ASSERT_NOT_REACHED; } _cairo_output_stream_printf (surface->output, "%s n\r\n", pdf_operator); return status;}static void_cairo_pdf_surface_get_font_options (void *abstract_surface, cairo_font_options_t *options){ _cairo_font_options_init_default (options); cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);}static cairo_pdf_resource_t_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface){ cairo_pdf_resource_t info; info = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Creator (cairographics.org)\r\n" " /Producer (cairographics.org)\r\n" ">>\r\n" "endobj\r\n", info.id); return info;}static void_cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface){ cairo_pdf_resource_t page, *res; cairo_pdf_font_t font; int num_pages, num_fonts, i; int num_alphas, num_resources; double alpha; _cairo_pdf_surface_update_object (surface, surface->pages_resource); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /Pages\r\n" " /Kids [ ", surface->pages_resource.id); num_pages = _cairo_array_num_elements (&surface->pages); for (i = 0; i < num_pages; i++) { _cairo_array_copy_element (&surface->pages, i, &page); _cairo_output_stream_printf (surface->output, "%d 0 R ", page.id); } _cairo_output_stream_printf (surface->output, "]\r\n"); _cairo_output_stream_printf (surface->output, " /Count %d\r\n", num_pages); _cairo_output_stream_printf (surface->output, " /Resources <<\r\n"); num_alphas = _cairo_array_num_elements (&surface->alphas); if (num_alphas > 0) { _cairo_output_stream_printf (surface->output, " /ExtGState <<\r\n"); for (i = 0; i < num_alphas; i++) { /* With some work, we could separate the stroking * or non-stroking alpha here as actually needed. */ _cairo_array_copy_element (&surface->alphas, i, &alpha); _cairo_output_stream_printf (surface->output, " /a%d << /CA %f /ca %f >>\r\n", i, alpha, alpha); } _cairo_output_stream_printf (surface->output, " >>\r\n"); } num_resources = _cairo_array_num_elements (&surface->patterns); if (num_resources > 0) { _cairo_output_stream_printf (surface->output, " /Pattern <<"); for (i = 0; i < num_resources; i++) { res = _cairo_array_index (&surface->patterns, i); _cairo_output_stream_printf (surface->output, " /res%d %d 0 R", res->id, res->id); } _cairo_output_stream_printf (surface->output, " >>\r\n"); } num_resources = _cairo_array_num_elements (&surface->xobjects); if (num_resources > 0) { _cairo_output_stream_printf (surface->output, " /XObject <<"); for (i = 0; i < num_resources; i++) { res = _cairo_array_index (&surface->xobjects, i); _cairo_output_stream_printf (surface->output, " /res%d %d 0 R", res->id, res->id); } _cairo_output_stream_printf (surface->output, " >>\r\n"); } _cairo_output_stream_printf (surface->output," /Font <<\r\n"); num_fonts = _cairo_array_num_elements (&surface->fonts); for (i = 0; i < num_fonts; i++) { _cairo_array_copy_element (&surface->fonts, i, &font); _cairo_output_stream_printf (surface->output, " /CairoFont-%d-%d %d 0 R\r\n", font.font_id, font.subset_id, font.subset_resource.id); } _cairo_output_stream_printf (surface->output, " >>\r\n"); _cairo_output_stream_printf (surface->output, " >>\r\n"); /* TODO: Figure out wich other defaults to be inherited by /Page * objects. */ _cairo_output_stream_printf (surface->output, ">>\r\n" "endobj\r\n");}static cairo_status_t_cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface, cairo_scaled_font_subset_t *font_subset){ cairo_pdf_resource_t stream, descriptor, subset_resource; cairo_status_t status; cairo_pdf_font_t font; cairo_type1_subset_t subset; unsigned long length, compressed_length; char *compressed; int i; char name[64]; snprintf (name, sizeof name, "CairoFont-%d-%d", font_subset->font_id, font_subset->subset_id); status = _cairo_type1_subset_init (&subset, name, font_subset); if (status) return status; /* We ignore the zero-trailer and set Length3 to 0. */ length = subset.header_length + subset.data_length; compressed = compress_dup (subset.data, length, &compressed_length); if (compressed == NULL) { _cairo_type1_subset_fini (&subset); return CAIRO_STATUS_NO_MEMORY; } stream = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Filter /FlateDecode\r\n" " /Length %lu\r\n" " /Length1 %lu\r\n" " /Length2 %lu\r\n" " /Length3 0\r\n" ">>\r\n" "stream\r\n", stream.id, compressed_length, subset.header_length, subset.data_length); _cairo_output_stream_write (surface->output, compressed, compressed_length); _cairo_output_stream_printf (surface->output, "\r\n" "endstream\r\n" "endobj\r\n"); free (compressed); descriptor = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /FontDescriptor\r\n" " /FontName /%s\r\n" " /Flags 4\r\n" " /FontBBox [ %ld %ld %ld %ld ]\r\n" " /ItalicAngle 0\r\n" " /Ascent %ld\r\n" " /Descent %ld\r\n" " /CapHeight 500\r\n" " /StemV 80\r\n" " /StemH 80\r\n" " /FontFile %u 0 R\r\n" ">>\r\n" "endobj\r\n", descriptor.id, subset.base_font, subset.x_min, subset.y_min, subset.x_max, subset.y_max, subset.ascent, subset.descent, stream.id); subset_resource = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /Font\r\n" " /Subtype /Type1\r\n" " /BaseFont /%s\r\n" " /FirstChar 0\r\n" " /LastChar %d\r\n" " /FontDescriptor %d 0 R\r\n" " /Widths [", subset_resource.id, subset.base_font, font_subset->num_glyphs, descriptor.id); for (i = 0; i < font_subset->num_glyphs; i++) _cairo_output_stream_printf (surface->output, " %d", subset.widths[i]); _cairo_output_stream_printf (surface->output, " ]\r\n" ">>\r\n" "endobj\r\n"); font.font_id = font_subset->font_id; font.subset_id = font_subset->subset_id; font.subset_resource = subset_resource; _cairo_array_append (&surface->fonts, &font); _cairo_type1_subset_fini (&subset); return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, cairo_scaled_font_subset_t *font_subset){ cairo_pdf_resource_t stream, descriptor, subset_resource; cairo_status_t status; cairo_pdf_font_t font; cairo_truetype_subset_t subset; unsigned long compressed_length; char *compressed; int i; status = _cairo_truetype_subset_init (&subset, font_subset); if (status) return status; compressed = compress_dup (subset.data, subset.data_length, &compressed_length); if (compressed == NULL) { _cairo_truetype_subset_fini (&subset); return CAIRO_STATUS_NO_MEMORY; } stream = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Filter /FlateDecode\r\n" " /Length %lu\r\n" " /Length1 %lu\r\n" ">>\r\n" "stream\r\n", stream.id, compressed_length, subset.data_length); _cairo_output_stream_write (surface->output, compressed, compressed_length); _cairo_output_stream_printf (surface->output, "\r\n" "endstream\r\n" "endobj\r\n"); free (compressed); descriptor = _cairo_pdf_surface_new_object (surface); _cairo_output_stream_printf (surface->output, "%d 0 obj\r\n" "<< /Type /FontDescriptor\r\n" " /FontName /7%s\r\n" " /Flags 4\r\n" " /FontBBox [ %ld %ld %ld %ld ]\r\n" " /ItalicAngle 0\r\n" " /Ascent %ld\r\n" " /Descent %ld\r\n" " /CapHeight 500\r\n" " /StemV 80\r\n" " /StemH 80\r\n" " /FontFile2 %u 0 R\r\n" ">>\r\n" "endobj\r\n", descriptor.id, subset.base_font, subset.x_min, subset.y_min, subset.x_max, subset.y_max, subset.ascent, subset.descent, stream.id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -