mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-15 06:50:31 +01:00
Add OpenType/CFF Subsetting
This commit is contained in:
parent
e4c3da8080
commit
bd0f991908
5 changed files with 1601 additions and 0 deletions
|
|
@ -1,4 +1,5 @@
|
|||
font_subset_sources = \
|
||||
cairo-cff-subset.c \
|
||||
cairo-truetype-subset.c \
|
||||
cairo-type1-fallback.c \
|
||||
cairo-truetype-subset-private.h \
|
||||
|
|
|
|||
1452
src/cairo-cff-subset.c
Normal file
1452
src/cairo-cff-subset.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1579,6 +1579,109 @@ _cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
|
|||
"endobj\r\n");
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_cff_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_cff_subset_t subset;
|
||||
unsigned long compressed_length;
|
||||
char *compressed;
|
||||
unsigned int i;
|
||||
char name[64];
|
||||
|
||||
snprintf (name, sizeof name, "CairoFont-%d-%d",
|
||||
font_subset->font_id, font_subset->subset_id);
|
||||
status = _cairo_cff_subset_init (&subset, name, font_subset);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
compressed = compress_dup (subset.data, subset.data_length, &compressed_length);
|
||||
if (compressed == NULL) {
|
||||
_cairo_cff_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"
|
||||
" /Subtype /Type1C\r\n"
|
||||
">>\r\n"
|
||||
"stream\r\n",
|
||||
stream.id,
|
||||
compressed_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"
|
||||
" /FontFile3 %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_cff_subset_fini (&subset);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset,
|
||||
|
|
@ -2059,6 +2162,10 @@ _cairo_pdf_surface_emit_font_subset (cairo_scaled_font_subset_t *font_subset,
|
|||
cairo_pdf_surface_t *surface = closure;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return;
|
||||
|
||||
#if CAIRO_HAS_FT_FONT
|
||||
status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
|
|
|
|||
|
|
@ -179,6 +179,46 @@ _cairo_scaled_font_subsets_foreach (cairo_scaled_font_subsets_t *font_subsets,
|
|||
cairo_scaled_font_subset_callback_func_t font_subset_callback,
|
||||
void *closure);
|
||||
|
||||
typedef struct _cairo_cff_subset {
|
||||
char *base_font;
|
||||
int *widths;
|
||||
long x_min, y_min, x_max, y_max;
|
||||
long ascent, descent;
|
||||
char *data;
|
||||
unsigned long data_length;
|
||||
} cairo_cff_subset_t;
|
||||
|
||||
/**
|
||||
* _cairo_cff_subset_init:
|
||||
* @cff_subset: a #cairo_cff_subset_t to initialize
|
||||
* @font_subset: the #cairo_scaled_font_subset_t to initialize from
|
||||
*
|
||||
* If possible (depending on the format of the underlying
|
||||
* cairo_scaled_font_t and the font backend in use) generate a
|
||||
* cff file corresponding to @font_subset and initialize
|
||||
* @cff_subset with information about the subset and the cff
|
||||
* data.
|
||||
*
|
||||
* Return value: CAIRO_STATUS_SUCCESS if successful,
|
||||
* CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a
|
||||
* cff file, or an non-zero value indicating an error. Possible
|
||||
* errors include CAIRO_STATUS_NO_MEMORY.
|
||||
**/
|
||||
cairo_private cairo_status_t
|
||||
_cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
|
||||
const char *name,
|
||||
cairo_scaled_font_subset_t *font_subset);
|
||||
|
||||
/**
|
||||
* _cairo_cff_subset_fini:
|
||||
* @cff_subset: a #cairo_cff_subset_t
|
||||
*
|
||||
* Free all resources associated with @cff_subset. After this
|
||||
* call, @cff_subset should not be used again without a
|
||||
* subsequent call to _cairo_cff_subset_init() again first.
|
||||
**/
|
||||
cairo_private void
|
||||
_cairo_cff_subset_fini (cairo_cff_subset_t *cff_subset);
|
||||
|
||||
typedef struct _cairo_truetype_subset {
|
||||
char *base_font;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
*/
|
||||
|
||||
#define MAKE_TT_TAG(a, b, c, d) (a<<24 | b<<16 | c<<8 | d)
|
||||
#define TT_TAG_CFF MAKE_TT_TAG('C','F','F',' ')
|
||||
#define TT_TAG_cmap MAKE_TT_TAG('c','m','a','p')
|
||||
#define TT_TAG_cvt MAKE_TT_TAG('c','v','t',' ')
|
||||
#define TT_TAG_fpgm MAKE_TT_TAG('f','p','g','m')
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue