summaryrefslogtreecommitdiff
path: root/pcl/pgvector.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcl/pgvector.c')
-rw-r--r--pcl/pgvector.c629
1 files changed, 629 insertions, 0 deletions
diff --git a/pcl/pgvector.c b/pcl/pgvector.c
new file mode 100644
index 000000000..a36163808
--- /dev/null
+++ b/pcl/pgvector.c
@@ -0,0 +1,629 @@
+/* Portions Copyright (C) 2001 artofcode LLC.
+ Portions Copyright (C) 1996, 2001 Artifex Software Inc.
+ Portions Copyright (C) 1988, 2000 Aladdin Enterprises.
+ This software is based in part on the work of the Independent JPEG Group.
+ All Rights Reserved.
+
+ This software is distributed under license and may not be copied, modified
+ or distributed except as expressly authorized under the terms of that
+ license. Refer to licensing information at http://www.artifex.com/ or
+ contact Artifex Software, Inc., 101 Lucas Valley Road #110,
+ San Rafael, CA 94903, (415)492-9861, for further information. */
+/*$Id$ */
+
+/* pgvector.c */
+/* HP-GL/2 vector commands */
+
+#include "stdio_.h" /* for gdebug.h */
+#include "gdebug.h"
+#include "pcparse.h"
+#include "pgmand.h"
+#include "pggeom.h"
+#include "pgdraw.h"
+#include "pgmisc.h"
+#include "gspath.h"
+#include "gscoord.h"
+#include "math_.h"
+
+/* ------ Internal procedures ------ */
+
+/* Draw an arc (AA, AR). */
+ static int
+hpgl_arc(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative)
+{
+ hpgl_real_t x_center, y_center, sweep, x_current, y_current, chord_angle = 5;
+ hpgl_real_t radius, start_angle;
+
+ if ( !hpgl_arg_units(pgls->memory, pargs, &x_center) ||
+ !hpgl_arg_units(pgls->memory, pargs, &y_center) ||
+ !hpgl_arg_c_real(pgls->memory, pargs, &sweep)
+ )
+ return e_Range;
+
+ hpgl_arg_c_real(pgls->memory, pargs, &chord_angle);
+
+ if ( current_units_out_of_range(x_center) ||
+ current_units_out_of_range(y_center) )
+ return 0;
+
+ x_current = pgls->g.pos.x;
+ y_current = pgls->g.pos.y;
+
+ if ( relative )
+ {
+ x_center += x_current;
+ y_center += y_current;
+ }
+
+ radius =
+ hpgl_compute_distance(x_current, y_current, x_center, y_center);
+
+ start_angle = radians_to_degrees *
+ hpgl_compute_angle(x_current - x_center, y_current - y_center);
+
+ hpgl_call(hpgl_add_arc_to_path(pgls, x_center, y_center,
+ radius, start_angle, sweep,
+ chord_angle,
+ false,
+ pgls->g.move_or_draw, true));
+
+ hpgl_call(hpgl_update_carriage_return_pos(pgls));
+ return 0;
+}
+
+/* Draw a 3-point arc (AT, RT). */
+ static int
+hpgl_arc_3_point(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative)
+{
+ hpgl_real_t x_start = pgls->g.pos.x, y_start = pgls->g.pos.y;
+ hpgl_real_t x_inter, y_inter, x_end, y_end;
+ hpgl_real_t chord_angle = 5;
+
+ if ( !hpgl_arg_units(pgls->memory, pargs, &x_inter) ||
+ !hpgl_arg_units(pgls->memory, pargs, &y_inter) ||
+ !hpgl_arg_units(pgls->memory, pargs, &x_end) ||
+ !hpgl_arg_units(pgls->memory, pargs, &y_end)
+ )
+ return e_Range;
+
+ hpgl_arg_c_real(pgls->memory, pargs, &chord_angle);
+
+ if ( relative )
+ {
+ x_inter += x_start;
+ y_inter += y_start;
+ x_end += x_start;
+ y_end += y_start;
+ }
+
+ hpgl_call(hpgl_add_arc_3point_to_path(pgls,
+ x_start, y_start,
+ x_inter, y_inter,
+ x_end, y_end, chord_angle,
+ pgls->g.move_or_draw));
+ hpgl_call(hpgl_update_carriage_return_pos(pgls));
+ return 0;
+}
+
+/* Draw a Bezier (BR, BZ). */
+int
+hpgl_bezier(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative)
+{
+ hpgl_real_t x_start, y_start;
+
+ /*
+ * Since these commands take an arbitrary number of arguments,
+ * we reset the argument bookkeeping after each group.
+ */
+
+ for ( ; ; )
+ {
+ hpgl_real_t coords[6];
+ int i;
+
+ for ( i = 0; i < 6 && hpgl_arg_units(pgls->memory, pargs, &coords[i]); ++i )
+ ;
+ switch ( i )
+ {
+ case 0: /* done */
+ hpgl_call(hpgl_update_carriage_return_pos(pgls));
+ /* draw the path */
+ if ( !pgls->g.polygon_mode ) {
+ /* apparently only round and beveled joins are
+ allowed 5 is bevel and 4 is round */
+ int save_join = pgls->g.line.join;
+ if ( pgls->g.line.join != 1 && pgls->g.line.join != 4 )
+ pgls->g.line.join = 1; /* bevel */
+ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector));
+ pgls->g.line.join = save_join;
+ }
+ return 0;
+ case 6:
+ break;
+ default:
+ hpgl_call(hpgl_update_carriage_return_pos(pgls));
+ return e_Range;
+ }
+
+ x_start = pgls->g.pos.x;
+ y_start = pgls->g.pos.y;
+
+ if ( relative )
+ hpgl_call(hpgl_add_bezier_to_path(pgls, x_start, y_start,
+ x_start + coords[0],
+ y_start + coords[1],
+ x_start + coords[2],
+ y_start + coords[3],
+ x_start + coords[4],
+ y_start + coords[5],
+ pgls->g.move_or_draw));
+ else
+ hpgl_call(hpgl_add_bezier_to_path(pgls, x_start, y_start,
+ coords[0], coords[1],
+ coords[2], coords[3],
+ coords[4], coords[5],
+ pgls->g.move_or_draw));
+ /* Prepare for the next set of points. */
+ hpgl_args_init(pargs);
+ }
+}
+
+/* Plot points, symbols, or lines (PA, PD, PR, PU). */
+int
+hpgl_plot(hpgl_args_t *pargs, hpgl_state_t *pgls, hpgl_plot_function_t func)
+{
+ /*
+ * Since these commands take an arbitrary number of arguments,
+ * we reset the argument bookkeeping after each group.
+ */
+ /* bool first_loop = true; */
+ hpgl_real_t x, y;
+ if ( hpgl_plot_is_move(func) && !pgls->g.polygon_mode ) {
+ hpgl_call(hpgl_close_path(pgls));
+ }
+ while ( hpgl_arg_units(pgls->memory, pargs, &x) &&
+ hpgl_arg_units(pgls->memory, pargs, &y) ) {
+
+ if ( current_units_out_of_range(x) ||
+ current_units_out_of_range(y) )
+ return e_Range;
+
+ /* move with arguments closes path */
+ if ( pargs->phase == 0
+ && (hpgl_plot_is_move(func) || pgls->g.subpolygon_started )) {
+ hpgl_call(hpgl_close_path(pgls));
+ }
+ pargs->phase = 1; /* we have arguments */
+ /* first point of a subpolygon is a pen up - absurd */
+ if ( pgls->g.subpolygon_started ) {
+ pgls->g.subpolygon_started = false;
+ pgls->g.have_drawn_in_path = false;
+ hpgl_call(hpgl_add_point_to_path(pgls, x, y,
+ hpgl_plot_move | pgls->g.relative_coords,
+ true));
+ }
+ else {
+ hpgl_call(hpgl_add_point_to_path(pgls, x, y, func, true));
+ if ( hpgl_plot_is_draw(func) )
+ pgls->g.have_drawn_in_path = true;
+ }
+ /* Prepare for the next set of points. */
+ if ( pgls->g.symbol_mode != 0 )
+ hpgl_call(hpgl_print_symbol_mode_char(pgls));
+ hpgl_args_init(pargs);
+ }
+
+ /* check for no argument, no polygon, absolute will add a point to path case
+ * NB stefan: need to find the test case
+ */
+ if ( !pargs->phase && hpgl_plot_is_absolute(func) && !pgls->g.polygon_mode ) {
+ gs_point cur_point;
+ hpgl_call(hpgl_get_current_position(pgls, &cur_point));
+ hpgl_call(hpgl_add_point_to_path(pgls, cur_point.x,
+ cur_point.y, func, true));
+ }
+ if ( pgls->g.symbol_mode != 0 )
+ hpgl_call(hpgl_print_symbol_mode_char(pgls));
+
+ /* don't update if no arguments */
+ if ( pargs->phase )
+ hpgl_call(hpgl_update_carriage_return_pos(pgls));
+ return 0;
+}
+
+/* ------ Commands ------ */
+ static int
+hpgl_draw_arc(hpgl_state_t *pgls)
+{
+ if ( !pgls->g.polygon_mode )
+ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector));
+ return 0;
+}
+
+/* AA xcenter,ycenter,sweep[,chord]; */
+ int
+hpgl_AA(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ hpgl_call(hpgl_arc(pargs, pgls, false));
+ hpgl_call(hpgl_draw_arc(pgls));
+ return 0;
+}
+
+/* AR xcenter,ycenter,sweep[,chord]; */
+ int
+hpgl_AR(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ hpgl_call(hpgl_arc(pargs, pgls, true));
+ hpgl_call(hpgl_draw_arc(pgls));
+ return 0;
+}
+
+/* AT xinter,yinter,xend,yend[,chord]; */
+ int
+hpgl_AT(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ hpgl_call(hpgl_arc_3_point(pargs, pgls, false));
+ hpgl_call(hpgl_draw_arc(pgls));
+ return 0;
+}
+
+/* BR x1,y1,x2,y2,x3,y3...; */
+ int
+hpgl_BR(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{ return hpgl_bezier(pargs, pgls, true);
+}
+
+/* BZ x1,y1,x2,y2,x3,y3...; */
+int
+hpgl_BZ(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{ return hpgl_bezier(pargs, pgls, false);
+}
+
+/* CI radius[,chord]; */
+int
+hpgl_CI(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ hpgl_real_t radius, chord = 5;
+ bool reset_ctm = true;
+ gs_point pos;
+
+ if ( !hpgl_arg_units(pgls->memory, pargs, &radius) )
+ return e_Range;
+
+ /* close existing path iff a draw exists in polygon path */
+ if ( pgls->g.have_drawn_in_path && pgls->g.polygon_mode )
+ hpgl_call(hpgl_close_subpolygon(pgls));
+
+ /* center; closing subpolygon can move center */
+ pos = pgls->g.pos;
+
+ hpgl_arg_c_real(pgls->memory, pargs, &chord);
+ /* draw the path here for line type 0, otherwise the first dot
+ drawn in the circumference of the circle will be oriented
+ in the same direction as the center dot */
+ if ( !pgls->g.line.current.is_solid && (pgls->g.line.current.type == 0) )
+ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector));
+
+ /* draw the arc/circle */
+ hpgl_call(hpgl_add_arc_to_path(pgls, pos.x, pos.y,
+ radius, 0.0, 360.0, chord, true,
+ hpgl_plot_draw_absolute, reset_ctm));
+ if ( !pgls->g.polygon_mode )
+ hpgl_call(hpgl_draw_arc(pgls));
+
+ /* end path, start new path by moving back to the center */
+ hpgl_call(hpgl_close_current_path(pgls));
+ hpgl_call(hpgl_add_point_to_path(pgls, pos.x, pos.y,
+ hpgl_plot_move_absolute,
+ true));
+ pgls->g.have_drawn_in_path = false; /* prevent dot draw on close */
+ hpgl_call(hpgl_set_current_position(pgls, &pos));
+
+ if ( !pgls->g.polygon_mode )
+ hpgl_call(hpgl_clear_current_path(pgls));
+
+ return 0;
+}
+
+/* PA x,y...; */
+int
+hpgl_PA(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+
+ if ( pgls->g.relative_coords != hpgl_plot_absolute ) {
+ pgls->g.relative_coords = hpgl_plot_absolute;
+ if ( !pgls->g.polygon_mode ) {
+ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector));
+ hpgl_call(hpgl_clear_current_path(pgls));
+ }
+ }
+ return hpgl_plot(pargs, pgls,
+ pgls->g.move_or_draw | hpgl_plot_absolute);
+}
+
+/* PD (d)x,(d)y...; */
+int
+hpgl_PD(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ pgls->g.move_or_draw = hpgl_plot_draw;
+ return hpgl_plot(pargs, pgls,
+ hpgl_plot_draw | pgls->g.relative_coords);
+}
+
+/* PE (flag|value|coord)*; */
+/*
+ * We record the state of the command in the 'phase' as follows:
+ */
+enum {
+ pe_pen_up = 1, /* next coordinate are pen-up move */
+ pe_absolute = 2, /* next coordinates are absolute */
+ pe_7bit = 4, /* use 7-bit encoding */
+ pe_entered = 8 /* we have entered PE once */
+};
+
+/* convert pe fixed to float accounting for fractional bits */
+static inline floatp
+pe_fixed2float(int32 x, int32 fbits)
+{
+ return ((floatp)x * (1.0 / pow(2, fbits)));
+}
+
+static bool pe_args(const gs_memory_t *mem, hpgl_args_t *, int32 *, int);
+int
+hpgl_PE(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ /*
+ * To simplify the control structure here, we require that
+ * the input buffer be large enough to hold 2 coordinates
+ * in the base 32 encoding, i.e., 14 bytes. We're counting on
+ * there not being any whitespace within coordinate values....
+ */
+ const byte *p = pargs->source.ptr;
+ const byte *rlimit = pargs->source.limit;
+ /* count points to allow medium size paths, performance optimization
+ * point_count_max should be smaller than input buffer
+ */
+ int point_count = 0;
+ static const int point_count_max = 100;
+
+ if ( pargs->phase == 0 ) {
+ /* After PE is executed, the previous plotting mode (absolute or
+ relative) is restored. If the finnal move is made with the pen up,
+ the pen remains in the up position; otherwise the pen is left in
+ the down position. At least HP documented this bug. */
+ hpgl_save_pen_state(pgls, &pgls->g.pen_state, hpgl_pen_relative);
+ pargs->phase |= pe_entered;
+ pgls->g.fraction_bits = 0;
+ }
+ while ( p < rlimit ) {
+ byte ch = *(pargs->source.ptr = ++p);
+ switch ( ch & 127 /* per spec */ ) {
+ case ';':
+ hpgl_call(hpgl_update_carriage_return_pos(pgls));
+ if ( pargs->phase & pe_entered )
+ hpgl_restore_pen_state(pgls, &pgls->g.pen_state, hpgl_pen_relative);
+ /* prevent paths from getting excessively large */
+ if ( !pgls->g.polygon_mode )
+ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector));
+ return 0;
+ case ':':
+ if_debug0('I', "\n PE SP");
+ {
+ int32 pen;
+ if ( !pe_args(pgls->memory, pargs, &pen, 1) )
+ {
+ pargs->source.ptr = p - 1;
+ break;
+ }
+ if ( !pgls->g.polygon_mode ) {
+ hpgl_args_t args;
+ hpgl_args_set_int(&args, pen);
+ /* Note SP is illegal in polygon mode we must handle that here */
+ hpgl_call(hpgl_SP(&args, pgls));
+ }
+ }
+ p = pargs->source.ptr;
+ continue;
+ case '<':
+ if_debug0('I', "\n PE PU");
+ pargs->phase |= pe_pen_up;
+ continue;
+ case '>':
+ if_debug0('I', "\n PE PD");
+ {
+ int32 fbits;
+ if ( !pe_args(pgls->memory, pargs, &fbits, 1) )
+ {
+ pargs->source.ptr = p - 1;
+ break;
+ }
+ if ( fbits < -26 || fbits > 26 )
+ return e_Range;
+ pgls->g.fraction_bits = fbits;
+ }
+ p = pargs->source.ptr;
+ continue;
+ case '=':
+ if_debug0('I', " PE ABS");
+ pargs->phase |= pe_absolute;
+ continue;
+ case '7':
+ if_debug0('I', "\n PE 7bit");
+ pargs->phase |= pe_7bit;
+ continue;
+ case ESC:
+ /*
+ * This is something of a hack. Apparently we're supposed
+ * to parse all PCL commands embedded in the GL/2 stream,
+ * and simply ignore everything except the 3 that end GL/2
+ * mode. Instead, we simply stop parsing PE arguments as
+ * soon as we see an ESC.
+ */
+ if ( ch == ESC ) /* (might be ESC+128) */ {
+ pargs->source.ptr = p - 1; /* rescan ESC */
+ if ( pargs->phase & pe_entered ) {
+ hpgl_restore_pen_state(pgls, &pgls->g.pen_state, hpgl_pen_relative);
+ }
+ hpgl_call(hpgl_update_carriage_return_pos(pgls));
+ return 0;
+ }
+ /* falls through */
+ default:
+ if ( (ch & 127) <= 32 || (ch & 127) == 127 )
+ continue;
+ pargs->source.ptr = p - 1;
+ {
+ int32 xy[2];
+ hpgl_args_t args;
+ int32 fbits = pgls->g.fraction_bits;
+ if ( !pe_args(pgls->memory, pargs, xy, 2) )
+ break;
+ if ( pargs->phase & pe_absolute )
+ pgls->g.relative_coords = hpgl_plot_absolute;
+ else
+ pgls->g.relative_coords = hpgl_plot_relative;
+ hpgl_args_set_real2(&args, pe_fixed2float(xy[0], fbits),
+ pe_fixed2float(xy[1], fbits));
+ if ( pargs->phase & pe_pen_up ) {
+ /* prevent paths from getting excessively large */
+ if ( !pgls->g.polygon_mode && point_count > point_count_max ) {
+ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector));
+ point_count = 0;
+ }
+ hpgl_PU(&args, pgls);
+ }
+ else
+ hpgl_PD(&args, pgls);
+ point_count++;
+ }
+ pargs->phase &= ~(pe_pen_up | pe_absolute);
+ p = pargs->source.ptr;
+ continue;
+ }
+ break;
+ }
+ return e_NeedData;
+}
+/* Get an encoded value from the input. Return false if we ran out of */
+/* input data. Ignore syntax errors (!). */
+static bool
+pe_args(const gs_memory_t *mem, hpgl_args_t *pargs, int32 *pvalues, int count)
+{ const byte *p = pargs->source.ptr;
+ const byte *rlimit = pargs->source.limit;
+ int i, code;
+
+ for ( i = 0; i < count; ++i )
+ { int32 value = 0;
+ int shift = 0;
+
+ for ( ; ; )
+ { int ch;
+
+ if ( p >= rlimit )
+ return false;
+ ch = *++p;
+ if ( (ch & 127) <= 32 || (ch & 127) == 127 )
+ continue;
+ if ( pargs->phase & pe_7bit )
+ { ch -= 63;
+ if ( ch & ~63 )
+ goto syntax_error;
+ value += (int32)(ch & 31) << shift;
+ shift += 5;
+ if ( ch & 32 )
+ break;
+ }
+ else
+ { ch -= 63;
+ if ( ch & ~191 )
+ goto syntax_error;
+ value += (int32)(ch & 63) << shift;
+ shift += 6;
+ if ( ch & 128 )
+ break;
+ }
+ }
+ pvalues[i] = (value & 1 ? -(value >> 1) : value >> 1);
+ if_debug1('I', " [%ld]", (long)pvalues[i] );
+ }
+ pargs->source.ptr = p;
+ return true;
+syntax_error:
+ /* Just ignore everything we've parsed up to this point. */
+ pargs->source.ptr = p;
+ code = gs_note_error(e_Syntax);
+ return false;
+}
+
+/* PR dx,dy...; */
+int
+hpgl_PR(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ if ( pgls->g.relative_coords != hpgl_plot_relative ) {
+ pgls->g.relative_coords = hpgl_plot_relative;
+ if ( !pgls->g.polygon_mode ) {
+ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector));
+ hpgl_call(hpgl_clear_current_path(pgls));
+ }
+ }
+ return hpgl_plot(pargs, pgls,
+ pgls->g.move_or_draw | hpgl_plot_relative);
+}
+
+/* PU (d)x,(d)y...; */
+int
+hpgl_PU(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ pgls->g.move_or_draw = hpgl_plot_move;
+ return hpgl_plot(pargs, pgls,
+ hpgl_plot_move | pgls->g.relative_coords);
+}
+
+/* RT xinter,yinter,xend,yend[,chord]; */
+int
+hpgl_RT(hpgl_args_t *pargs, hpgl_state_t *pgls)
+{
+ hpgl_call(hpgl_arc_3_point(pargs, pgls, true));
+ hpgl_call(hpgl_draw_arc(pgls));
+ return 0;
+}
+
+/* Initialization */
+static int
+pgvector_do_registration(
+ pcl_parser_state_t *pcl_parser_state,
+ gs_memory_t *mem
+)
+{
+ /* Register commands */
+ DEFINE_HPGL_COMMANDS(mem)
+ HPGL_COMMAND('A', 'A',
+ hpgl_AA, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both),
+ HPGL_COMMAND('A', 'R',
+ hpgl_AR, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both),
+ HPGL_COMMAND('A', 'T',
+ hpgl_AT, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both),
+ HPGL_COMMAND('B', 'R',
+ hpgl_BR, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */
+ HPGL_COMMAND('B', 'Z',
+ hpgl_BZ, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */
+ HPGL_COMMAND('C', 'I',
+ hpgl_CI, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both),
+ HPGL_COMMAND('P', 'A',
+ hpgl_PA, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */
+ HPGL_COMMAND('P', 'D',
+ hpgl_PD, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */
+ HPGL_COMMAND('P', 'E',
+ hpgl_PE, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both),
+ HPGL_COMMAND('P', 'R',
+ hpgl_PR, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */
+ HPGL_COMMAND('P', 'U',
+ hpgl_PU, hpgl_cdf_polygon|hpgl_cdf_pcl_rtl_both), /* argument pattern can repeat */
+ HPGL_COMMAND('R', 'T',
+ hpgl_RT, hpgl_cdf_polygon|hpgl_cdf_lost_mode_cleared|hpgl_cdf_pcl_rtl_both),
+ END_HPGL_COMMANDS
+ return 0;
+}
+const pcl_init_t pgvector_init = {
+ pgvector_do_registration, 0
+};