summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pcl/news-pcl23
-rw-r--r--pcl/pcl.mak4
-rw-r--r--pcl/pconf5.h34
-rw-r--r--pcl/pconfig.h34
-rw-r--r--pcl/pgdraw.c110
-rw-r--r--pcl/pggeom.c18
-rw-r--r--pcl/pggeom.h7
-rw-r--r--pcl/pglabel.c11
-rw-r--r--pcl/pglfill.c35
-rw-r--r--pcl/pgstate.h17
-rw-r--r--pcl/pgvector.c112
11 files changed, 304 insertions, 101 deletions
diff --git a/pcl/news-pcl b/pcl/news-pcl
index d15763c5e..4fd3f46ea 100644
--- a/pcl/news-pcl
+++ b/pcl/news-pcl
@@ -6,10 +6,11 @@
This file, NEWS-PCL, describes the changes in the most recent releases of
Aladdin's PCL5 code, in reverse chronological order.
-Version 0.23 (4/16/97)
-======================
+Version 0.24 (5/7/97)
+=====================
-More bug fixes. Labels now appear in the correct place.
+More bug fixes. This is an intermediate fileset to synchronize LPD's and
+HAS's changes.
Known problems (PCL):
- The width of Intellifont characters is wrong. (CET 14_01)
@@ -27,6 +28,22 @@ Unimplemented features (PCL):
- Text clipping at the right margin.
- User-defined line type (99).
+(LPD) Fixes bugs:
+ - The makefile rule for pcl5.dev had a typo (PCLOJB for PCLOBJ).
+(pcl.mak)
+
+(LPD) Makes stick font characters always use round caps and joins, for
+visual consistency. (pgdraw.h, pgdraw.c, pglabel.c)
+
+(HAS) Numerous fixes to graphics -- changes will be included in the log for
+the next fileset. (pggeom.h, pgstate.h, pggeom.c, pgdraw.c, pglfill.c,
+pgvector.c)
+
+Version 0.23 (4/16/97)
+======================
+
+More bug fixes. Labels now appear in the correct place.
+
(LPD) Splits off functionality from two existing files:
- pcfont.c => pcfsel.h, pcfsel.c (font selection machinery used by
both PCL and HP-GL/2)
diff --git a/pcl/pcl.mak b/pcl/pcl.mak
index 02fb0adf3..a12821612 100644
--- a/pcl/pcl.mak
+++ b/pcl/pcl.mak
@@ -303,7 +303,7 @@ PCL5_OPS=$(PCL5_OPS1) $(PCL5_OPS2) $(PCL5_OPS3) $(PCL5_OPS4)
# Note: we have to initialize the cursor after initializing the logical
# page dimensions, so we do it last. This is a hack.
$(PCLOBJ)pcl5.dev: $(PCL_MAK) $(ECHOGS_XE) $(PCL_COMMON) $(PCL5_OPS) $(PCLOBJ)pcl5base.dev $(PCLOBJ)rtlbase.dev
- $(SETMOD) $(PCLOJB)pcl5 $(PCL_COMMON)
+ $(SETMOD) $(PCLOBJ)pcl5 $(PCL_COMMON)
$(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS1)
$(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS2)
$(ADDMOD) $(PCLOBJ)pcl5 $(PCL5_OPS3)
@@ -356,7 +356,7 @@ $(PCLOBJ)pcl5c.dev: $(PCL_MAK) $(ECHOGS_XE) $(PCL5C_OPS) $(PCLOBJ)pcl5.dev $(PCL
pgdraw_h=$(PCLSRC)pgdraw.h
pgfont_h=$(PCLSRC)pgfont.h $(stdpre_h) $(gstypes_h)
-pggeom_h=$(PCLSRC)pggeom.h $(math__h)
+pggeom_h=$(PCLSRC)pggeom.h $(math__h) $(gstypes_h)
pginit_h=$(PCLSRC)pginit.h
pgmisc_h=$(PCLSRC)pgmisc.h
diff --git a/pcl/pconf5.h b/pcl/pconf5.h
new file mode 100644
index 000000000..f8defd73a
--- /dev/null
+++ b/pcl/pconf5.h
@@ -0,0 +1,34 @@
+/* This file was generated automatically by genconf.c. */
+#ifdef init_
+init_(pcparse_init)
+init_(rtmisc_init)
+init_(rtcursor_init)
+init_(rtraster_init)
+init_(pcjob_init)
+init_(pcpage_init)
+init_(pcdraw_init)
+init_(pcfont_init)
+init_(pcsymbol_init)
+init_(pcsfont_init)
+init_(pcmacros_init)
+init_(pcprint_init)
+init_(pcrect_init)
+init_(rtraster_pcl_init)
+init_(pcstatus_init)
+init_(pcmisc_init)
+init_(pcursor_init)
+init_(rtcolor_init)
+init_(rtcrastr_init)
+init_(pccpalet_init)
+init_(pccrendr_init)
+init_(pccprint_init)
+init_(rtcrastr_pcl_init)
+init_(pginit_init)
+init_(pgframe_init)
+init_(pgconfig_init)
+init_(pgvector_init)
+init_(pgpoly_init)
+init_(pglfill_init)
+init_(pgchar_init)
+init_(pglabel_init)
+#endif
diff --git a/pcl/pconfig.h b/pcl/pconfig.h
new file mode 100644
index 000000000..f8defd73a
--- /dev/null
+++ b/pcl/pconfig.h
@@ -0,0 +1,34 @@
+/* This file was generated automatically by genconf.c. */
+#ifdef init_
+init_(pcparse_init)
+init_(rtmisc_init)
+init_(rtcursor_init)
+init_(rtraster_init)
+init_(pcjob_init)
+init_(pcpage_init)
+init_(pcdraw_init)
+init_(pcfont_init)
+init_(pcsymbol_init)
+init_(pcsfont_init)
+init_(pcmacros_init)
+init_(pcprint_init)
+init_(pcrect_init)
+init_(rtraster_pcl_init)
+init_(pcstatus_init)
+init_(pcmisc_init)
+init_(pcursor_init)
+init_(rtcolor_init)
+init_(rtcrastr_init)
+init_(pccpalet_init)
+init_(pccrendr_init)
+init_(pccprint_init)
+init_(rtcrastr_pcl_init)
+init_(pginit_init)
+init_(pgframe_init)
+init_(pgconfig_init)
+init_(pgvector_init)
+init_(pgpoly_init)
+init_(pglfill_init)
+init_(pgchar_init)
+init_(pglabel_init)
+#endif
diff --git a/pcl/pgdraw.c b/pcl/pgdraw.c
index ad837b4de..a000434a2 100644
--- a/pcl/pgdraw.c
+++ b/pcl/pgdraw.c
@@ -31,7 +31,7 @@
Potential performance issue. The design choice is based solely on
ease of implementation. */
-private int
+ private int
hpgl_set_graphics_dash_state(hpgl_state_t *pgls)
{
bool adaptive = ( pgls->g.line.type < 0 );
@@ -85,7 +85,7 @@ hpgl_set_graphics_dash_state(hpgl_state_t *pgls)
}
/* set up joins, caps, miter limit, and line width */
-private int
+ private int
hpgl_set_graphics_line_attribute_state(hpgl_state_t *pgls,
hpgl_rendering_mode_t render_mode)
{
@@ -144,7 +144,7 @@ vector: hpgl_call(gs_setlinejoin(pgls->pgs,
}
/* set up an hpgl clipping region wrt last IW command */
-private int
+ private int
hpgl_set_clipping_region(hpgl_state_t *pgls)
{
gs_fixed_rect fixed_box;
@@ -168,7 +168,7 @@ hpgl_set_clipping_region(hpgl_state_t *pgls)
return 0;
}
-private int
+ private int
hpgl_set_plu_to_device_ctm(hpgl_state_t *pgls)
{
pcl_set_ctm(pgls, false);
@@ -230,7 +230,7 @@ hpgl_set_plu_to_device_ctm(hpgl_state_t *pgls)
return 0;
}
-private int
+ private int
hpgl_set_label_to_plu_ctm(hpgl_state_t *pgls)
{
/* if we are not in character mode do nothing -- identity
@@ -240,9 +240,7 @@ hpgl_set_label_to_plu_ctm(hpgl_state_t *pgls)
&pgls->g.font_selection[pgls->g.font_selected];
hpgl_real_t height_points = pfs->params.height_4ths / 4.0;
hpgl_real_t width_points = 1.0 / (pfs->params.pitch_100ths / 100.0);
- /* HAS -- Only LO1 is currently supported -- need to add others */
hpgl_call(gs_translate(pgls->pgs, pgls->g.pos.x, pgls->g.pos.y));
- /* HAS -- only support standard font */
hpgl_call(gs_scale(pgls->pgs,
points_2_plu(height_points),
inches_2_plu(width_points)));
@@ -250,31 +248,32 @@ hpgl_set_label_to_plu_ctm(hpgl_state_t *pgls)
}
-private int
+ private int
hpgl_set_user_units_to_plu_ctm(hpgl_state_t *pgls)
{
- hpgl_call(gs_translate(pgls->pgs, pgls->g.P1.x, -pgls->g.P1.y));
+ hpgl_call(gs_translate(pgls->pgs, pgls->g.P1.x, pgls->g.P1.y));
/* finally scale to user units. HAS this only handles the
simple scaling scale for the moment. */
- if ( pgls->g.scaling_type == hpgl_scaling_anisotropic )
- {
+ /* if ( pgls->g.scaling_type == hpgl_scaling_anisotropic ) */
+ if ( pgls->g.scaling_type != hpgl_scaling_none )
+ {
floatp scale_x = (pgls->g.P2.x - pgls->g.P1.x) /
(pgls->g.scaling_params.pmax.x - pgls->g.scaling_params.pmin.x);
floatp scale_y = (pgls->g.P2.y - pgls->g.P1.y) /
(pgls->g.scaling_params.pmax.y - pgls->g.scaling_params.pmin.y);
hpgl_call(gs_scale(pgls->pgs, scale_x, scale_y));
}
- else if ( pgls->g.scaling_type != hpgl_scaling_none )
- dprintf1("unsuported scaling type %d:\n", pgls->g.scaling_type);
+ /* else if ( pgls->g.scaling_type != hpgl_scaling_none ) */
+ /* dprintf1("unsuported scaling type %d:\n", pgls->g.scaling_type); */
return 0;
}
/* set up ctm's. Uses the current render mode to figure out which ctm
is appropriate */
-private int
+ private int
hpgl_set_ctm(hpgl_state_t *pgls)
{
/* convert pcl->device to plu->device */
@@ -291,30 +290,50 @@ hpgl_set_ctm(hpgl_state_t *pgls)
}
/* maps current hpgl fill type to pcl pattern type. */
-private pcl_pattern_type_t
-hpgl_map_fill_type(hpgl_state_t *pgls)
+ private pcl_pattern_type_t
+hpgl_map_fill_type(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)
{
- switch (pgls->g.fill.type)
+
+ if ( render_mode == hpgl_rm_character )
{
- case hpgl_fill_solid : return pcpt_solid_black;
- case hpgl_fill_solid2 : return pcpt_solid_black;
- case hpgl_fill_pcl_crosshatch : return pcpt_cross_hatch;
- case hpgl_fill_shaded : return pcpt_shading;
- case hpgl_fill_pcl_user_defined :
- dprintf("No key mapping support falling back to solid\n");
- break;
- default :
- dprintf1("Unsupported fill type %d falling back to solid\n",
- pgls->g.fill.type);
+ switch (pgls->g.character.fill_mode)
+ {
+ case 0 : ; return pcpt_solid_black;
+ case 1 : ; /* HAS NOT IMPLEMENTED */
+ case 2 : ; /* HAS NOT IMPLEMENTED */
+ case 3 : ; /* HAS NOT IMPLEMENTED */
+ dprintf1("Character fill mode %d not supported falling back to solid\n",
+ pgls->g.character.fill_mode);
+ break;
+ default :
+ dprintf1("Unknown character fill mode falling back to solid%d\n",
+ pgls->g.character.fill_mode);
+ break;
+ }
+ }
+ else
+ {
+ switch (pgls->g.fill.type)
+ {
+ case hpgl_fill_solid : return pcpt_solid_black;
+ case hpgl_fill_solid2 : return pcpt_solid_black;
+ case hpgl_fill_pcl_crosshatch : return pcpt_cross_hatch;
+ case hpgl_fill_shaded : return pcpt_shading;
+ case hpgl_fill_pcl_user_defined :
+ dprintf("No key mapping support falling back to solid\n");
+ break;
+ default :
+ dprintf1("Unsupported fill type %d falling back to solid\n",
+ pgls->g.fill.type);
+ }
}
-
return pcpt_solid_black;
}
/* HAS I don't much care for the idea of overloading pcl_id with
shading and hatching information, but that appears to be the way
pcl_set_drawing_color() is set up. */
-private pcl_id_t *
+ private pcl_id_t *
hpgl_map_id_type(hpgl_state_t *pgls, pcl_id_t *id)
{
switch (pgls->g.fill.type)
@@ -341,13 +360,13 @@ hpgl_map_id_type(hpgl_state_t *pgls, pcl_id_t *id)
return id;
}
-private int
-hpgl_set_drawing_color(hpgl_state_t *pgls)
+ private int
+hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)
{
pcl_id_t pcl_id;
hpgl_call(pcl_set_drawing_color(pgls,
- hpgl_map_fill_type(pgls),
+ hpgl_map_fill_type(pgls, render_mode),
hpgl_map_id_type(pgls, &pcl_id)));
return 0;
}
@@ -368,7 +387,7 @@ hpgl_set_graphics_state(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)
hpgl_call(hpgl_set_graphics_line_attribute_state(pgls, render_mode));
/* set up the hpgl fills. */
- hpgl_call(hpgl_set_drawing_color(pgls));
+ hpgl_call(hpgl_set_drawing_color(pgls, render_mode));
/* set up a clipping region */
hpgl_call(hpgl_set_clipping_region(pgls));
@@ -376,7 +395,7 @@ hpgl_set_graphics_state(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)
return 0;
}
-int
+ int
hpgl_get_current_position(hpgl_state_t *pgls, gs_point *pt)
{
@@ -384,7 +403,7 @@ hpgl_get_current_position(hpgl_state_t *pgls, gs_point *pt)
return 0;
}
-int
+ int
hpgl_set_current_position(hpgl_state_t *pgls, gs_point *pt)
{
if ( pgls->g.relative )
@@ -424,7 +443,7 @@ hpgl_start_path(hpgl_state_t *pgls, gs_point pt)
return 0;
}
-int
+ int
hpgl_add_point_to_path(hpgl_state_t *pgls, floatp x, floatp y,
int (*gs_func)(gs_state *pgs, floatp x, floatp y))
{
@@ -451,7 +470,7 @@ hpgl_add_point_to_path(hpgl_state_t *pgls, floatp x, floatp y,
/* destroys the current path. HAS probably don't need to create a new
one also. */
-int
+ int
hpgl_clear_current_path(hpgl_state_t *pgls)
{
/* if a current path exists set the current state position */
@@ -461,7 +480,7 @@ hpgl_clear_current_path(hpgl_state_t *pgls)
}
/* closes the current path, making the first point and last point coincident */
-int
+ int
hpgl_close_current_path(hpgl_state_t *pgls)
{
hpgl_call(gs_closepath(pgls->pgs));
@@ -469,7 +488,7 @@ hpgl_close_current_path(hpgl_state_t *pgls)
}
/* converts pcl coordinate to device space and back to hpgl space */
-int
+ int
hpgl_add_pcl_point_to_path(hpgl_state_t *pgls, gs_point *pcl_pt)
{
gs_point dev_pt, hpgl_pt;
@@ -481,7 +500,8 @@ hpgl_add_pcl_point_to_path(hpgl_state_t *pgls, gs_point *pcl_pt)
hpgl_call(hpgl_add_point_to_path(pgls, hpgl_pt.x, hpgl_pt.y, gs_moveto));
return 0;
}
-int
+
+ int
hpgl_add_arc_to_path(hpgl_state_t *pgls, floatp center_x, floatp center_y,
floatp radius, floatp start_angle, floatp sweep_angle,
floatp chord_angle)
@@ -520,7 +540,7 @@ hpgl_add_arc_to_path(hpgl_state_t *pgls, floatp center_x, floatp center_y,
return 0;
}
-int
+ int
hpgl_add_bezier_to_path(hpgl_state_t *pgls, floatp x1, floatp y1,
floatp x2, floatp y2, floatp x3, floatp y3,
floatp x4, floatp y4)
@@ -540,7 +560,7 @@ hpgl_add_bezier_to_path(hpgl_state_t *pgls, floatp x1, floatp y1,
/* an implicit gl/2 style closepath. If the first and last point are
the same the path gets closed */
-private int
+ private int
hpgl_close_path(hpgl_state_t *pgls)
{
gs_point last_point;
@@ -559,7 +579,7 @@ hpgl_close_path(hpgl_state_t *pgls)
extraneous PU's do not result in separate subpaths. */
/* Stroke the current path */
-int
+ int
hpgl_draw_current_path(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)
{
if ( !pgls->g.have_first_moveto ) return 0;
@@ -584,7 +604,7 @@ hpgl_draw_current_path(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)
return 0;
}
-int
+ int
hpgl_draw_line(hpgl_state_t *pgls, floatp x1, floatp y1, floatp x2, floatp y2)
{
hpgl_call(hpgl_add_point_to_path(pgls, x1, y1,
@@ -597,7 +617,7 @@ hpgl_draw_line(hpgl_state_t *pgls, floatp x1, floatp y1, floatp x2, floatp y2)
return 0;
}
-int
+ int
hpgl_draw_dot(hpgl_state_t *pgls, floatp x1, floatp y1)
{
hpgl_call(hpgl_add_point_to_path(pgls, x1, y1,
diff --git a/pcl/pggeom.c b/pcl/pggeom.c
index 584304a35..fb37b47d9 100644
--- a/pcl/pggeom.c
+++ b/pcl/pggeom.c
@@ -97,7 +97,7 @@ hpgl_compute_arc_center(floatp x1, floatp y1, floatp x2, floatp y2,
* y = (a*f - c*d) / denom
*/
denom = dx3 * dy2 - dx2 * dy3;
- if ( denom < 1.0e-6 )
+ if ( fabs(denom) < 1.0e-6 )
return -1; /* degenerate */
t2 = ((px3 - px2) * (-dy3) - (-dx3) * (py3 - py2)) / denom;
@@ -136,3 +136,19 @@ hpgl_compute_vector_endpoints(floatp magnitude, floatp x, floatp y,
angle_degrees * (M_PI/180.0),
endx, endy);
}
+
+ int
+hpgl_compute_dot_product(gs_point *pt1, gs_point *pt2, floatp *result)
+{
+ *result = ((pt1->x * pt2->x) + (pt1->y * pt2->y));
+ return 0;
+}
+
+/* scales a 2d vector */
+ int
+hpgl_scale_vector(gs_point *pt1, floatp scale, gs_point *result)
+{
+ result->x = scale * pt1->x;
+ result->y = scale * pt1->y;
+ return 0;
+}
diff --git a/pcl/pggeom.h b/pcl/pggeom.h
index 3686ad088..b565f1a5a 100644
--- a/pcl/pggeom.h
+++ b/pcl/pggeom.h
@@ -9,6 +9,7 @@
# define pggeom_INCLUDED
#include "math_.h"
+#include "gstypes.h" /* for gs_point */
/* ------ Useful conversions ------ */
@@ -61,6 +62,12 @@ int hpgl_compute_vector_endpoints(P6(floatp magnitude, floatp x, floatp y,
floatp angle_degrees, floatp *endx,
floatp *endy));
+/* calculates the dot product of 2 2d vectors */
+int hpgl_compute_dot_product(P3(gs_point *pt1, gs_point *pt2, floatp *result));
+
+/* scales a 2d vector */
+int hpgl_scale_vector(P3(gs_point *pt1, floatp scale, gs_point *result));
+
/* ------ 3-point arcs ------ */
/* points are equal. HAS -- TEST for epsilon */
diff --git a/pcl/pglabel.c b/pcl/pglabel.c
index 8ac7b45e7..330ddd146 100644
--- a/pcl/pglabel.c
+++ b/pcl/pglabel.c
@@ -15,6 +15,7 @@
#include "pggeom.h"
#include "pgmisc.h"
#include "pcfsel.h"
+#include "gsline.h"
/* Define a bogus pl_font_t for the stick font. */
/* Eventually this will be a real one.... */
@@ -270,6 +271,10 @@ hpgl_print_char(hpgl_state_t *pgls, hpgl_character_point *character)
pgls->g.current_render_mode = hpgl_rm_character;
hpgl_call(hpgl_set_graphics_state(pgls, hpgl_rm_character));
+ /* Always use round caps and joins. */
+ gs_setlinecap(pgls->pgs, gs_cap_round);
+ gs_setlinejoin(pgls->pgs, gs_join_round);
+
/* all character data is absolute */
pgls->g.relative = false;
while (character->operation != hpgl_char_end)
@@ -513,10 +518,12 @@ shift: hpgl_call(hpgl_recompute_font(pgls));
do_CR = true;
break;
case FF :
- /****** WHAT TO DO? ******/
+ /* does nothing */
+ spaces = 0, lines = 0;
break;
case HT :
- /****** WHAT TO DO? ******/
+ /* appears to expand to 5 spaces */
+ spaces = 5, lines = 0;
break;
case SI :
pgls->g.font_selected = 0;
diff --git a/pcl/pglfill.c b/pcl/pglfill.c
index 1fe47e4b4..70a4ad6af 100644
--- a/pcl/pglfill.c
+++ b/pcl/pglfill.c
@@ -199,20 +199,33 @@ private const hpgl_line_type_t hpgl_adaptive_pats[8] = {
/* LT; */
int
hpgl_LT(hpgl_args_t *pargs, hpgl_state_t *pgls)
-{ int type = 0;
+{
+ int type = 0;
if ( hpgl_arg_c_int(pargs, &type) )
- { if ( type == 99 )
- ;
+ {
+ /* restore old saved line if we have a solid line,
+ otherwise the instruction is ignored. */
+ if ( type == 99 )
+ {
+ if ( pgls->g.line.is_solid == true )
+ {
+ hpgl_args_t args;
+ hpgl_args_set_int(&args, pgls->g.line.last_type);
+ hpgl_LT(&args, pgls);
+ }
+ return 0;
+ }
else
- { hpgl_real_t length = 0.04;
- int mode = 0;
+ {
+ hpgl_real_t length = 0.04;
+ int mode = 0;
if ( type < -8 || type > 8 ||
(hpgl_arg_c_real(pargs, &length) &&
(length <= 0 ||
(hpgl_arg_c_int(pargs, &mode) && (mode & ~1))))
- )
+ )
return e_Range;
pgls->g.line.pattern_length = length;
pgls->g.line.pattern_length_relative = mode == 0;
@@ -220,8 +233,12 @@ hpgl_LT(hpgl_args_t *pargs, hpgl_state_t *pgls)
}
} else
{
- /* no args restore defaults */
- /*** HAS, need to save the current line type also ***/
+ /* no args restore defaults and set previous line
+ type. */
+ /* HAS **BUG**BUG** initial value of line type
+ is not supplied unless it gets set by previous LT
+ command. */
+ pgls->g.line.last_type = pgls->g.line.type;
pgls->g.line.is_solid = true;
memcpy(&pgls->g.fixed_line_type,
&hpgl_fixed_pats,
@@ -458,7 +475,7 @@ hpgl_UL(hpgl_args_t *pargs, hpgl_state_t *pgls)
hpgl_line_type_t *fixed_plt =
&pgls->g.fixed_line_type[(index < 0 ? -index : index) - 1];
hpgl_line_type_t *adaptive_plt =
- &pgls->g.fixed_line_type[(index < 0 ? -index : index) - 1];
+ &pgls->g.adaptive_line_type[(index < 0 ? -index : index) - 1];
fixed_plt->count = adaptive_plt->count = i;
memcpy(fixed_plt->gap, gap, i * sizeof(hpgl_real_t));
memcpy(adaptive_plt->gap, gap, i * sizeof(hpgl_real_t));
diff --git a/pcl/pgstate.h b/pcl/pgstate.h
index 4e0e74b32..84446915f 100644
--- a/pcl/pgstate.h
+++ b/pcl/pgstate.h
@@ -8,6 +8,15 @@
#ifndef pgstate_INCLUDED
# define pgstate_INCLUDED
+/* HPGL/2 coordinates are internally represented in plotter units
+ 1/1024" when scaling is off and user units when scaling is in
+ effect. The data structure g.pos maintains the coordinates in the
+ hpgl/2 state. By default the coordinate system sets up the origin
+ in the lower left of the page with X increasing along the short
+ edge and Y increasing up the long edge. Note the Y direction is
+ opposite PCL's. */
+
+
#include "gslparam.h"
#include "gsuid.h" /* for gxbitmap.h */
#include "gstypes.h" /* for gxbitmap.h */
@@ -95,6 +104,7 @@ typedef struct pcl_hpgl_state_s {
/* Chapter 22 (pglfill.c) */
struct lp_ {
+ int last_type; /* used by line type 99 */
int type;
float pattern_length;
bool pattern_length_relative;
@@ -237,4 +247,11 @@ do {\
if ( (restore_flags) & hpgl_pen_pos )\
((pgls)->g.pos = (save)->pos);\
} while (0)
+
+/* save the current line to be used when lt99 is issued */
+#define hpgl_set_line_type99(pgls) ((pgls)->g.line99 = (pgls)->g.line)
+
+/* restore previous line type */
+#define hpgl_restore_line_type99(pgls) ((pgls)->g.line = (pgls)->g.line99)
#endif /* pgstate_INCLUDED */
+
diff --git a/pcl/pgvector.c b/pcl/pgvector.c
index 13978790c..d3bda37d0 100644
--- a/pcl/pgvector.c
+++ b/pcl/pgvector.c
@@ -46,11 +46,13 @@ hpgl_arc(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative)
radius =
hpgl_compute_distance(x_current, y_current, x_center, y_center);
- start_angle =
+ start_angle = radians_to_degrees *
hpgl_compute_angle(x_current - x_center, y_current - y_center);
hpgl_add_arc_to_path(pgls, x_center, y_center,
- radius, start_angle, sweep, chord_angle);
+ radius, start_angle, sweep,
+ (sweep < 0.0 ) ?
+ -chord_angle : chord_angle);
hpgl_draw_current_path(pgls, hpgl_rm_vector);
@@ -88,10 +90,7 @@ hpgl_arc_3_point(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative)
x_start = pgls->g.pos.x;
y_start = pgls->g.pos.y;
-
- /* HAS check this */
- /* hpgl_draw_current_path(pgls, hpgl_rm_vector); */
-
+
if ( hpgl_3_same_points(x_start, y_start, x_inter,
y_inter, x_end, y_end) )
hpgl_draw_dot(pgls, x_start, y_start);
@@ -127,24 +126,70 @@ hpgl_arc_3_point(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative)
x_inter, y_inter,
x_end, y_end, &x_center, &y_center);
- radius = hpgl_compute_distance(x_start, y_start,
- x_center, y_center);
+ radius = hypot(x_start - x_center, y_start - y_center);
counter_clockwise =
- hpgl_compute_arc_direction(x_start, y_start, x_end, y_end);
+ hpgl_compute_arc_direction(x_start, y_start, x_inter, y_inter);
- start_angle =
+ start_angle = radians_to_degrees *
hpgl_compute_angle(x_start - x_center, y_start - y_center);
- end_angle =
+ end_angle = radians_to_degrees *
hpgl_compute_angle(x_end - x_center, y_end - y_center);
- hpgl_add_arc_to_path(pgls, x_center, y_center, radius,
- start_angle,
- (counter_clockwise ?
- -(end_angle - start_angle) :
- (start_angle - end_angle)),
- chord_angle);
+ {
+ floatp sweep_angle, dot_product;
+ hpgl_args_t args;
+ gs_point u, v, u_scaled, v_scaled;
+
+ /* calculate angle x between start vector (u) and end vector
+ (v) using:
+ u v
+ cos(x) =---- . ----
+ ||u|| ||v||
+ */
+
+ u.x = x_start - x_center;
+ u.y = y_start - y_center;
+
+ v.x = x_end - x_center;
+ v.y = y_end - y_center;
+
+ hpgl_call(hpgl_scale_vector(&u, (1.0 / radius), &u_scaled));
+ hpgl_call(hpgl_scale_vector(&v, (1.0 / radius), &v_scaled));
+
+ hpgl_call(hpgl_compute_dot_product(&u_scaled,
+ &v_scaled,
+ &dot_product));
+
+ /* HAS annoying imprecision -- clamp for now but needs
+ to be done correctly later specifically dot_product
+ +- NOISE results in acos returning NaN */
+ dot_product = (dot_product > 1.0) ? 1.0 : dot_product;
+ dot_product = (dot_product < -1.0) ? -1.0 : dot_product;
+ sweep_angle = radians_to_degrees * acos(dot_product);
+
+
+
+ if ( hpgl_compute_arc_direction(x_start, y_start,
+ x_inter, y_inter) )
+ {
+ sweep_angle = -sweep_angle;
+ sweep_angle += 360.0;
+ sweep_angle = -sweep_angle;
+ }
+ else
+ sweep_angle = 360.0 - sweep_angle;
+
+ /* reverse the direction if necessary. hpgl_arc handles
+ changing the chord value. */
+
+ hpgl_args_set_real(&args, x_center);
+ hpgl_args_add_real(&args, y_center);
+ hpgl_args_add_real(&args, sweep_angle);
+ hpgl_args_add_real(&args, chord_angle);
+ hpgl_arc(&args, pgls, false);
+ }
}
return 0;
}
@@ -293,35 +338,24 @@ int
hpgl_CI(hpgl_args_t *pargs, hpgl_state_t *pgls)
{
hpgl_real_t radius, chord = 5;
+ hpgl_pen_state_t saved_pen_state;
if ( !hpgl_arg_units(pargs, &radius) )
return e_Range;
hpgl_arg_c_real(pargs, &chord);
- {
- hpgl_args_t args;
- bool down = pgls->g.pen_down;
+ /* draw the current path if there is one */
+ hpgl_draw_current_path(pgls, hpgl_rm_vector);
+ hpgl_save_pen_state(pgls, &saved_pen_state, hpgl_pen_all);
- hpgl_clear_current_path(pgls);
+ pgls->g.pen_down = true;
- /* implicit pen down */
- hpgl_args_setup(&args);
- hpgl_PU(&args, pgls);
+ /* draw the arc/circle */
+ hpgl_add_arc_to_path(pgls, pgls->g.pos.x, pgls->g.pos.y,
+ radius, 0.0, 360.0, chord);
+ /* restore pen state */
- hpgl_args_setup(&args);
- hpgl_PD(&args, pgls);
+ hpgl_restore_pen_state(pgls, &saved_pen_state, hpgl_pen_all);
+ hpgl_draw_current_path(pgls, hpgl_rm_vector);
- /* draw the arc/circle */
- hpgl_add_arc_to_path(pgls, pgls->g.pos.x, pgls->g.pos.y,
- radius, 0.0, 360.0, chord);
- /* restore pen state */
- hpgl_args_setup(&args);
- if (down)
- hpgl_PD(&args, pgls);
- else
- hpgl_PU(&args, pgls);
- }
-
- /* HAS check this */
- /* hpgl_draw_current_path(pgls, hpgl_rm_vector); */
return 0;
}