[hb-view] Make print to stdout work in Windows
Apparently there's no equivalent to "/dev/stdout", so write using stdio to be able to output to stdout.
This commit is contained in:
parent
36b10f58cc
commit
f7e2ef74f8
|
@ -39,6 +39,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <hb.h>
|
#include <hb.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
|
@ -215,8 +215,14 @@ struct output_options_t : option_group_t
|
||||||
output_file = NULL;
|
output_file = NULL;
|
||||||
output_format = NULL;
|
output_format = NULL;
|
||||||
|
|
||||||
|
fp = NULL;
|
||||||
|
|
||||||
add_options (parser);
|
add_options (parser);
|
||||||
}
|
}
|
||||||
|
~output_options_t (void) {
|
||||||
|
if (fp && fp != stdout)
|
||||||
|
fclose (fp);
|
||||||
|
}
|
||||||
|
|
||||||
void add_options (option_parser_t *parser);
|
void add_options (option_parser_t *parser);
|
||||||
|
|
||||||
|
@ -228,13 +234,21 @@ struct output_options_t : option_group_t
|
||||||
output_format++; /* skip the dot */
|
output_format++; /* skip the dot */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!output_file) {
|
if (output_file && 0 == strcmp (output_file, "-"))
|
||||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
output_file = NULL; /* STDOUT */
|
||||||
output_file = "CON"; /* XXX right? */
|
|
||||||
#else
|
|
||||||
output_file = "/dev/stdout";
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE *get_file_handle (void)
|
||||||
|
{
|
||||||
|
if (fp)
|
||||||
|
return fp;
|
||||||
|
|
||||||
|
fp = output_file ? fopen (output_file, "wb") : stdout;
|
||||||
|
if (!fp)
|
||||||
|
fail (FALSE, "Cannot open output file '%s': %s",
|
||||||
|
output_file, strerror (errno));
|
||||||
|
|
||||||
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void init (const font_options_t *font_opts) = 0;
|
virtual void init (const font_options_t *font_opts) = 0;
|
||||||
|
@ -243,8 +257,11 @@ struct output_options_t : option_group_t
|
||||||
unsigned int text_len) = 0;
|
unsigned int text_len) = 0;
|
||||||
virtual void finish (const font_options_t *font_opts) = 0;
|
virtual void finish (const font_options_t *font_opts) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
const char *output_file;
|
const char *output_file;
|
||||||
const char *output_format;
|
const char *output_format;
|
||||||
|
|
||||||
|
mutable FILE *fp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,14 @@
|
||||||
# define HAS_EPS 1
|
# define HAS_EPS 1
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_eps_surface_create (const char *filename,
|
_cairo_eps_surface_create_for_stream (cairo_write_func_t write_func,
|
||||||
|
void *closure,
|
||||||
double width,
|
double width,
|
||||||
double height)
|
double height)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
|
||||||
surface = cairo_ps_surface_create (filename, width, height);
|
surface = cairo_ps_surface_create_for_stream (write_func, closure, width, height);
|
||||||
cairo_ps_surface_set_eps (surface, TRUE);
|
cairo_ps_surface_set_eps (surface, TRUE);
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
|
@ -223,7 +224,8 @@ view_cairo_t::create_scaled_font (const font_options_t *font_opts)
|
||||||
struct finalize_closure_t {
|
struct finalize_closure_t {
|
||||||
void (*callback)(finalize_closure_t *);
|
void (*callback)(finalize_closure_t *);
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
const char *filename;
|
cairo_write_func_t write_func;
|
||||||
|
void *closure;
|
||||||
};
|
};
|
||||||
static cairo_user_data_key_t finalize_closure_key;
|
static cairo_user_data_key_t finalize_closure_key;
|
||||||
|
|
||||||
|
@ -233,14 +235,17 @@ static void
|
||||||
finalize_png (finalize_closure_t *closure)
|
finalize_png (finalize_closure_t *closure)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
status = cairo_surface_write_to_png (closure->surface, closure->filename);
|
status = cairo_surface_write_to_png_stream (closure->surface,
|
||||||
|
closure->write_func,
|
||||||
|
closure->closure);
|
||||||
if (status != CAIRO_STATUS_SUCCESS)
|
if (status != CAIRO_STATUS_SUCCESS)
|
||||||
fail (FALSE, "Failed to write output to `%s': %s",
|
fail (FALSE, "Failed to write output: %s",
|
||||||
closure->filename, cairo_status_to_string (status));
|
cairo_status_to_string (status));
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_png_surface_create (const char *filename,
|
_cairo_png_surface_create_for_stream (cairo_write_func_t write_func,
|
||||||
|
void *closure,
|
||||||
double width,
|
double width,
|
||||||
double height,
|
double height,
|
||||||
cairo_content_t content)
|
cairo_content_t content)
|
||||||
|
@ -266,12 +271,13 @@ _cairo_png_surface_create (const char *filename,
|
||||||
fail (FALSE, "Failed to create cairo surface: %s",
|
fail (FALSE, "Failed to create cairo surface: %s",
|
||||||
cairo_status_to_string (status));
|
cairo_status_to_string (status));
|
||||||
|
|
||||||
finalize_closure_t *closure = g_new0 (finalize_closure_t, 1);
|
finalize_closure_t *png_closure = g_new0 (finalize_closure_t, 1);
|
||||||
closure->callback = finalize_png;
|
png_closure->callback = finalize_png;
|
||||||
closure->surface = surface;
|
png_closure->surface = surface;
|
||||||
closure->filename = filename;
|
png_closure->write_func = write_func;
|
||||||
|
png_closure->closure = closure;
|
||||||
|
|
||||||
if (cairo_surface_set_user_data (surface, &finalize_closure_key, (void *) closure, (cairo_destroy_func_t) g_free))
|
if (cairo_surface_set_user_data (surface, &finalize_closure_key, (void *) png_closure, (cairo_destroy_func_t) g_free))
|
||||||
g_free ((void *) closure);
|
g_free ((void *) closure);
|
||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
|
@ -304,13 +310,33 @@ view_cairo_t::render (const font_options_t *font_opts)
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
stdio_write_func (void *closure,
|
||||||
|
const unsigned char *data,
|
||||||
|
unsigned int size)
|
||||||
|
{
|
||||||
|
FILE *fp = (FILE *) closure;
|
||||||
|
|
||||||
|
while (size) {
|
||||||
|
size_t ret = fwrite (data, 1, size, fp);
|
||||||
|
size -= ret;
|
||||||
|
data += ret;
|
||||||
|
if (size && ferror (fp))
|
||||||
|
fail (FALSE, "Failed to write output: %s", strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
cairo_t *
|
cairo_t *
|
||||||
view_cairo_t::create_context (double w, double h)
|
view_cairo_t::create_context (double w, double h)
|
||||||
{
|
{
|
||||||
cairo_surface_t *(*constructor) (const char *filename,
|
cairo_surface_t *(*constructor) (cairo_write_func_t write_func,
|
||||||
|
void *closure,
|
||||||
double width,
|
double width,
|
||||||
double height) = NULL;
|
double height) = NULL;
|
||||||
cairo_surface_t *(*constructor2) (const char *filename,
|
cairo_surface_t *(*constructor2) (cairo_write_func_t write_func,
|
||||||
|
void *closure,
|
||||||
double width,
|
double width,
|
||||||
double height,
|
double height,
|
||||||
cairo_content_t content) = NULL;
|
cairo_content_t content) = NULL;
|
||||||
|
@ -322,22 +348,22 @@ view_cairo_t::create_context (double w, double h)
|
||||||
;
|
;
|
||||||
#ifdef CAIRO_HAS_PNG_FUNCTIONS
|
#ifdef CAIRO_HAS_PNG_FUNCTIONS
|
||||||
else if (0 == strcasecmp (extension, "png"))
|
else if (0 == strcasecmp (extension, "png"))
|
||||||
constructor2 = _cairo_png_surface_create;
|
constructor2 = _cairo_png_surface_create_for_stream;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||||
else if (0 == strcasecmp (extension, "svg"))
|
else if (0 == strcasecmp (extension, "svg"))
|
||||||
constructor = cairo_svg_surface_create;
|
constructor = cairo_svg_surface_create_for_stream;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CAIRO_HAS_PDF_SURFACE
|
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||||
else if (0 == strcasecmp (extension, "pdf"))
|
else if (0 == strcasecmp (extension, "pdf"))
|
||||||
constructor = cairo_pdf_surface_create;
|
constructor = cairo_pdf_surface_create_for_stream;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CAIRO_HAS_PS_SURFACE
|
#ifdef CAIRO_HAS_PS_SURFACE
|
||||||
else if (0 == strcasecmp (extension, "ps"))
|
else if (0 == strcasecmp (extension, "ps"))
|
||||||
constructor = cairo_ps_surface_create;
|
constructor = cairo_ps_surface_create_for_stream;
|
||||||
#ifdef HAS_EPS
|
#ifdef HAS_EPS
|
||||||
else if (0 == strcasecmp (extension, "eps"))
|
else if (0 == strcasecmp (extension, "eps"))
|
||||||
constructor = _cairo_eps_surface_create;
|
constructor = _cairo_eps_surface_create_for_stream;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -357,10 +383,11 @@ view_cairo_t::create_context (double w, double h)
|
||||||
content = CAIRO_CONTENT_COLOR_ALPHA;
|
content = CAIRO_CONTENT_COLOR_ALPHA;
|
||||||
|
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
FILE *f = get_file_handle ();
|
||||||
if (constructor)
|
if (constructor)
|
||||||
surface = constructor (output_file, w, h);
|
surface = constructor (stdio_write_func, f, w, h);
|
||||||
else if (constructor2)
|
else if (constructor2)
|
||||||
surface = constructor2 (output_file, w, h, content);
|
surface = constructor2 (stdio_write_func, f, w, h, content);
|
||||||
else
|
else
|
||||||
fail (FALSE, "Unknown output format `%s'", extension);
|
fail (FALSE, "Unknown output format `%s'", extension);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue