diff options
43 files changed, 1305 insertions, 1008 deletions
diff --git a/pcl/news-pcl b/pcl/news-pcl index 96fa438fb..74c8cf914 100644 --- a/pcl/news-pcl +++ b/pcl/news-pcl @@ -6,10 +6,108 @@ This file, NEWS-PCL, describes the changes in the most recent releases of Aladdin's PCL5 code, in reverse chronological order. -Version 0.40 (11/30/97) -======================= +Version 0.41 (11/26/97) + +All functionality of the pcl5e fts is now included. Here is what is +new with pcl 0.41: +-pcl alphanumeric id command (ESC & n <count> W [operation][string +ID]) (pcsfont.c) +-Assign font id to copy of current font (ESC * c 6 F). (pcsfont.c) +-Variable text path (ESC & c # T). (pctext.c) +-pcl text parsing method was partially implemented now it is fully +implemented. + +These functions are still not implemented and are not sported in the +fts: + +-Select default font (ESC (|) 3 @). (pcfont.c) +-Conditional pattern rotation (ESC * p # R). (pcprint.c) +-Continuation blocks for character data (for ESC ( s # W). +-Double-byte characters (LM command is implemented but has no + effect). + +This is not implemented and is part of the fts, but does not result in +erroneous output: +-media select of pcl alphanumeric id command (ESC & n <count> W) (see +new functionality above) is not supported. It requires interaction +with the control panel. + + +Known problems: +1) GS does not support grid centered fill model so a number of the fts PP +placement panels do not produce the correct output. Fills should drop +one row and one column of pixels when "grid centering" is enabled. +2) GS bug for triangular joins manifests in the GL/2 portion of the +pcl5e (e.g. 1493). Seems like ccw case does not work and cw does. +3) We lack complete symbol set coverage. The current fonts do not +provide all of the symbols. +4) There is a very small difference in space width which is only +noticeable as an accumulation error after a long line of characters. +We are using the space width value from the fonts which comes very +close to the actual HP value. +5) GL/2 fill types FT3, FT4 do not support non-zero winding and +even/odd filling - A bounding box for the object is filled and +subsequently clipped in device space to the perimeter of the polygon. +6) A downloaded intellifont that shows up in several fts panels +(e.g. 2502) has the value 0xffff for the number of auxillary +coordinates. PCL sets the value to zero, prints an error message and +rasterizes without using auxillary coordinates resulting in a +misprinted character (char 116 't'). +8) the character substitution model is not correct but is optimized to +display as many symbols as possible given our font collection. It +simply selects the closest matching font that contains the missing symbol. +9) the escapement for vertical characters is wrong. +10) several fts panels (e.g. 2381) use logical operation 85 or not +destination. We implement this correctly the 6mp does not seem to +support it. +12) GS single dots default orientation is wrong. 0 lenghth lines are +project parallel to the current hpgl/2 X-axis. + +The scope of problems 3, 4, 6, 8, and 9 cannot be exactly determined +without a compatible font solution. + +Bug fixes and other changes: + +-removed hpgl_clear_state(), -Z@ suffices. +-pgvector.c incorrect parameters given for +hpgl_print_symbol_mode_char(), harmless but wrong. +-pgmand.h added missing prototype decorations. +-pglabel.c label origin 21 not correct - needs be set in user space +not plu space as other origin offsets are handled. +-pgdraw.c gs_setdotlength used always now, not just for dash. +-pgconfig.c SC now updates the CR point contrary to the documentation. +Also, simplification of SC command. +-pctext.c the hack for bound true type fonts being indexed from 0xf000 +should only apply to internal fonts. +-state changes to support switching back and forth between numeric id' +and alphanumeric id's. Only used for soft fonts and fonts. +-pcifont.c removed - absorbed into the PL library. +-pcfsel.c - recompute substitute font hack added (see new +functionality section). Some reorganization. +-pcommand.c - float_value() lacked a cast to int, losing sign when +cast to float. +-pgdraw.c - Testing on the 6mp indicates if pen 0 (white) is active +GL/2 always selects a solid white pattern irrespective of current fill +type. This does not seem right and might be a 6mp bug but now we +emulated that behavior. +-pclfont.c - changed character complement to reflect MSL symbol codes for +wingdings and symbol fonts. +-pginit.c - added limit clamping to prevent overflow on several CET +tests. This is probably not a sufficient fix if complete CET +compliance is needed. +-pgdraw.c - code to adjust anchor corner for hpgl/2 vector fills. +Cases where the anchor is greater than the origin of the filled object +are now handled correctly. Also, simplified filling code a bit more. +-pgconfig.c - hpgl's SC now updates carriage return position. +-pgvector.c - hpgl's CI was not returning the pen to the center +position in all circumstances. +-pgpoly.c - exiting polygon mode does not restore the previous pen +relative status but it does restore position and up/down status. +-makefile - the usual "missing" include file fixes (this should be +automated). + +Version 0.40 (11/26/97) -(HAS) -rtmisc.c - changed comments, pcl_source_transparent() changed to only update state source transparency; moved gs call to pcl_set_drawing_color(). @@ -68,20 +166,15 @@ adjust since this is now maintained directly as floats. now float. -pcl.mak - new include file dependencies added. -(LPD) Adds some #includes to make the code compile with library version -5.20, in which gs_memory_default is not declared by gsmemory.h. -(pcstatus.c) - See Version 0.38 notes for missing functionality. Version 0.39 (11/25/97) -======================= -This release simply changes the default pcl5 device to x11mono. Currently -the pcl code does not completely support devices with more than 1 bit per -pixel, previously the default device was X11 which is an 8 bit per pixel -color device. The only necessary change was reordering the device files in -the pcl5 makefile. (pcl.mak) +This release simply changes the default pcl5 device to x11mono. +Currently the pcl code does not completely support devices with more +than 1 bit per pixel, previously the default device was X11 which is +an 8 bit per pixel color device. The only necessary change was +reordering the device files in the pcl5 makefile Version 0.38 (11/20/97) ======================= diff --git a/pcl/pccprint.c b/pcl/pccprint.c index e686fc5e3..74cba9d2f 100644 --- a/pcl/pccprint.c +++ b/pcl/pccprint.c @@ -61,7 +61,7 @@ pccprint_do_copy(pcl_state_t *psaved, const pcl_state_t *pcls, pcl_copy_operation_t operation) { if ( operation & pcl_copy_after ) { gs_setrasterop(pcls->pgs, psaved->logical_op); - gs_setfilladjust(pcls->pgs, + gs_setfilladjust(pcls->pgs, psaved->grid_adjust, psaved->grid_adjust); } return 0; diff --git a/pcl/pcdraw.c b/pcl/pcdraw.c index a9d0b8b92..3cdfa1e44 100644 --- a/pcl/pcdraw.c +++ b/pcl/pcdraw.c @@ -10,12 +10,12 @@ #include "gsmatrix.h" /* for gsstate.h */ #include "gsmemory.h" /* for gsstate.h */ #include "gsstate.h" -#include "gsrop.h" #include "gscspace.h" /* for gscolor2.h */ #include "gscoord.h" #include "gsdcolor.h" #include "gsimage.h" #include "gsrefct.h" +#include "gsrop.h" #include "gsutil.h" #include "gxcolor2.h" /* for gs_makebitmappattern, rc_decrement */ #include "gxfixed.h" @@ -263,7 +263,7 @@ pcl_set_hmi(pcl_state_t *pcls, coord hmi, bool explicit) pcls->hmi = (explicit ? hmi : (hmi + (pcls->uom_cp >> 1)) / pcls->uom_cp * pcls->uom_cp); -} +} /* Update the HMI by recomputing it from the font. */ coord @@ -305,7 +305,7 @@ pcl_updated_hmi(pcl_state_t *pcls) #define r1(a) r2(a,a) #define p4(a,b,c,d) r1(a), r1(b), r1(c), r1(d) #define p8(a,b,c,d,e,f,g,h) p4(a,b,c,d), p4(e,f,g,h) -#define p2x8(a,b,c,d,e,f,g,h) p8(a,b,c,d,e,f,g,h), p8(a,b,c,d,e,f,g,h) +#define p2x8(a,b,c,d,e,f,g,h) p8(a,b,c,d,e,f,g,h), p8(a,b,c,d,e,f,g,h) private const uint32 shade_1_2[] = { p8(0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), @@ -568,7 +568,7 @@ pcl_set_drawing_color_rotation(pcl_state_t *pcls, pcl_pattern_type_t type, return_error(gs_error_rangecheck); } tile.id = gx_no_bitmap_id; - /* + /* * Create a bitmap pattern if one doesn't already exist. */ { gs_client_color ccolor; @@ -644,19 +644,17 @@ pcl_set_drawing_color(pcl_state_t *pcls, pcl_pattern_type_t type, const pcl_id_t /* get rid of cached pattern references maintained in the pcl state. This code is duplicated in pattern initilization. */ -private void -cached_pattern_release(gs_pattern_instance **pcpat) -{ rc_decrement_only(*pcpat, "cached_pattern_release"); - *pcpat = 0; -} int pcl_clear_cached_pattern_refs(pcl_state_t *pcls) { int i; for ( i=0; i < countof(pcls->cached_pattern); i++ ) - cached_pattern_release(&pcls->cached_pattern[i]); + { rc_decrement_only(pcls->cached_pattern[i], + "old cached_pattern"); + pcls->cached_pattern[i] = 0; + } return 0; } - + /* Initialization */ private int pcdraw_do_init(gs_memory_t *mem) @@ -667,6 +665,11 @@ cached_pattern_init(gs_pattern_instance **pcpat) { *pcpat = 0; } private void +cached_pattern_release(gs_pattern_instance **pcpat) +{ rc_decrement_only(*pcpat, "cached_pattern_release"); + *pcpat = 0; +} +private void pcdraw_do_reset(pcl_state_t *pcls, pcl_reset_type_t type) { void (*proc)(P1(gs_pattern_instance **)); diff --git a/pcl/pcdraw.h b/pcl/pcdraw.h index 9cc1fda6f..04f68a452 100644 --- a/pcl/pcdraw.h +++ b/pcl/pcdraw.h @@ -89,12 +89,12 @@ typedef struct pcl_pattern_s { /* the phase or "origin" of the pattern is specified in device space */ int pcl_set_drawing_color_rotation(P6(pcl_state_t *pcls, pcl_pattern_type_t type, - const pcl_id_t *pid, pl_dict_t *patterns, + const pcl_id_t *pid, pl_dict_t *patterns, int rotation, gs_point *origin)); /* same as above function but is only called only by pcl. It derives the rotation and origin from pcl state values */ -int pcl_set_drawing_color(P3(pcl_state_t *pcls, pcl_pattern_type_t type, +int pcl_set_drawing_color(P3(pcl_state_t *pcls, pcl_pattern_type_t type, const pcl_id_t *pid)); /* get rid of cached pattern references maintained in the pcl state. */ diff --git a/pcl/pcfont.c b/pcl/pcfont.c index 722090800..28546d061 100644 --- a/pcl/pcfont.c +++ b/pcl/pcfont.c @@ -60,6 +60,27 @@ pcl_decache_font(pcl_state_t *pcls, int set) } } +/* set current font and symbol table to selected parameter's font and + symbol table */ +private int +pcl_set_font(pcl_state_t *pcls, pcl_font_selection_t *pfs) +{ + pcls->font = pfs->font; + pcls->map = pfs->map; + return 0; +} + +int +pcl_recompute_substitute_font(pcl_state_t *pcls, const uint chr) +{ + pcl_font_selection_t *pfs = &pcls->font_selection[pcls->font_selected]; + int code = pcl_reselect_substitute_font(pfs, pcls, chr); + if ( code < 0 ) + return code; + pcl_set_font(pcls, pfs); + return 0; +} + /* Recompute the current font from the descriptive parameters. */ /* This is exported for resetting HMI. */ int @@ -69,13 +90,11 @@ pcl_recompute_font(pcl_state_t *pcls) if ( code < 0 ) return code; - pcls->font = pfs->font; - pcls->map = pfs->map; + pcl_set_font(pcls, pfs); return 0; } /* The font parameter commands all come in primary and secondary variants. */ - private int pcl_symbol_set(pcl_args_t *pargs, pcl_state_t *pcls, int set) { uint num = uint_arg(pargs); diff --git a/pcl/pcfont.h b/pcl/pcfont.h index d8bdd2008..c7377d68b 100644 --- a/pcl/pcfont.h +++ b/pcl/pcfont.h @@ -19,6 +19,11 @@ void pcl_decache_font(P2(pcl_state_t *pcls, int set)); /* This is exported for resetting HMI. */ int pcl_recompute_font(P1(pcl_state_t *pcls)); +/* recompute the font if the glyph is not found at the time of + rendering */ +int pcl_recompute_substitute_font(P2(pcl_state_t *pcls, const uint chr)); + + /* Do any underlining just before a break in motion (vertical motion or * negative horizontal motion)... */ #define pcl_break_underline(pcls)\ diff --git a/pcl/pcfsel.c b/pcl/pcfsel.c index 20b7f3f56..2538f8316 100644 --- a/pcl/pcfsel.c +++ b/pcl/pcfsel.c @@ -57,31 +57,35 @@ dprint_font_t(const pl_font_t *pfont) #endif -/* Decide whether an unbound font supports a symbol set (mostly convenient - * setup for pcl_check_symbol_support(). */ -private bool +/* Decide whether an unbound font supports a symbol set (mostly + convenient setup for pcl_check_symbol_support(). (HAS) Has the + peculiar side effect of setting the symbol table to the default if + the requested map is not available or to the requested symbol set + if it is available. 2 is returned for no matching symbol set, 1 for + mismatched vocabulary and 0 if the sets match. */ +private int check_support(const pcl_state_t *pcls, uint symbol_set, pl_font_t *fp, pl_symbol_map_t **mapp) { pl_glyph_vocabulary_t gv = ~fp->character_complement[7] & 07; byte id[2]; - pl_symbol_map_t *map; - id[0] = symbol_set >> 8; id[1] = symbol_set; - if ( (map = pcl_find_symbol_map(pcls, id, gv)) == 0 ) - return false; - if ( pcl_check_symbol_support(map->character_requirements, - fp->character_complement) ) + *mapp = pcl_find_symbol_map(pcls, id, gv); + if ( *mapp == 0 ) { - *mapp = map; - return true; + id[0] = pcl_default_symbol_set_value >> 8; + id[1] = (byte)pcl_default_symbol_set_value; + *mapp = pcl_find_symbol_map(pcls, id, gv); + return 2; /* worst */ } + if ( pcl_check_symbol_support((*mapp)->character_requirements, + fp->character_complement) ) + return 2; /* best */ else - return false; + return 1; } - /* Compute a font's score against selection parameters. TRM 8-27. * Also set *mapp to the symbol map to be used if this font wins. */ private void @@ -100,10 +104,7 @@ score_match(const pcl_state_t *pcls, const pcl_font_selection_t *pfs, *mapp = 0; /* bound fonts have no map */ } else - score[score_symbol_set] = - check_support(pcls, pfs->params.symbol_set, fp, mapp)? 2: - check_support(pcls, pcl_default_symbol_set_value, fp, mapp); - + score[score_symbol_set] = check_support(pcls, pfs->params.symbol_set, fp, mapp); /* 2. Spacing. */ score[score_spacing] = pfs->params.proportional_spacing == fp->params.proportional_spacing; @@ -283,21 +284,70 @@ pcl_reselect_font(pcl_font_selection_t *pfs, const pcl_state_t *pcls) return 0; } -/* Select a font by ID, updating the selection parameters. */ -/* Return 0 normally, 1 if no font was found, or an error code. */ +/* Selects a substitute font after a glyph is not found in the + currently selected font upon rendering. Very expensive in the + current architecture. We should have a more efficient way of + finding characters in fonts */ + +/* This is used by both PCL and HP-GL/2. */ int -pcl_select_font_by_id(pcl_font_selection_t *pfs, uint id, - const pcl_state_t *pcls) -{ byte id_key[2]; - void *value; - pl_font_t *fp; +pcl_reselect_substitute_font(pcl_font_selection_t *pfs, + const pcl_state_t *pcls, const uint chr) +{ + if ( pfs->font == 0 ) + { + pl_dict_enum_t dictp; + gs_const_string key; + void *value; + pl_font_t *best_font = 0; + pl_symbol_map_t *mapp, *best_map; + match_score_t best_match; +#ifdef DEBUG + if ( gs_debug_c('=') ) + { dputs("[=]request: "); + dprint_font_params_t(&pfs->params); + } +#endif - id_key[0] = id >> 8; - id_key[1] = (byte)id; - if ( !pl_dict_find(&pcls->soft_fonts, id_key, 2, &value) ) - return 1; /* font not found */ - fp = (pl_font_t *)value; + /* Initialize the best match to be worse than any real font. */ + best_match[0] = -1; + pl_dict_enum_begin(&pcls->soft_fonts, &dictp); + while ( pl_dict_enum_next(&dictp, &key, &value) ) + { pl_font_t *fp = (pl_font_t *)value; + match_score_t match; + score_index_t i; + gs_matrix ignore_mat; + if ( !pl_font_includes_char(fp, NULL, &ignore_mat, chr) ) + continue; + score_match(pcls, pfs, fp, &mapp, match); + for (i=0; i<score_limit; i++) + if ( match[i] != best_match[i] ) + { + if ( match[i] > best_match[i] ) + { + best_font = fp; + best_map = mapp; + memcpy((void*)best_match, (void*)match, + sizeof(match)); + if_debug0('=', " (***best so far***)\n"); + } + break; + } + } + if ( best_font == 0 ) + return -1; /* no font found */ + pfs->font = best_font; + pfs->map = best_map; + } + pfs->selected_by_id = false; + return 0; +} +/* set font parameters after an id selection */ +void +pcl_set_id_parameters(const pcl_state_t *pcls, + pcl_font_selection_t *pfs, const pl_font_t *fp) +{ /* Transfer parameters from the selected font into the selection * parameters, being careful with the softer parameters. */ pfs->font = fp; @@ -319,7 +369,6 @@ pcl_select_font_by_id(pcl_font_selection_t *pfs, uint id, */ } } - pfs->params.proportional_spacing = fp->params.proportional_spacing; if ( !pfs->params.proportional_spacing && !pl_font_is_scalable(fp) ) pfs->params.pitch = fp->params.pitch; @@ -328,5 +377,23 @@ pcl_select_font_by_id(pcl_font_selection_t *pfs, uint id, pfs->params.style = fp->params.style; pfs->params.stroke_weight = fp->params.stroke_weight; pfs->params.typeface_family = fp->params.typeface_family; + return; +} + +/* Select a font by ID, updating the selection parameters. */ +/* Return 0 normally, 1 if no font was found, or an error code. */ +int +pcl_select_font_by_id(pcl_font_selection_t *pfs, uint id, + const pcl_state_t *pcls) +{ byte id_key[2]; + void *value; + pl_font_t *fp; + + id_key[0] = id >> 8; + id_key[1] = (byte)id; + if ( !pl_dict_find(&pcls->soft_fonts, id_key, 2, &value) ) + return 1; /* font not found */ + fp = (pl_font_t *)value; + pcl_set_id_parameters(pcls, pfs, fp); return 0; } diff --git a/pcl/pcfsel.h b/pcl/pcfsel.h index 0f5f40669..85a18f065 100644 --- a/pcl/pcfsel.h +++ b/pcl/pcfsel.h @@ -12,6 +12,12 @@ /* This is used by both PCL and HP-GL/2. */ int pcl_reselect_font(P2(pcl_font_selection_t *pfs, const pcl_state_t *pcls)); +/* fallback if a glyph is not found in a font. This select the best + from the parameters, however, the font is chosen only from the + collection of fonts that actually have the desired character code */ +int pcl_reselect_substitute_font(P3(pcl_font_selection_t *pfs, + const pcl_state_t *pcls, + const uint chr)); /* * Select a font by ID, updating the selection parameters. Return 0 * normally, 1 if no font was found, or an error code. The pcl_state_t is diff --git a/pcl/pcjob.c b/pcl/pcjob.c index 5f1b90dbc..f8b6617de 100644 --- a/pcl/pcjob.c +++ b/pcl/pcjob.c @@ -25,6 +25,11 @@ pcl_printer_reset(pcl_args_t *pargs, pcl_state_t *pcls) if ( code < 0 ) return code; } + /* exit hpgl/2 mode if necessary */ + { pcl_args_t args; + arg_set_uint(&args, 0); + rtl_enter_pcl_mode(pargs, pcls); + } /* Reset to user default state. */ return pcl_do_resets(pcls, pcl_reset_printer); } @@ -211,7 +216,7 @@ pcjob_do_init(gs_memory_t *mem) {'u', 'D', PCL_COMMAND("Set Unit of Measure", pcl_set_unit_of_measure, pca_neg_error|pca_big_error)}, - END_CLASS + END_CLASS return 0; } private void diff --git a/pcl/pcl.mak b/pcl/pcl.mak index 8e5640935..445cc8a66 100644 --- a/pcl/pcl.mak +++ b/pcl/pcl.mak @@ -93,7 +93,7 @@ $(PCLOBJ)pcommand.$(OBJ): $(PCLSRC)pcommand.c $(std_h)\ $(PCLOBJ)pcdraw.$(OBJ): $(PCLSRC)pcdraw.c $(std_h) $(math__h)\ $(gscolor2_h) $(gscoord_h) $(gscspace_h) $(gsdcolor_h) $(gsimage_h)\ - $(gsmatrix_h) $(gsmemory_h) $(gsrop_h) $(gsstate_h) $(gstypes_h) $(gsutil_h)\ + $(gsrefct_h) $(gsrop_h) $(gsmatrix_h) $(gsmemory_h) $(gsstate_h) $(gstypes_h) $(gsutil_h)\ $(gxfixed_h) $(gxstate_h) $(gzstate_h)\ $(plvalue_h)\ $(pcdraw_h) $(pcommand_h) $(pcfont_h) $(pcstate_h) @@ -206,7 +206,7 @@ pcsymbol_h=$(PCLSRC)pcsymbol.h $(plsymbol_h) # Font selection is essentially identical in PCL and HP-GL/2. $(PCLOBJ)pcfsel.$(OBJ): $(PCLSRC)pcfsel.c\ - $(std_h)\ + $(stdio_h) $(gdebug_h)\ $(pcommand_h) $(pcfont_h) $(pcfsel_h) $(pcstate_h) $(pcsymbol_h) $(PCLCCC) $(PCLSRC)pcfsel.c $(PCLO_)pcfsel.$(OBJ) @@ -241,7 +241,7 @@ $(PCLOBJ)pcursor.$(OBJ): $(PCLSRC)pcursor.c $(std_h)\ $(PCLOBJ)pcfont.$(OBJ): $(PCLSRC)pcfont.c $(memory__h)\ $(gsccode_h) $(gsmatrix_h)\ $(gx_h) $(gxfont_h) $(gxfont42_h)\ - $(pcfont_h) $(pcfsel_h) $(pcommand_h) $(pcstate_h) + $(pcfont_h) $(pcfsel_h) $(pcommand_h) $(pcstate_h) $(plfont_h) $(PCLCCC) $(PCLSRC)pcfont.c $(PCLO_)pcfont.$(OBJ) $(PCLOBJ)pclfont.$(OBJ): $(PCLSRC)pclfont.c $(stdio__h) $(string__h)\ @@ -251,8 +251,9 @@ $(PCLOBJ)pclfont.$(OBJ): $(PCLSRC)pclfont.c $(stdio__h) $(string__h)\ $(PCLCCC) $(PCLSRC)pclfont.c $(PCLO_)pclfont.$(OBJ) $(PCLOBJ)pctext.$(OBJ): $(PCLSRC)pctext.c\ - $(std_h)\ - $(gscoord_h) $(gsline_h) $(gspaint_h) $(gspath_h) $(gspath2_h)\ + $(std_h) $(stdio_h)\ + $(gdebug_h)\ + $(gscoord_h) $(gsline_h) $(gspaint_h) $(gspath_h) $(gspath2_h) $(gsrop) $(gsstate.h)\ $(gxchar_h) $(gxfont_h) $(gxstate_h)\ $(plvalue_h)\ $(pcdraw_h) $(pcfont_h) $(pcommand_h) $(pcstate_h) @@ -264,17 +265,8 @@ $(PCLOBJ)pcsymbol.$(OBJ): $(PCLSRC)pcsymbol.c $(stdio__h)\ $(pcommand_h) $(pcfont_h) $(pcstate_h) $(pcsymbol_h) $(PCLCCC) $(PCLSRC)pcsymbol.c $(PCLO_)pcsymbol.$(OBJ) -# Chapter 9 & 11 -$(PCLOBJ)pcifont.$(OBJ): $(PCLSRC)pcifont.c $(stdio__h)\ - $(gdebug_h)\ - $(gsccode_h) $(gschar_h) $(gscoord_h) $(gsmatrix_h) $(gsmemory_h)\ - $(gspaint_h) $(gspath_h) $(gsstate_h) $(gstypes_h)\ - $(gxfont_h)\ - $(plfont_h) $(plvalue_h) - $(PCLCCC) $(PCLSRC)pcifont.c $(PCLO_)pcifont.$(OBJ) - $(PCLOBJ)pcsfont.$(OBJ): $(PCLSRC)pcsfont.c $(memory__h) $(stdio__h)\ - $(gsbitops_h) $(gsccode_h) $(gsmatrix_h) $(gsutil_h)\ + $(math__h) $(gsbitops_h) $(gsccode_h) $(gsmatrix_h) $(gsutil_h)\ $(gxfont_h) $(gxfont42_h)\ $(pcommand_h) $(pcfont_h) $(pcstate_h)\ $(pldict_h) $(plvalue_h) @@ -288,8 +280,8 @@ $(PCLOBJ)pcmacros.$(OBJ): $(PCLSRC)pcmacros.c $(stdio__h)\ # Chapter 13 # Some of these are in rtmisc.c. $(PCLOBJ)pcprint.$(OBJ): $(PCLSRC)pcprint.c $(stdio__h)\ - $(gsbitops_h) $(gscoord_h) $(gsmatrix_h) $(gsrop_h) $(gsstate_h)\ - $(gxbitmap_h)\ + $(gsbitops_h) $(gscoord_h) $(gsmatrix_h) $(gsrefct_h) $(gsrop_h) $(gsstate_h)\ + $(gxbitmap_h) $(gxdevice_h) $(gxpcolor_h)\ $(plvalue_h)\ $(pcdraw_h) $(pcommand_h) $(pcstate_h) $(PCLCCC) $(PCLSRC)pcprint.c $(PCLO_)pcprint.$(OBJ) @@ -306,7 +298,6 @@ $(PCLOBJ)pcrect.$(OBJ): $(PCLSRC)pcrect.c $(math__h)\ # Chapter 16 $(PCLOBJ)pcstatus.$(OBJ): $(PCLSRC)pcstatus.c $(memory__h) $(stdio__h) $(string__h)\ - $(gsmemory_h) $(gstypes_h) $(gxdevice_h)\ $(stream_h)\ $(pcfont_h) $(pcommand_h) $(pcstate_h) $(pcsymbol_h) $(PCLCCC) $(PCLSRC)pcstatus.c $(PCLO_)pcstatus.$(OBJ) @@ -317,7 +308,7 @@ $(PCLOBJ)pcmisc.$(OBJ): $(PCLSRC)pcmisc.c $(std_h) $(pcommand_h) $(pcstate_h) PCL5_OPS1=$(PCLOBJ)pcjob.$(OBJ) $(PCLOBJ)pcpage.$(OBJ) $(PCLOBJ)pcursor.$(OBJ) PCL5_OPS2=$(PCLOBJ)pcfont.$(OBJ) $(PCLOBJ)pclfont.$(OBJ) $(PCLOBJ)pctext.$(OBJ) -PCL5_OPS3=$(PCLOBJ)pcsymbol.$(OBJ) $(PCLOBJ)pcifont.$(OBJ) +PCL5_OPS3=$(PCLOBJ)pcsymbol.$(OBJ) PCL5_OPS4=$(PCLOBJ)pcsfont.$(OBJ) $(PCLOBJ)pcmacros.$(OBJ) $(PCLOBJ)pcprint.$(OBJ) PCL5_OPS5=$(PCLOBJ)pcrect.$(OBJ) $(PCLOBJ)pcstatus.$(OBJ) $(PCLOBJ)pcmisc.$(OBJ) PCL5_OPS=$(PCL5_OPS1) $(PCL5_OPS2) $(PCL5_OPS3) $(PCL5_OPS4) $(PCL5_OPS5) @@ -390,14 +381,14 @@ pgmisc_h=$(PCLSRC)pgmisc.h $(PCLOBJ)pgdraw.$(OBJ): $(PCLSRC)pgdraw.c $(math__h) $(stdio__h)\ $(gdebug_h) $(gscoord_h) $(gsmatrix_h) $(gsmemory_h) $(gspaint_h) $(gspath_h)\ - $(gsstate_h) $(gstypes_h)\ + $(gsrop_h) $(gsstate_h) $(gstypes_h)\ $(gxfarith_h) $(gxfixed_h)\ $(pcdraw_h)\ $(pgdraw_h) $(pggeom_h) $(pgmand_h) $(pgmisc_h) $(PCLCCC) $(PCLSRC)pgdraw.c $(PCLO_)pgdraw.$(OBJ) -$(PCLOBJ)pggeom.$(OBJ): $(PCLSRC)pggeom.c $(math__h) $(stdio__h)\ - $(gxfarith_h) $(pggeom_h) +$(PCLOBJ)pggeom.$(OBJ): $(PCLSRC)pggeom.c $(stdio__h)\ + $(pggeom_h) $(gxfarith_h) $(PCLCCC) $(PCLSRC)pggeom.c $(PCLO_)pggeom.$(OBJ) $(PCLOBJ)pgmisc.$(OBJ): $(PCLSRC)pgmisc.c $(pgmand_h) $(pgmisc_h) @@ -406,7 +397,8 @@ $(PCLOBJ)pgmisc.$(OBJ): $(PCLSRC)pgmisc.c $(pgmand_h) $(pgmisc_h) # Initialize/reset. We break this out simply because it's easier to keep # track of it this way. -$(PCLOBJ)pginit.$(OBJ): $(PCLSRC)pginit.c $(memory__h)\ +$(PCLOBJ)pginit.$(OBJ): $(PCLSRC)pginit.c $(std_h)\ + $(gstypes_h) $(gsmatrix_h) $(gsmemory_h) $(gsstate_h)\ $(pgdraw_h) $(pginit_h) $(pgmand_h) $(pgmisc_h) $(PCLCCC) $(PCLSRC)pginit.c $(PCLO_)pginit.$(OBJ) @@ -469,13 +461,14 @@ $(PCLOBJ)pglabel.$(OBJ): $(PCLSRC)pglabel.c\ $(ctype__h) $(math__h) $(memory__h) $(stdio__h)\ $(gdebug_h)\ $(gschar_h) $(gscoord_h) $(gsline_h) $(gspath_h) $(gsutil_h)\ - $(gxfont_h)\ - $(pcfsel_h)\ - $(pgdraw_h) $(pgfont_h) $(pggeom_h) $(pginit_h) $(pgmand_h) $(pgmisc_h) + $(gxfont_h) $(gxchar_h) $(gxstate.h)\ + $(pcfsel_h) $(pcsymbol_h)\ + $(pgdraw_h) $(pgfont_h) $(pggeom_h) $(pginit_h) $(pgmand_h) $(pgmisc_h)\ + $(plvalue_h) $(PCLCCC) $(PCLSRC)pglabel.c $(PCLO_)pglabel.$(OBJ) $(PCLOBJ)pgfdata.$(OBJ): $(PCLSRC)pgfdata.c $(std_h)\ - $(gstypes_h) $(gxarith_h)\ + $(gstypes_h) $(gsccode_h) $(gxarith_h)\ $(pgfdata_h) $(PCLCCC) $(PCLSRC)pgfdata.c $(PCLO_)pgfdata.$(OBJ) diff --git a/pcl/pcl_ugcc.mak b/pcl/pcl_ugcc.mak index fe8a2d8cb..286ec6c74 100644 --- a/pcl/pcl_ugcc.mak +++ b/pcl/pcl_ugcc.mak @@ -39,7 +39,7 @@ XLIBS=Xt SM ICE Xext X11 CCLD=gcc -DEVICE_DEVS=x11mono.dev x11.dev x11alpha.dev x11cmyk.dev\ +DEVICE_DEVS=x11.dev x11mono.dev x11alpha.dev x11cmyk.dev\ djet500.dev ljet4.dev\ pcxmono.dev pcxgray.dev\ pbmraw.dev pgmraw.dev ppmraw.dev\ diff --git a/pcl/pclfont.c b/pcl/pclfont.c index cc3071f6d..fb3f04056 100644 --- a/pcl/pclfont.c +++ b/pcl/pclfont.c @@ -42,9 +42,9 @@ pcl_load_built_in_fonts(pcl_state_t *pcls, const char *prefixes[]) #define cc_alphabetic\ { C(0), C(0), C(0), C(0), C(0xff), C(0xc0), C(0), C(plgv_Unicode) } #define cc_symbol\ - { C(0), C(0), C(0), C(4), C(0), C(0), C(0), C(plgv_Unicode) } + { C(0), C(0), C(0), C(4), C(0), C(0), C(0), C(plgv_MSL) } #define cc_dingbats\ - { C(0), C(0), C(0), C(1), C(0), C(0), C(0), C(plgv_Unicode) } + { C(0), C(0), C(0), C(1), C(0), C(0), C(0), C(plgv_MSL) } #define pitch_1 fp_pitch_value_cp(1) /* * Per TRM 23-87, PCL5 printers are supposed to have Univers diff --git a/pcl/pcmacros.c b/pcl/pcmacros.c index 1cb420bc8..9cd6cf10f 100644 --- a/pcl/pcmacros.c +++ b/pcl/pcmacros.c @@ -76,8 +76,8 @@ pcl_macro_control(pcl_args_t *pargs, pcl_state_t *pcls) { /* The parser has included everything through this command */ /* in the macro_definition, so we can finish things up. */ int code; - code = pl_dict_put(&pcls->macros, id_key(pcls->macro_id), - 2, pcls->macro_definition); + code = pl_dict_put(&pcls->macros, current_macro_id, + current_macro_id_size, pcls->macro_definition); pcls->defining_macro = false; pcls->macro_definition = 0; return code; @@ -101,7 +101,7 @@ pcl_macro_control(pcl_args_t *pargs, pcl_state_t *pcls) { /* Start defining <macro_id>. */ pcl_macro_t *pmac; - pl_dict_undef(&pcls->macros, id_key(pcls->macro_id), 2); + pl_dict_undef_purge_links(&pcls->macros, current_macro_id, current_macro_id_size); pmac = (pcl_macro_t *) gs_alloc_bytes(pcls->memory, sizeof(pcl_macro_t), "begin macro definition"); @@ -119,7 +119,7 @@ pcl_macro_control(pcl_args_t *pargs, pcl_state_t *pcls) case macro_execute: /* 2 */ { /* Execute <macro_id>. */ void *value; - if ( !pl_dict_find(&pcls->macros, id_key(pcls->macro_id), 2, + if ( !pl_dict_find(&pcls->macros, current_macro_id, current_macro_id_size, &value) ) return 0; @@ -129,7 +129,7 @@ pcl_macro_control(pcl_args_t *pargs, pcl_state_t *pcls) case macro_call: /* 3 */ { /* Call <macro_id>, saving and restoring environment. */ void *value; - if ( !pl_dict_find(&pcls->macros, id_key(pcls->macro_id), 2, + if ( !pl_dict_find(&pcls->macros, current_macro_id, current_macro_id_size, &value) ) return 0; @@ -158,23 +158,23 @@ pcl_macro_control(pcl_args_t *pargs, pcl_state_t *pcls) pl_dict_enum_stack_begin(&pcls->macros, &denum, false); while ( pl_dict_enum_next(&denum, &key, &value) ) if ( ((pcl_macro_t *)value)->storage == pcds_temporary ) - pl_dict_undef(&pcls->macros, key.data, key.size); + pl_dict_undef_purge_links(&pcls->macros, key.data, key.size); return 0; } case 8: { /* Delete <macro_id>. */ - pl_dict_undef(&pcls->macros, id_key(pcls->macro_id), 2); + pl_dict_undef_purge_links(&pcls->macros, current_macro_id, current_macro_id_size); return 0; } case 9: { /* Make <macro_id> temporary. */ - if ( pl_dict_find(&pcls->macros, id_key(pcls->macro_id), 2, &value) ) + if ( pl_dict_find(&pcls->macros, current_macro_id, current_macro_id_size, &value) ) ((pcl_macro_t *)value)->storage = pcds_temporary; return 0; } case 10: { /* Make <macro_id> permanent. */ - if ( pl_dict_find(&pcls->macros, id_key(pcls->macro_id), 2, &value) ) + if ( pl_dict_find(&pcls->macros, current_macro_id, current_macro_id_size, &value) ) ((pcl_macro_t *)value)->storage = pcds_permanent; return 0; } @@ -187,6 +187,7 @@ private int /* ESC & f <id> Y */ pcl_assign_macro_id(pcl_args_t *pargs, pcl_state_t *pcls) { uint id = uint_arg(pargs); id_set_value(pcls->macro_id, id); + pcls->macro_id_type = numeric_id; return 0; } @@ -212,9 +213,15 @@ pcmacros_do_reset(pcl_state_t *pcls, pcl_reset_type_t type) pcls->defining_macro = false; pcls->saved = 0; pcls->macro_definition = 0; + pcls->alpha_macro_id.size = 0; + pcls->macro_id_type = numeric_id; id_set_value(pcls->macro_id, 0); if ( type & pcl_reset_initial ) - pl_dict_init(&pcls->macros, pcls->memory, NULL); + { + pl_dict_init(&pcls->macros, pcls->memory, NULL); + pcls->macro_id_type = numeric_id; + /* ***** Free the macro string if necessary **** */ + } else { pcl_args_t args; arg_set_uint(&args, macro_delete_temporary); diff --git a/pcl/pcmisc.c b/pcl/pcmisc.c index 2657cf654..47e961a97 100644 --- a/pcl/pcmisc.c +++ b/pcl/pcmisc.c @@ -8,7 +8,7 @@ #include "pcommand.h" #include "pcstate.h" -private int /* ESC & s <bool> C */ +private int /* ESC & s <bool> C */ pcl_end_of_line_wrap(pcl_args_t *pargs, pcl_state_t *pcls) { uint i = uint_arg(pargs); diff --git a/pcl/pcommand.c b/pcl/pcommand.c index 7778e71cc..d8c1bb911 100644 --- a/pcl/pcommand.c +++ b/pcl/pcommand.c @@ -17,7 +17,7 @@ /* Get the command argument as an int, uint, or float. */ int int_value(const pcl_value_t *pv) -{ return (int)(value_is_neg(pv) ? -pv->i : pv->i); +{ return (int)(value_is_neg(pv) ? -(int)pv->i : pv->i); } uint uint_value(const pcl_value_t *pv) @@ -27,7 +27,7 @@ float float_value(const pcl_value_t *pv) { return (value_is_float(pv) ? - (value_is_neg(pv) ? -pv->i - pv->fraction : pv->i + pv->fraction) : + (float)(value_is_neg(pv) ? -(int)pv->i - pv->fraction : pv->i + pv->fraction) : (float)int_value(pv)); } pcl_fixed diff --git a/pcl/pcommand.h b/pcl/pcommand.h index 4686d0f2b..d0abff7f2 100644 --- a/pcl/pcommand.h +++ b/pcl/pcommand.h @@ -110,10 +110,10 @@ int pcl_text(P3(const byte *str, uint size, pcl_state_t *pcls)); pcl_command_proc(pcl_plain_char); /* Define error returns. */ -#define e_Range 0 /* ignore range errors */ +#define e_Range (0) /* ignore range errors */ #define e_Syntax (-18) /* gs_error_syntaxerror */ #define e_Memory gs_error_VMerror -#define e_Unimplemented 0 /* ignore unimplemented commands */ +#define e_Unimplemented (105) /* ignore unimplemented commands */ #define e_ExitLanguage (-102) /* e_InterpreterExit */ /* Define a command definition. */ diff --git a/pcl/pcpage.c b/pcl/pcpage.c index 2d9fb9828..af31348d9 100644 --- a/pcl/pcpage.c +++ b/pcl/pcpage.c @@ -285,8 +285,8 @@ pcl_perforation_skip(pcl_args_t *pargs, pcl_state_t *pcls) length and text length and margins to their defaults */ if ( new_skip != pcls->perforation_skip ) { - pcl_top_margin(pcls) = - (top_margin_default > pcls->rotated_page_height ? 0 : + pcl_top_margin(pcls) = + (top_margin_default > pcls->rotated_page_height ? 0 : top_margin_default); reset_text_length(pcls); pcls->perforation_skip = new_skip; diff --git a/pcl/pcprint.c b/pcl/pcprint.c index b7fa9747b..cbb9b515c 100644 --- a/pcl/pcprint.c +++ b/pcl/pcprint.c @@ -82,8 +82,8 @@ pcl_purge_pattern_cache(pcl_state_t *pcls) /* build a pattern and create a dictionary entry for it. Also used by hpgl/2 for raster fills. */ int -pcl_store_user_defined_pattern(pcl_state_t *pcls, pl_dict_t *pattern_dict, - pcl_id_t pattern_id, +pcl_store_user_defined_pattern(pcl_state_t *pcls, pl_dict_t *pattern_dict, + pcl_id_t pattern_id, const byte *data, uint size) { uint height, width; @@ -162,7 +162,7 @@ pcl_user_defined_pattern(pcl_args_t *pargs, pcl_state_t *pcls) if ( count < 8 ) return e_Range; - { int code = pcl_store_user_defined_pattern(pcls, &pcls->patterns, + { int code = pcl_store_user_defined_pattern(pcls, &pcls->patterns, pcls->pattern_id, data, count); diff --git a/pcl/pcrect.c b/pcl/pcrect.c index 6da0cba61..49602754b 100644 --- a/pcl/pcrect.c +++ b/pcl/pcrect.c @@ -56,7 +56,6 @@ pcl_fill_rect_area(pcl_args_t *pargs, pcl_state_t *pcls) if ( code < 0 ) return code; { gs_rect r; - r.p.x = pcls->cap.x; r.p.y = pcls->cap.y; r.q.x = r.p.x + pcls->rectangle.x; diff --git a/pcl/pcsfont.c b/pcl/pcsfont.c index 0c505a768..ba4cc77f1 100644 --- a/pcl/pcsfont.c +++ b/pcl/pcsfont.c @@ -6,6 +6,7 @@ /* PCL5 soft font creation commands */ #include "memory_.h" #include "stdio_.h" /* needed for pl_load_tt_font */ +#include "math_.h" #include "pcommand.h" #include "pcfont.h" #include "pcstate.h" @@ -18,9 +19,6 @@ #include "gxfont.h" #include "gxfont42.h" -/* Import procedures from pcifont.c. */ -extern void pcl_fill_in_intelli_font(P2(gs_font_base *pfont, long unique_id)); - /* Define the downloaded character data formats. */ typedef enum { pccd_bitmap = 4, @@ -28,7 +26,6 @@ typedef enum { pccd_truetype = 15 } pcl_character_format; - /* ------ Internal procedures ------ */ /* Delete a soft font. If it is the currently selected font, or the */ @@ -45,7 +42,7 @@ pcl_delete_soft_font(pcl_state_t *pcls, const byte *key, uint ksize, if ( pcls->font_selection[1].font == value ) pcls->font_selection[1].font = 0; pcls->font = pcls->font_selection[pcls->font_selected].font; - pl_dict_undef(&pcls->soft_fonts, key, ksize); + pl_dict_undef_purge_links(&pcls->soft_fonts, key, ksize); } /* ------ Commands ------ */ @@ -54,6 +51,8 @@ private int /* ESC * c <id> D */ pcl_assign_font_id(pcl_args_t *pargs, pcl_state_t *pcls) { uint id = uint_arg(pargs); id_set_value(pcls->font_id, id); + /* set state to use id's not strings */ + pcls->font_id_type = numeric_id; return 0; } @@ -87,38 +86,57 @@ pcl_font_control(pcl_args_t *pargs, pcl_state_t *pcls) return 0; case 2: { /* Delete soft font <font_id>. */ - pcl_delete_soft_font(pcls, id_key(pcls->font_id), 2, NULL); + pcl_delete_soft_font(pcls, current_font_id, current_font_id_size, NULL); } return 0; case 3: { /* Delete character <font_id, character_code>. */ - if ( pl_dict_find(&pcls->soft_fonts, id_key(pcls->font_id), 2, &value) ) + if ( pl_dict_find(&pcls->soft_fonts, current_font_id, current_font_id_size, &value) ) pl_font_remove_glyph((pl_font_t *)value, pcls->character_code); return 0; } case 4: { /* Make soft font <font_id> temporary. */ - if ( pl_dict_find(&pcls->soft_fonts, id_key(pcls->font_id), 2, &value) ) + if ( pl_dict_find(&pcls->soft_fonts, current_font_id, current_font_id_size, &value) ) ((pl_font_t *)value)->storage = pcds_temporary; } return 0; case 5: { /* Make soft font <font_id> permanent. */ - if ( pl_dict_find(&pcls->soft_fonts, id_key(pcls->font_id), 2, &value) ) + if ( pl_dict_find(&pcls->soft_fonts, current_font_id, current_font_id_size, &value) ) ((pl_font_t *)value)->storage = pcds_permanent; } return 0; case 6: - { /* Assign <font_id> to copy of current font. */ - /* recompute the current font */ + { + int code; + if ( pcls->font == 0 ) + { + code = pcl_recompute_font(pcls); + if ( code < 0 ) + return code; + } + { + pl_font_t *plfont = pl_clone_font(pcls->font, + pcls->memory, + "pcl_font_control()"); + if ( plfont == 0 ) + return_error(e_Memory); + code = gs_definefont(pcls->font_dir, plfont->pfont); + if ( code < 0 ) + return code; + pcl_delete_soft_font(pcls, current_font_id, current_font_id_size, NULL); + plfont->storage = pcds_temporary; + pl_dict_put(&pcls->soft_fonts, current_font_id, current_font_id_size, plfont); + } } - return e_Unimplemented; + return 0; default: return 0; } } -private int /* ESC ) s <count> W */ +private int /* ESC ) s <count> W */ pcl_font_header(pcl_args_t *pargs, pcl_state_t *pcls) { uint count = uint_arg(pargs); const byte *data = arg_data(pargs); @@ -153,7 +171,7 @@ pcl_font_header(pcl_args_t *pargs, pcl_state_t *pcls) return_error(gs_error_invalidfont); } /* Delete any previous font with this ID. */ - pcl_delete_soft_font(pcls, id_key(pcls->font_id), 2, NULL); + pcl_delete_soft_font(pcls, current_font_id, current_font_id_size, NULL); /* Create the generic font information. */ plfont = pl_alloc_font(mem, "pcl_font_header(pl_font_t)"); header = gs_alloc_bytes(mem, count, "pcl_font_header(header)"); @@ -204,9 +222,12 @@ pcl_font_header(pcl_args_t *pargs, pcl_state_t *pcls) pl_fp_set_pitch_cp(&plfont->params, pitch_cp); } - plfont->params.height_4ths = - (uint)(pl_get_uint16(pfh->Height) * 72.0 / plfont->resolution.x + - 0.5); + { + uint height_quarter_dots = pl_get_uint16(pfh->Height); + plfont->params.height_4ths = + (uint)(floor((double)height_quarter_dots * 72.0 / + (double)(plfont->resolution.x) + 0.5)); + } break; } case plfst_TrueType: @@ -262,7 +283,7 @@ pcl_font_header(pcl_args_t *pargs, pcl_state_t *pcls) mem); if ( code < 0 ) return code; - pcl_fill_in_intelli_font(pfont, gs_next_ids(1)); + pl_fill_in_intelli_font(pfont, gs_next_ids(1)); /* pfh->Pitch is design unit width for scalable fonts. */ { uint pitch_cp = pl_get_uint16(pfh->Pitch) * 100 * pfont->FontMatrix.xx; @@ -281,18 +302,19 @@ pcl_font_header(pcl_args_t *pargs, pcl_state_t *pcls) (int)(pfh->StrokeWeight ^ 0x80) - 0x80; plfont->params.typeface_family = (pfh->TypefaceMSB << 8) + pfh->TypefaceLSB; - pl_dict_put(&pcls->soft_fonts, id_key(pcls->font_id), 2, plfont); + pl_dict_put(&pcls->soft_fonts, current_font_id, + current_font_id_size, plfont); plfont->pfont->procs.define_font = gs_no_define_font; return gs_definefont(pcls->font_dir, plfont->pfont); } -private int /* ESC * c <char_code> E */ +private int /* ESC * c <char_code> E */ pcl_character_code(pcl_args_t *pargs, pcl_state_t *pcls) { pcls->character_code = uint_arg(pargs); return 0; } -private int /* ESC ( s <count> W */ +private int /* ESC ( s <count> W */ pcl_character_data(pcl_args_t *pargs, pcl_state_t *pcls) { uint count = uint_arg(pargs); const byte *data = arg_data(pargs); @@ -300,13 +322,16 @@ pcl_character_data(pcl_args_t *pargs, pcl_state_t *pcls) #define plfont ((pl_font_t *)value) pcl_font_header_format_t format; byte *char_data = 0; + uint char_data_size; - if ( !pl_dict_find(&pcls->soft_fonts, id_key(pcls->font_id), 2, &value) ) + if ( !pl_dict_find(&pcls->soft_fonts, current_font_id, + current_font_id_size, &value) ) return 0; /* font not found */ if ( count < 4 || data[2] > count - 2 ) return e_Range; if ( data[1] ) { /**** HANDLE CONTINUATION ****/ + dprintf("continuation not implemented\n"); return e_Unimplemented; } format = ((const pcl_font_header_t *)plfont->header)->HeaderFormat; @@ -340,7 +365,8 @@ pcl_character_data(pcl_args_t *pargs, pcl_state_t *pcls) if ( char_data == 0 ) return_error(e_Memory); memcpy(char_data, data, 16); - memset(char_data + 16, 0, width_bytes * height); + char_data_size = width_bytes * height; + memset(char_data + 16, 0, char_data_size); row = char_data + 16; while ( src < end && y < height ) { /* Read the next compressed row. */ @@ -445,11 +471,153 @@ pcl_character_data(pcl_args_t *pargs, pcl_state_t *pcls) if ( char_data == 0 ) return_error(e_Memory); memcpy(char_data, data, count); + char_data_size = count; } - return pl_font_add_glyph(plfont, pcls->character_code, char_data); + return pl_font_add_glyph(plfont, pcls->character_code, char_data, char_data_size); #undef plfont } +/* template for casting data to command */ +typedef struct alphanumeric_data_s { + byte operation; + byte string_id[512]; +} alphanumeric_data_t; + +private int /* ESC & n <count> W [operation][string ID] */ +pcl_alphanumeric_id_data(pcl_args_t *pargs, pcl_state_t *pcls) +{ + uint count = uint_arg(pargs); + const alphanumeric_data_t *alpha_data = + (const alphanumeric_data_t *)arg_data(pargs); + int string_id_size = (count - 1); /* size of id data size - operation size */ + if ( count == 0 ) + return 0; + if ( count < 1 || count > 512 ) + return e_Range; + switch ( alpha_data->operation ) + { + case 0: + /* Set the current font id to the given string id. */ + { + char *new_id = gs_alloc_bytes(pcls->memory, string_id_size, + "pcl_alphanumeric_id_data"); + if ( new_id == 0 ) + return_error(e_Memory); + /* release the previous id, if necessary */ + if ( pcls->alpha_font_id.size ) + gs_free_object( pcls->memory, + pcls->alpha_font_id.id, + "pcl_free_string_id" ); + /* copy in the new id from the data */ + memcpy(new_id, alpha_data->string_id, string_id_size); + /* set new id and size */ + pcls->alpha_font_id.id = new_id; + pcls->alpha_font_id.size = string_id_size; + /* now set up the state to use string id's */ + pcls->font_id_type = string_id; + } + break; + case 1: + { + /* Associates the current font's font id to the font + with the string id. We simply create an alias entry + for the current font id entry. HAS - FIXME. ... */ + void *value; + if ( !pl_dict_find(&pcls->soft_fonts, + alpha_data->string_id, + string_id_size, + &value) ) + return 0; + pl_dict_put_link(&pcls->soft_fonts, alpha_data->string_id, + string_id_size, current_font_id, + current_font_id_size); + } + break; + case 2: + { + /* Select the fonts referred to by the String ID as + primary. Same as font id selection but uses the + string key instead of a numerical key */ + void *value; + pcl_font_selection_t *pfs = &pcls->font_selection[primary]; + if ( !pl_dict_find(&pcls->soft_fonts, + alpha_data->string_id, + string_id_size, + &value) ) + return 1; + pcl_set_id_parameters(pcls, pfs, (pl_font_t *)value); + pcls->font = pfs->font; + } + break; + case 3: + { + /* same as case 2 but sets secondary font */ + void *value; + pcl_font_selection_t *pfs = &pcls->font_selection[secondary]; + if ( !pl_dict_find(&pcls->soft_fonts, + alpha_data->string_id, + string_id_size, + &value) ) + return 1; + pcl_set_id_parameters(pcls, pfs, (pl_font_t *)value); + } + break; + case 4: + { + /* sets the current macro id to the string id */ + char *new_id = gs_alloc_bytes(pcls->memory, string_id_size, + "pcl_alphanumeric_id_data"); + if ( new_id == 0 ) + return_error(e_Memory); + /* release the previous id, if necessary */ + if ( pcls->alpha_macro_id.size ) + gs_free_object( pcls->memory, + pcls->alpha_macro_id.id, + "pcl_free_string_id" ); + /* copy in the new id from the data */ + memcpy(new_id, alpha_data->string_id, string_id_size); + /* set new id and size */ + pcls->alpha_macro_id.id = new_id; + pcls->alpha_macro_id.size = string_id_size; + /* now set up the state to use string id's */ + pcls->macro_id_type = string_id; + } + break; + case 5: + /* associates current macro id to the supplied string id */ + { + void *value; + if ( !pl_dict_find(&pcls->macros, + alpha_data->string_id, + string_id_size, + &value) ) + return 0; + pl_dict_put_link(&pcls->macros, alpha_data->string_id, string_id_size, + current_macro_id, current_macro_id_size ); + } + break; + case 20: + /* deletes the font association named by the current Font ID */ + if ( pcls->font_id_type == string_id ) + pcl_delete_soft_font(pcls, current_font_id, current_font_id_size, NULL); + break; + case 21: + /* deletes the macro association named the the current macro id */ + if ( pcls->macro_id_type == string_id ) + pl_dict_undef(&pcls->macros, current_macro_id, current_macro_id_size); + break; + case 100: + /* media select */ + /* this is not sufficiently specified in the PCL + comparison guide and interacts with the control panel + so we do not implement it (yet). */ + return e_Unimplemented; + default: + return e_Range; + } + return 0; +} + /* Initialization */ private int pcsfont_do_init(gs_memory_t *mem) @@ -468,18 +636,31 @@ pcsfont_do_init(gs_memory_t *mem) pcl_character_code, pca_neg_error|pca_big_ok) DEFINE_CLASS_COMMAND_ARGS('(', 's', 'W', "Character Data", pcl_character_data, pca_bytes) + DEFINE_CLASS_COMMAND_ARGS('&', 'n', 'W', "Alphanumeric ID Data", + pcl_alphanumeric_id_data, pca_bytes) return 0; } private void pcsfont_do_reset(pcl_state_t *pcls, pcl_reset_type_t type) { if ( type & (pcl_reset_initial | pcl_reset_printer) ) - { id_set_value(pcls->font_id, 0); + { + id_set_value(pcls->font_id, 0); pcls->character_code = 0; + pcls->font_id_type = numeric_id; + pcls->alpha_font_id.size = 0; if ( !(type & pcl_reset_initial) ) { pcl_args_t args; arg_set_uint(&args, 1); /* delete temporary fonts */ pcl_font_control(&args, pcls); } + + } + if ( pcls->alpha_font_id.size ) + { + gs_free_object( pcls->memory, + pcls->alpha_font_id.id, + "pcsfont_do_reset" ); + pcls->alpha_font_id.size = 0; } } private int diff --git a/pcl/pcstate.h b/pcl/pcstate.h index 6fae02ed3..d31333f20 100644 --- a/pcl/pcstate.h +++ b/pcl/pcstate.h @@ -109,6 +109,20 @@ typedef struct pcl_id_s { #define id_set_value(id, val)\ ((id).value = (val), (id).key[0] = (val) >> 8, (id).key[1] = (byte)(val)) +/* type for string id's */ +typedef struct pcl_string_id_s { + byte *id; + int size; +} alphanumeric_string_id_t; + +/* type for current state of id's, string or regular id's macros */ +typedef enum id_type_enum { + string_id, + numeric_id +} id_type_t; + + /* last set id is the id type used */ + /* Define the various types of pattern for filling. */ typedef enum { pcpt_solid_black = 0, @@ -308,9 +322,11 @@ struct pcl_state_s { int line_termination; /* Chapter 8 (pcfont.c) */ - - pcl_font_selection_t font_selection[2]; - int font_selected; /* 0 or 1 */ + pcl_font_selection_t font_selection[3]; + enum { + primary = 0, + secondary = 1, + } font_selected; pl_font_t *font; /* 0 means recompute from params */ pl_dict_t built_in_fonts; /* "built-in", known at start-up */ /* Internal variables */ @@ -345,9 +361,15 @@ struct pcl_state_s { pcl_id_t font_id; uint character_code; pl_dict_t soft_fonts; + /* PCL comparison guide - alphanumeric string id */ + alphanumeric_string_id_t alpha_font_id; + id_type_t font_id_type; +#define current_font_id (((pcls->font_id_type == string_id) ?\ + (pcls->alpha_font_id.id) : (id_key(pcls->font_id)))) +#define current_font_id_size (((pcls->font_id_type == string_id) ?\ + (pcls->alpha_font_id.size) : (2))) /* Chapter 12 (pcmacros.c) */ - pcl_id_t macro_id; pcl_id_t overlay_macro_id; bool overlay_enabled; @@ -357,6 +379,12 @@ struct pcl_state_s { pcl_state_t *saved; /* saved state during execute/call/overlay */ /* Internal variables */ byte *macro_definition; /* for macro being defined, if any */ + alphanumeric_string_id_t alpha_macro_id; + id_type_t macro_id_type; +#define current_macro_id (((pcls->macro_id_type == string_id) ?\ + (pcls->alpha_macro_id.id) : (id_key(pcls->macro_id)))) +#define current_macro_id_size (((pcls->macro_id_type == string_id) ?\ + (pcls->alpha_macro_id.size) : (2))) /* Chapter 13 (pcprint.c) */ @@ -370,6 +398,7 @@ struct pcl_state_s { pl_dict_t patterns; /* Internal variables */ pcl_id_t current_pattern_id; /* at last select_pattern */ + bool pattern_set; /* true if pattern set in graphics state */ gx_ht_tile pattern_tile; /* set by pcl_set_drawing_color */ gs_pattern_instance *cached_shading[7*4]; /* create as needed, */ /* 1 per rotation */ diff --git a/pcl/pcstatus.c b/pcl/pcstatus.c index af00d05a9..e4598b86b 100644 --- a/pcl/pcstatus.c +++ b/pcl/pcstatus.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997 Aladdin Enterprises. All rights reserved. +/* Copyright (C) 1996 Aladdin Enterprises. All rights reserved. Unauthorized use, copying, and/or distribution prohibited. */ @@ -8,9 +8,6 @@ #include "stdio_.h" #include <stdarg.h> /* how to make this portable? */ #include "string_.h" -#include "gsmemory.h" /* for gxdevice.h */ -#include "gstypes.h" /* ditto */ -#include "gxdevice.h" /* for gs_memory_default, if needed */ #include "pcommand.h" #include "pcstate.h" #include "pcfont.h" @@ -499,19 +496,19 @@ private int (*status_write[])(P3(stream *s, const pcl_state_t *pcls, /* Commands */ -private int /* ESC * s <enum> T */ +private int /* ESC * s <enum> T */ pcl_set_readback_loc_type(pcl_args_t *pargs, pcl_state_t *pcls) { pcls->location_type = uint_arg(pargs); return 0; } -private int /* ESC * s <enum> U */ +private int /* ESC * s <enum> U */ pcl_set_readback_loc_unit(pcl_args_t *pargs, pcl_state_t *pcls) { pcls->location_unit = uint_arg(pargs); return 0; } -private int /* ESC * s <enum> I */ +private int /* ESC * s <enum> I */ pcl_inquire_readback_entity(pcl_args_t *pargs, pcl_state_t *pcls) { uint i = uint_arg(pargs); int unit = pcls->location_unit; @@ -597,7 +594,7 @@ pcl_inquire_readback_entity(pcl_args_t *pargs, pcl_state_t *pcls) return 0; } -private int /* ESC * s 1 M */ +private int /* ESC * s 1 M */ pcl_free_space(pcl_args_t *pargs, pcl_state_t *pcls) { stream st; @@ -625,7 +622,7 @@ pcl_free_space(pcl_args_t *pargs, pcl_state_t *pcls) return 0; } -private int /* ESC & r <bool> F */ +private int /* ESC & r <bool> F */ pcl_flush_all_pages(pcl_args_t *pargs, pcl_state_t *pcls) { switch ( uint_arg(pargs) ) { @@ -643,7 +640,7 @@ pcl_flush_all_pages(pcl_args_t *pargs, pcl_state_t *pcls) } } -private int /* ESC * s <int_id> X */ +private int /* ESC * s <int_id> X */ pcl_echo(pcl_args_t *pargs, pcl_state_t *pcls) { stream st; diff --git a/pcl/pcsymbol.c b/pcl/pcsymbol.c index 362ecb2e7..44f761f43 100644 --- a/pcl/pcsymbol.c +++ b/pcl/pcsymbol.c @@ -12,14 +12,14 @@ #include "pcsymbol.h" -private int /* ESC * c <id> R */ +private int /* ESC * c <id> R */ pcl_symbol_set_id_code(pcl_args_t *pargs, pcl_state_t *pcls) { uint id = uint_arg(pargs); id_set_value(pcls->symbol_set_id, id); return 0; } -private int /* ESC ( f <count> W */ +private int /* ESC ( f <count> W */ pcl_define_symbol_set(pcl_args_t *pargs, pcl_state_t *pcls) { uint count = uint_arg(pargs); const pl_symbol_map_t *psm = (pl_symbol_map_t *)arg_data(pargs); @@ -99,7 +99,7 @@ pcl_define_symbol_set(pcl_args_t *pargs, pcl_state_t *pcls) return 0; } -private int /* ESC * c <ssc_enum> S */ +private int /* ESC * c <ssc_enum> S */ pcl_symbol_set_control(pcl_args_t *pargs, pcl_state_t *pcls) { gs_const_string key; void *value; diff --git a/pcl/pctext.c b/pcl/pctext.c index b226da656..5a2a215c0 100644 --- a/pcl/pctext.c +++ b/pcl/pctext.c @@ -5,11 +5,13 @@ /* pctext.c */ /* PCL5 text printing commands */ #include "std.h" +#include "stdio_.h" #include "plvalue.h" #include "pcommand.h" #include "pcstate.h" #include "pcdraw.h" #include "pcfont.h" +#include "gdebug.h" #include "gscoord.h" #include "gsline.h" #include "gspaint.h" @@ -40,9 +42,12 @@ pcl_map_symbol(uint chr, const gs_show_enum *penum) const pl_symbol_map_t *psm = pfs->map; uint first_code, last_code; - if ( psm == 0 ) - { /* Hack: bound TrueType fonts are indexed from 0xf000. */ - if ( pfs->font->scaling_technology == plfst_TrueType ) + /* if there is not symbol map we assume the the character + implicitly indexes the font. */ + if ( psm == 0 ) + { + if ( (pfs->font->scaling_technology == plfst_TrueType) && + (pfs->font->storage == pcds_internal) ) return chr + 0xf000; return chr; } @@ -71,7 +76,11 @@ pcl_next_char(const gs_const_string *pstr, uint *pindex, p = pstr->data + i; if ( pcl_char_is_2_byte(*p, tpm) ) { if ( i + 1 >= size ) - return -1; + { + *pindex = size; + *pchr = *p; + return 0; + } *pchr = (*p << 8) + p[1]; *pindex = i + 2; } else { @@ -80,49 +89,34 @@ pcl_next_char(const gs_const_string *pstr, uint *pindex, } return 0; } + private int pcl_next_char_proc(gs_show_enum *penum, gs_char *pchr) { const pcl_state_t *pcls = gs_state_client_data(penum->pgs); int code = pcl_next_char(&penum->str, &penum->index, pcls->text_parsing_method, pchr); - uint mapped_char; - if ( code ) return code; - mapped_char = pcl_map_symbol(*pchr, penum); - /* - * Undefined characters should print as spaces. - * We don't currently have any fallback if the symbol set - * doesn't include the space character at position ' ', - * or if the font doesn't include the space character. - * If it turns out that undefined characters should print as a - * space control code (with possibly modified HMI), we'll have to - * do something more complicated in pcl_text and pcl_show_chars. - * - * Checking whether a font includes a character is expensive. - * We'll have to find a better way to do this eventually. - */ - { const pl_font_t *plfont = + /* get symbol table value */ + *pchr = pcl_map_symbol(*pchr, penum); + /* don't need to look up undefined values */ + if ( *pchr == 0xffff ) + return 0; + { + const pl_font_t *plfont = (const pl_font_t *)(gs_currentfont(penum->pgs)->client_data); gs_matrix ignore_mat; - - if ( !pl_font_includes_char(plfont, NULL, &ignore_mat, mapped_char) - ) - mapped_char = 0xffff; + if ( !pl_font_includes_char(plfont, NULL, &ignore_mat, *pchr) + ) + /* HAS. we should differentiate between unmapped + characters and characters not found in the font to + avoid extra work in pcl_show_chars() */ + *pchr = 0xffff; } - if ( mapped_char == 0xffff ) - mapped_char = pcl_map_symbol(' ', penum); - *pchr = mapped_char; return 0; } -/* Show a string, possibly substituting a modified HMI for all characters */ -/* or only the space character. */ -typedef enum { - char_adjust_none, - char_adjust_space, - char_adjust_all -} pcl_char_adjust_t; + private int pcl_char_width(gs_show_enum *penum, gs_state *pgs, byte chr, gs_point *ppt) { int code = gs_stringwidth_n_init(penum, pgs, &chr, 1); @@ -131,16 +125,40 @@ pcl_char_width(gs_show_enum *penum, gs_state *pgs, byte chr, gs_point *ppt) gs_show_width(penum, ppt); return 0; } + +private void +pcl_set_gs_font(pcl_state_t *pcls) +{ + gs_font *pfont = (gs_font *)pcls->font->pfont; + pfont->procs.next_char = pcl_next_char_proc; + gs_setfont(pcls->pgs, pfont); +} + +/* restores a font after symbol set substitution */ +private int +pcl_restore_font(pcl_state_t *pcls, + pcl_font_selection_t *original_font) +{ + pcl_font_selection_t *pfp = &pcls->font_selection[pcls->font_selected]; + int code; + pcl_decache_font(pcls, pcls->font_selected); + pfp = original_font; + code = pcl_recompute_font(pcls); + if ( code < 0 ) + return code; + pcl_set_gs_font(pcls); + return 0; +} + + private int pcl_show_chars(gs_show_enum *penum, pcl_state_t *pcls, const gs_point *pscale, - pcl_char_adjust_t adjust, const byte *str, uint size) + const byte *str, uint size, gs_point *last_width) { gs_state *pgs = pcls->pgs; - int code; - floatp scaled_hmi = pcl_hmi(pcls) / pscale->x; - floatp diff; floatp limit = (pcl_right_margin(pcls) + 0.5) / pscale->x; gs_rop3_t rop = gs_currentrasterop(pgs); floatp gray = gs_currentgray(pgs); + pcl_font_selection_t *pfp = &pcls->font_selection[pcls->font_selected]; gs_rop3_t effective_rop = (gray == 1.0 ? rop3_know_T_1(rop) : gray == 0.0 ? rop3_know_T_0(rop) : rop); @@ -148,260 +166,278 @@ pcl_show_chars(gs_show_enum *penum, pcl_state_t *pcls, const gs_point *pscale, bool opaque = !source_transparent && rop3_know_S_0(effective_rop) != rop3_D; bool wrap = pcls->end_of_line_wrap; - bool clip = pcls->check_right_margin; - - /* Compute any width adjustment. */ - switch ( adjust ) - { - case char_adjust_none: - break; - case char_adjust_space: - { gs_point space_width; - - /* Find the actual width of the space character. */ - pcl_char_width(penum, pgs, ' ', &space_width); - diff = scaled_hmi - space_width.x; - } - break; - case char_adjust_all: - { gs_point char_width; - - /* Find some character that is defined in the font. */ - /****** WRONG -- SHOULD GET IT SOMEWHERE ELSE ******/ - { byte chr; - for ( chr = ' '; ; ++chr ) - { pcl_char_width(penum, pgs, chr, &char_width); - if ( char_width.x != 0 ) - break; + uint i, ci; + gs_char chr, mapped_chr; + gs_const_string gstr; + gstr.data = str; + gstr.size = size; + for ( i = ci = 0; + !pcl_next_char(&gstr, &i, pcls->text_parsing_method, &chr); + ci = i + ) + { gs_point width; + gs_point move, start; + bool substitute_font = false; + pcl_font_selection_t saved_font; + int code; + bool have_char = true; + gs_currentpoint(pgs, &start); + move = start; + gs_show_n_init(penum, pgs, str + ci, i - ci); + pcl_next_char_proc(penum, &mapped_chr); + /* HAS not good because mapped 0xffff can mean undefined + entry in symbol table or "glyph not found in + font". Check symbol table first? (HAS) We only + substitute for unbound fonts */ + if ( mapped_chr == 0xffff ) + { + uint mapped_chr2 = (uint)pcl_map_symbol(chr, penum); + saved_font = *pfp; + if ( !pfp->map ) + have_char = false; + else + { + pcl_decache_font(pcls, pcls->font_selected); + /* select courier */ + code = pcl_recompute_substitute_font(pcls, mapped_chr2); + /* character not in the font repoitore? */ + if ( code < 0 ) + { + *pfp = saved_font; + code = pcl_recompute_font(pcls); + if ( code < 0 ) + return code; + have_char = false; + substitute_font = false; + } + else + { + /* found a font with the glyph */ + substitute_font = true; + have_char = true; + } + pcl_set_gs_font(pcls); + code = gs_show_n_init(penum, pgs, str + ci, i - ci); + if ( code < 0 ) + return code; + code = pcl_next_char_proc(penum, &mapped_chr); + if ( code < 0 ) + return code; } - diff = scaled_hmi - char_width.x; } + + /* use the character width for proportionally spaced + printable characters otherwise use hmi, with one + exception: if hmi is set explicitly the space character + uses scaled hmi FTS panel 41 */ + { + floatp scaled_hmi = pcl_hmi(pcls) / pscale->x; + if ( pfp->params.proportional_spacing && have_char ) + { + if ( str[ci] == ' ' && (pcls->hmi_set == hmi_set_explicitly) ) + width.x = scaled_hmi; + else + { + code = pcl_char_width(penum, pgs, chr, &width); + if ( code < 0 ) + return code; + } + } + else + width.x = scaled_hmi; } - break; - } - /* - * Note that TRM 24-13 states (badly) that wrapping only - * occurs when *crossing* the right margin: if the cursor - * is initially to the right of the margin, wrapping does - * not occur. - * - * If characters are opaque (i.e., affect the part of their - * bounding box that is outside their actual shape), we have to - * do quite a bit of extra work. This "feature" is a pain! - */ - if ( clip ) - { - /* - * If end-of-line wrap is enabled, or characters are opaque, - * we must render one character at a time. (It's a good thing - * this is used primarily for diagnostics and contrived tests.) - */ - uint i, ci; - gs_char chr; - gs_const_string gstr; - - gstr.data = str; - gstr.size = size; - for ( i = ci = 0; - !pcl_next_char(&gstr, &i, pcls->text_parsing_method, &chr); - ci = i - ) - { gs_point width; - floatp move; - gs_point pt; - - if ( adjust == char_adjust_all || - (chr == ' ' && adjust == char_adjust_space) - ) - { width.x = scaled_hmi; - move = diff; + move.x += width.x; + if ( (move.x > limit) && pcls->check_right_margin ) + { + if ( wrap ) + { + gs_point new_line_coord; + pcl_do_CR(pcls); + pcl_do_LF(pcls); + pcls->check_right_margin = true; /* CR/LF reset this */ + gs_moveto(pgs, pcls->cap.x / pscale->x, + pcls->cap.y / pscale->y); + gs_currentpoint(pgs, &new_line_coord); + /* move - start is the advance width */ + move.x = (move.x - start.x) + new_line_coord.x; + move.y = new_line_coord.y; } else - { pcl_char_width(penum, pgs, chr, &width); - move = 0.0; - } - gs_currentpoint(pgs, &pt); - /* - * Check for end-of-line wrap. - * Compensate for the fact that everything is scaled. - * We should really handle this by scaling the font.... - * We need a little fuzz to handle rounding inaccuracies. - */ - if ( pt.x + width.x > limit ) - { - if ( wrap ) - { - pcl_do_CR(pcls); - pcl_do_LF(pcls); - pcls->check_right_margin = true; /* CR/LF reset this */ - gs_moveto(pgs, pcls->cap.x / pscale->x, - pcls->cap.y / pscale->y); - } - else + { + if ( substitute_font ) { - return 0; + code = pcl_restore_font(pcls, &saved_font); + if ( code < 0 ) + return code; } + /* crossed the right margin, nothing else to do */ + return 0; } - if ( opaque ) + } + + if ( opaque ) + { /* + * We have to handle bitmap and outline characters + * differently. For outlines, we construct the path, + * then use eofill to process the inside and outside + * separately. For bitmaps, we do the rendering + * ourselves, replacing the BuildChar procedure. + * What a nuisance! + */ + gs_font *pfont = gs_currentfont(penum->pgs); + const pl_font_t *plfont = + (const pl_font_t *)(pfont->client_data); + gs_rop3_t background_rop = rop3_know_S_1(effective_rop); + + if ( plfont->scaling_technology == plfst_bitmap ) { /* - * We have to handle bitmap and outline characters - * differently. For outlines, we construct the path, - * then use eofill to process the inside and outside - * separately. For bitmaps, we do the rendering - * ourselves, replacing the BuildChar procedure. - * What a nuisance! + * It's too much work to handle all cases right. + * Do the right thing in the two common ones: + * where the background is unchanged, or where + * the foreground doesn't depend on the previous + * state of the destination. */ - gs_font *pfont = gs_currentfont(penum->pgs); - const pl_font_t *plfont = - (const pl_font_t *)(pfont->client_data); - gs_rop3_t background_rop = rop3_know_S_1(effective_rop); - - if ( plfont->scaling_technology == plfst_bitmap ) + gs_point pt; + + gs_gsave(pgs); + gs_setfilladjust(pgs, 0.0, 0.0); + /* + * Here's where we take the shortcut: if the + * current RasterOp is such that the background is + * actually affected, affect the entire bounding + * box of the character, not just the part outside + * the glyph. + */ + if ( background_rop != rop3_D ) { /* - * It's too much work to handle all cases right. - * Do the right thing in the two common ones: - * where the background is unchanged, or where - * the foreground doesn't depend on the previous - * state of the destination. + * Fill the bounding box. We get this by + * actually digging into the font structure. + * Someday this should probably be a pl library + * procedure. */ - gs_point pt; - - gs_gsave(pgs); - gs_setfilladjust(pgs, 0.0, 0.0); - /* - * Here's where we take the shortcut: if the - * current RasterOp is such that the background is - * actually affected, affect the entire bounding - * box of the character, not just the part outside - * the glyph. - */ - if ( background_rop != rop3_D ) - { /* - * Fill the bounding box. We get this by - * actually digging into the font structure. - * Someday this should probably be a pl library - * procedure. - */ - gs_char chr; - gs_glyph glyph; - const byte *cdata; - - gs_show_n_init(penum, pgs, str + ci, 1); - pcl_next_char_proc(penum, &chr); - glyph = (*pfont->procs.encode_char) - (penum, pfont, &chr); - cdata = pl_font_lookup_glyph(plfont, glyph)->data; - if ( cdata != 0 ) - { const byte *params = cdata + 6; - int lsb = pl_get_int16(params); - int ascent = pl_get_int16(params + 2); - int width = pl_get_uint16(params + 4); - int height = pl_get_uint16(params + 6); - gs_rect bbox; - - gs_currentpoint(pgs, &pt); - bbox.p.x = pt.x + lsb; - bbox.p.y = pt.y - ascent; - bbox.q.x = bbox.p.x + width; - bbox.q.y = bbox.p.y + height; - gs_gsave(pgs); - gs_setrasterop(pgs, background_rop); - gs_rectfill(pgs, &bbox, 1); - gs_grestore(pgs); - } + gs_char chr; + gs_glyph glyph; + const byte *cdata; + + gs_show_n_init(penum, pgs, str + ci, i - ci); + pcl_next_char_proc(penum, &chr); + glyph = (*pfont->procs.encode_char) + (penum, pfont, &chr); + cdata = pl_font_lookup_glyph(plfont, glyph)->data; + if ( cdata != 0 ) + { const byte *params = cdata + 6; + int lsb = pl_get_int16(params); + int ascent = pl_get_int16(params + 2); + int width = pl_get_uint16(params + 4); + int height = pl_get_uint16(params + 6); + gs_rect bbox; + + gs_currentpoint(pgs, &pt); + bbox.p.x = pt.x + lsb; + bbox.p.y = pt.y - ascent; + bbox.q.x = bbox.p.x + width; + bbox.q.y = bbox.p.y + height; + gs_gsave(pgs); + gs_setrasterop(pgs, background_rop); + gs_rectfill(pgs, &bbox, 1); + gs_grestore(pgs); } - /* Now do the foreground. */ - gs_show_n_init(penum, pgs, str + ci, 1); - code = gs_show_next(penum); - if ( code < 0 ) - return code; - gs_currentpoint(pgs, &pt); - gs_grestore(pgs); - gs_moveto(pgs, pt.x, pt.y); - } - else - { gs_point pt; - gs_rect bbox; - - gs_gsave(pgs); - gs_currentpoint(pgs, &pt); - gs_newpath(pgs); - gs_moveto(pgs, pt.x, pt.y); - /* Don't allow pixels to be processed twice. */ - gs_setfilladjust(pgs, 0.0, 0.0); - gs_charpath_n_init(penum, pgs, str + ci, 1, true); - code = gs_show_next(penum); - if ( code < 0 ) - { gs_grestore(pgs); - return code; - } - gs_currentpoint(pgs, &pt); /* save end point */ - /* Handle the outside of the path. */ - gs_gsave(pgs); - gs_pathbbox(pgs, &bbox); - gs_rectappend(pgs, &bbox, 1); - gs_setrasterop(pgs, background_rop); - gs_eofill(pgs); - gs_grestore(pgs); - /* Handle the inside of the path. */ - gs_fill(pgs); - gs_grestore(pgs); - gs_moveto(pgs, pt.x, pt.y); } + /* Now do the foreground. */ + gs_show_n_init(penum, pgs, str + ci, i - ci); + code = gs_show_next(penum); + if ( code < 0 ) + return code; + gs_currentpoint(pgs, &pt); + gs_grestore(pgs); + gs_moveto(pgs, pt.x, pt.y); } else - { gs_show_n_init(penum, pgs, str + ci, 1); + { gs_point pt; + gs_rect bbox; + + gs_gsave(pgs); + gs_currentpoint(pgs, &pt); + gs_newpath(pgs); + gs_moveto(pgs, pt.x, pt.y); + /* Don't allow pixels to be processed twice. */ + gs_setfilladjust(pgs, 0.0, 0.0); + gs_charpath_n_init(penum, pgs, str + ci, i - ci, true); code = gs_show_next(penum); if ( code < 0 ) + { gs_grestore(pgs); + return code; + } + gs_currentpoint(pgs, &pt); /* save end point */ + /* Handle the outside of the path. */ + gs_gsave(pgs); + gs_pathbbox(pgs, &bbox); + gs_rectappend(pgs, &bbox, 1); + gs_setrasterop(pgs, background_rop); + gs_eofill(pgs); + gs_grestore(pgs); + /* Handle the inside of the path. */ + gs_fill(pgs); + gs_grestore(pgs); + gs_moveto(pgs, pt.x, pt.y); + } + } + else + { + if ( have_char ) + { + gs_matrix fmat; + gs_currentmatrix(pgs, &fmat); + if ( (pcls->text_path == -1) && ((i - ci) == 2) ) + { + gs_rotate(pgs, 90); + move.x += width.x; /* hack */ + } + code = gs_show_n_init(penum, pgs, str + ci, i - ci); + if ( code < 0 ) return code; + code = gs_show_next(penum); + if ( code < 0 ) + return code; + gs_setmatrix(pgs, &fmat); } - if ( move != 0 ) - gs_rmoveto(pgs, move, 0.0); + gs_moveto(pgs, move.x, move.y); } - return 0; - } - switch ( adjust ) - { - case char_adjust_none: - code = gs_show_n_init(penum, pgs, str, size); - break; - case char_adjust_space: - code = gs_widthshow_n_init(penum, pgs, diff, 0.0, ' ', str, size); - break; - case char_adjust_all: - code = gs_ashow_n_init(penum, pgs, diff, 0.0, str, size); - break; + if ( substitute_font ) + { + code = pcl_restore_font(pcls, &saved_font); + if ( code < 0 ) + return code; + substitute_font = false; + } + + { + /* set the last character width for backspace. Could be + moved outside the loop HAS */ + gs_point last_pt; + gs_currentpoint(pgs, &last_pt); + last_width->x = last_pt.x - start.x; + last_width->y = last_pt.y - start.y; + } } - if ( code < 0 ) - return code; - return gs_show_next(penum); + return 0; } -/* Commands */ - int pcl_text(const byte *str, uint size, pcl_state_t *pcls) { gs_memory_t *mem = pcls->memory; gs_state *pgs = pcls->pgs; gs_show_enum *penum; - gs_matrix user_ctm, font_ctm, font_only_mat; - pcl_font_selection_t *pfp; - coord_point initial; - gs_point gs_width; + gs_matrix user_ctm, font_ctm; + gs_point last_width; gs_point scale; int scale_sign; - pcl_char_adjust_t adjust = char_adjust_none; - int code = 0; - gs_const_string gstr; - const pcl_text_parsing_method_t *tpm = pcls->text_parsing_method; - uint index = 0; - + int code; if ( pcls->font == 0 ) { code = pcl_recompute_font(pcls); if ( code < 0 ) return code; } - pfp = &pcls->font_selection[pcls->font_selected]; /**** WE COULD CACHE MORE AND DO LESS SETUP HERE ****/ pcl_set_graphics_state(pcls, true); /* @@ -421,11 +457,7 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) &pcls->current_pattern_id); if ( code < 0 ) return code; - { gs_font *pfont = (gs_font *)pcls->font->pfont; - - pfont->procs.next_char = pcl_next_char_proc; - gs_setfont(pgs, pfont); - } + pcl_set_gs_font(pcls); penum = gs_show_enum_alloc(mem, pgs, "pcl_plain_char"); if ( penum == 0 ) return_error(e_Memory); @@ -449,6 +481,7 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) * it must be scaled by pitch, not by height, relative to * the nominal pitch of the outline. */ + pcl_font_selection_t *pfp = &pcls->font_selection[pcls->font_selected]; if ( pfp->params.proportional_spacing ) scale.x = scale.y = pfp->params.height_4ths * 0.25 * inch2coord(1.0/72); @@ -463,9 +496,6 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) scale_sign = -1; } - gstr.data = str; - gstr.size = size; - /* If floating underline is on, since we're about to print a real * character, track the best-underline position. * XXX Until we have the font's design value for underline position, @@ -478,7 +508,6 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) if ( yu > pcls->underline_position ) pcls->underline_position = yu; } - /* Keep copies of both the user-space CTM and the font-space * (font scale factors * user space) CTM because we flip back and * forth to deal with effect of past backspace and holding info @@ -492,114 +521,23 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) scale.y *= scale_sign; gs_scale(pgs, scale.x, scale.y); gs_currentmatrix(pgs, &font_ctm); - - /* - * If this is a fixed-pitch font and we have an explicitly set HMI, - * override the HMI. - */ - if ( !pcls->font->params.proportional_spacing ) - { if ( pcls->hmi_set == hmi_set_explicitly ) - adjust = char_adjust_all; - } - else - { /* - * If the string has any spaces and the font doesn't - * define the space character or hmi has been explicitly - * set we have to do something special. (required by - * Genoa FTS panel 40). - */ - uint i; - gs_char chr; - - for ( i = 0; !pcl_next_char(&gstr, &i, tpm, &chr); ) - if ( chr == ' ' ) - { if ( (!pl_font_includes_char(pcls->font, pcls->map, &font_ctm, ' ')) || - (pcls->hmi_set == hmi_set_explicitly) ) - adjust = char_adjust_space; - break; - } - } - - /* Overstrike-center if needed. Enter here in font space. */ - if ( pcls->last_was_BS ) - { - coord_point prev = pcls->cap; - coord_point this_width, delta_BS; - gs_char chr; - - if ( pcl_next_char(&gstr, &index, tpm, &chr) != 0 ) - return 0; - /* Scale the width only by the font part of transformation so - * it ends up in PCL coordinates. */ - gs_make_scaling(scale.x, scale.y, &font_only_mat); - if ( (code = pl_font_char_width(pcls->font, pcls->map, - &font_only_mat, chr, &gs_width)) != 0 ) - { - /* BS followed by an undefined character. Treat as a space. */ - if ( (code = pl_font_char_width(pcls->font, pcls->map, - &font_only_mat, ' ', &gs_width)) != 0 ) - goto x; - } - - this_width.x = gs_width.x; /* XXX just swapping types??? */ - this_width.y = gs_width.y; - delta_BS = this_width; /* in case just 1 char */ - initial.x = prev.x + (pcls->last_width.x - this_width.x) / 2; - initial.y = prev.y + (pcls->last_width.y - this_width.y) / 2; - if ( initial.x != 0 || initial.y != 0 ) - { - gs_setmatrix(pgs, &user_ctm); - gs_moveto(pgs, initial.x, initial.y); - gs_setmatrix(pgs, &font_ctm); - } - if ( (code = pcl_show_chars(penum, pcls, &scale, adjust, str, 1)) != 0 ) - goto x; - /* Now reposition to "un-backspace", *regardless* of the - * escapement of the character we just printed. */ - pcls->cap.x = prev.x + pcls->last_width.x; - pcls->cap.y = prev.y + pcls->last_width.y; - gs_setmatrix(pgs, &user_ctm); - gs_moveto(pgs, pcls->cap.x, pcls->cap.y); - gs_setmatrix(pgs, &font_ctm); - pcls->last_width = delta_BS; - } - /* Print remaining characters. Enter here in font space. */ - /****** FOLLOWING IS WRONG FOR DOUBLE-BYTE CHARS ******/ - if ( index < size ) - { gs_point pt; - if ( size - index > 1 ) - { - if ( (code = pcl_show_chars(penum, pcls, &scale, adjust, - str + index, - size - index - 1)) != 0 - ) - goto x; - index = size - 1; - } - - /* Print remaining characters. Note that pcls->cap may be out - * of sync here. */ - gs_setmatrix(pgs, &user_ctm); - gs_currentpoint(pgs, &pt); - initial.x = pt.x; - initial.y = pt.y; - gs_setmatrix(pgs, &font_ctm); - if ( (code = pcl_show_chars(penum, pcls, &scale, adjust, - str + index, size - index)) != 0 - ) - goto x; - gs_setmatrix(pgs, &user_ctm); - gs_currentpoint(pgs, &pt); - pcls->cap.x = pt.x; - pcls->cap.y = pt.y; - pcls->last_width.x = pcls->cap.x - initial.x; - pcls->last_width.y = pcls->cap.y - initial.y; - } + code = pcl_show_chars(penum, pcls, &scale, str, size, &last_width); + if ( code < 0 ) + goto x; + gs_setmatrix(pgs, &user_ctm); + { + gs_point pt; + gs_currentpoint(pgs, &pt); + pcls->cap.x = pt.x; + pcls->cap.y = pt.y; + } + pcls->last_width.x = last_width.x * scale.x; + pcls->last_width.y = last_width.y * scale.y; x: if ( code > 0 ) /* shouldn't happen */ code = gs_note_error(gs_error_invalidfont); if ( code < 0 ) - gs_show_enum_release(penum, mem); + gs_show_enum_release(penum, mem); else gs_free_object(mem, penum, "pcl_plain_char"); pcls->have_page = true; diff --git a/pcl/pgchar.c b/pcl/pgchar.c index 32abbcd0c..91af7792a 100644 --- a/pcl/pgchar.c +++ b/pcl/pgchar.c @@ -362,7 +362,7 @@ hpgl_SB(hpgl_args_t *pargs, hpgl_state_t *pgls) * disallowed. */ for ( i = 0; i < countof(pgls->g.font_selection); ++i ) - { pcl_font_selection_t *pfs = &pgls->font_selection[i]; + { pcl_font_selection_t *pfs = &pgls->g.font_selection[i]; if ( !pfs->selected_by_id || (!mode && pfs->font != 0 && pfs->font->scaling_technology == plfst_bitmap) diff --git a/pcl/pgconfig.c b/pcl/pgconfig.c index 3f63d2af8..44d420450 100644 --- a/pcl/pgconfig.c +++ b/pcl/pgconfig.c @@ -51,63 +51,70 @@ hpgl_CO(hpgl_args_t *pargs, hpgl_state_t *pgls) /* DF; sets programmable features except P1 and P2 */ int hpgl_DF(hpgl_args_t *pargs, hpgl_state_t *pgls) -{ - hpgl_args_t args; - -#define hpgl_do_command(hpgl_xx)\ - hpgl_args_setup(&args);\ - hpgl_xx(&args, pgls) -#define hpgl_do_int_command(hpgl_xx, intv)\ - hpgl_args_set_int(&args, intv);\ - hpgl_xx(&args, pgls) - - hpgl_do_command(hpgl_AC); - hpgl_do_command(hpgl_AD); - hpgl_do_command(hpgl_CF); - +{ hpgl_args_t args; + hpgl_args_setup(&args); + hpgl_AC(&args, pgls); + hpgl_args_setup(&args); + hpgl_AD(&args, pgls); + hpgl_args_setup(&args); + hpgl_SD(&args, pgls); + hpgl_args_setup(&args); + hpgl_CF(&args, pgls); hpgl_args_setup(&args); hpgl_args_add_int(&args, 1); hpgl_args_add_int(&args, 0); hpgl_DI(&args, pgls); - /* HAS -- Figure out some way to do this so that it is consistant */ pgls->g.label.terminator = 3; pgls->g.label.print_terminator = false; - - hpgl_do_command(hpgl_DV); - hpgl_do_command(hpgl_ES); - hpgl_do_command(hpgl_FT); - hpgl_do_command(hpgl_IW); - hpgl_do_command(hpgl_LA); - hpgl_do_command(hpgl_LM); - hpgl_do_int_command(hpgl_LO, 1); - hpgl_do_command(hpgl_LT); - + hpgl_args_setup(&args); + hpgl_DV(&args, pgls); + hpgl_args_setup(&args); + hpgl_ES(&args, pgls); + hpgl_args_setup(&args); + hpgl_FT(&args, pgls); + hpgl_args_setup(&args); + hpgl_IW(&args, pgls); + hpgl_args_setup(&args); + hpgl_LA(&args, pgls); + hpgl_args_setup(&args); + hpgl_LM(&args, pgls); + hpgl_args_set_int(&args, 1); + hpgl_LO(&args, pgls); + hpgl_args_setup(&args); + hpgl_LT(&args, pgls); /* we do this instead of calling SC directly */ pgls->g.scaling_type = hpgl_scaling_none; - - hpgl_do_int_command(hpgl_PM, 0); - hpgl_do_int_command(hpgl_PM, 2); - hpgl_do_command(hpgl_RF); - hpgl_do_int_command(hpgl_SB, 0); - hpgl_do_command(hpgl_SV); - hpgl_do_command(hpgl_SD); - hpgl_do_command(hpgl_SI); - hpgl_do_command(hpgl_SL); - + hpgl_args_set_int(&args,0); + hpgl_PM(&args, pgls); + hpgl_args_set_int(&args,2); + hpgl_PM(&args, pgls); + hpgl_args_setup(&args); + hpgl_RF(&args, pgls); + hpgl_args_set_int(&args,0); + hpgl_SB(&args, pgls); + hpgl_args_setup(&args); + hpgl_SV(&args, pgls); + hpgl_args_setup(&args); + hpgl_SI(&args, pgls); + hpgl_args_setup(&args); + hpgl_SL(&args, pgls); /* HAS needs to be consistant */ pgls->g.symbol_mode = 0; /* hpgl_args_setup(&args); hpgl_SM(&args, pgls); */ - - hpgl_do_command(hpgl_SS); - hpgl_do_int_command(hpgl_TR, 1); - hpgl_do_command(hpgl_TD); - hpgl_do_command(hpgl_UL); - hpgl_do_command(hpgl_MC); - hpgl_do_command(hpgl_PP); -#undef hpgl_do_command -#undef hpgl_do_int_command + hpgl_args_setup(&args); + hpgl_SS(&args, pgls); + hpgl_args_set_int(&args,1); + hpgl_TR(&args, pgls); + hpgl_args_setup(&args); + hpgl_TD(&args, pgls); + hpgl_args_setup(&args); + hpgl_UL(&args, pgls); + hpgl_args_setup(&args); + hpgl_MC(&args, pgls); + hpgl_args_setup(&args); + hpgl_PP(&args, pgls); return 0; } @@ -119,8 +126,9 @@ hpgl_IN(hpgl_args_t *pargs, hpgl_state_t *pgls) /* restore defaults */ hpgl_DF(&args, pgls); /* cancel rotation */ - hpgl_args_setup(&args); - hpgl_RO(&args, pgls); + /* hpgl_args_setup(&args); + hpgl_RO(&args, pgls); */ + pgls->g.rotation = 0; /* defaults P1 and P2 */ hpgl_args_setup(&args); hpgl_IP(&args, pgls); @@ -144,7 +152,7 @@ hpgl_IN(hpgl_args_t *pargs, hpgl_state_t *pgls) 0,0 or the lower left of the picture frame. Simply sets the gl/2 state, we subsequently clear the path because we do not want to create a live gs path. */ - hpgl_args_setup(&args); + hpgl_args_set_real2(&args, 0.0, 0.0); hpgl_PU(&args, pgls); hpgl_args_set_real2(&args, 0.0, 0.0); hpgl_PA(&args, pgls); @@ -154,7 +162,7 @@ hpgl_IN(hpgl_args_t *pargs, hpgl_state_t *pgls) /* derive the current picture frame coordinates */ - private int + private int hpgl_picture_frame_coords(hpgl_state_t *pgls, gs_int_rect *gl2_win) { gs_rect dev_win; /* device window */ @@ -186,8 +194,7 @@ hpgl_picture_frame_coords(hpgl_state_t *pgls, gs_int_rect *gl2_win) } return 0; } - - + /* IP p1x,p1y[,p2x,p2y]; */ /* IP; */ int @@ -208,11 +215,10 @@ hpgl_IP(hpgl_args_t *pargs, hpgl_state_t *pgls) if ( i == 2 ) { - pgls->g.P2.x = (ptxy[0] - pgls->g.P1.x) + + pgls->g.P2.x = (ptxy[0] - pgls->g.P1.x) + pgls->g.P2.x; - pgls->g.P2.y = (ptxy[1] - pgls->g.P1.y) + + pgls->g.P2.y = (ptxy[1] - pgls->g.P1.y) + pgls->g.P2.y; - pgls->g.P1.x = ptxy[0]; pgls->g.P1.y = ptxy[1]; } @@ -332,23 +338,12 @@ hpgl_RO(hpgl_args_t *pargs, hpgl_state_t *pgls) if ( angle != pgls->g.rotation ) { - hpgl_args_t args; - hpgl_pen_state_t saved_pen_state; - hpgl_save_pen_state(pgls, &saved_pen_state, hpgl_pen_down | hpgl_pen_relative); hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); pgls->g.rotation = angle; hpgl_call(hpgl_set_ctm(pgls)); hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); - /* set the pen to the up position */ - hpgl_args_setup(&args); - hpgl_PU(&args, pgls); - /* now add a moveto the using the current ctm */ - hpgl_args_set_real(&args, point.x); - hpgl_args_add_real(&args, point.y); - hpgl_call(hpgl_PA(&args, pgls)); - hpgl_call(hpgl_clear_current_path(pgls)); - hpgl_restore_pen_state(pgls, &saved_pen_state, - hpgl_pen_down | hpgl_pen_relative); + hpgl_call(hpgl_set_current_position(pgls, &point)); + pgls->g.carriage_return_pos = pgls->g.pos; } return 0; } @@ -425,29 +420,15 @@ pxy: scale_params.pmin.x = xy[0]; return e_Range; } } - - { - hpgl_args_t args; - - hpgl_pen_state_t saved_pen_state; - hpgl_save_pen_state(pgls, &saved_pen_state, hpgl_pen_down); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - pgls->g.scaling_params = scale_params; - pgls->g.scaling_type = type; - hpgl_call(hpgl_set_ctm(pgls)); - hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); - /* we must clear the current path because we set up the CTM - when issuing the first point, and the CTM is a function of - SC. */ - - /* now add a moveto the using the current ctm */ - hpgl_args_set_real(&args, point.x); - hpgl_args_add_real(&args, point.y); - hpgl_call(hpgl_PU(&args, pgls)); - hpgl_call(hpgl_clear_current_path(pgls)); - hpgl_restore_pen_state(pgls, &saved_pen_state, hpgl_pen_down); - } - + hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); + pgls->g.scaling_params = scale_params; + pgls->g.scaling_type = type; + hpgl_call(hpgl_set_ctm(pgls)); + hpgl_call(gs_itransform(pgls->pgs, dev_pt.x, dev_pt.y, &point)); + hpgl_call(hpgl_set_current_position(pgls, &point)); + /* PCLTRM 23-7 (commands the update cr position) does not list + SC but PCL updates the position */ + pgls->g.carriage_return_pos = pgls->g.pos; return 0; } diff --git a/pcl/pgdraw.c b/pcl/pgdraw.c index 859af68fa..6514a22c8 100644 --- a/pcl/pgdraw.c +++ b/pcl/pgdraw.c @@ -7,7 +7,7 @@ #include "stdio_.h" #include "math_.h" -#include "gdebug.h" +#include "gdebug.h" #include "gstypes.h" /* for gsstate.h */ #include "gsmatrix.h" /* for gsstate.h */ #include "gsmemory.h" /* for gsstate.h */ @@ -45,7 +45,6 @@ hpgl_set_picture_frame_scaling(hpgl_state_t *pgls) hpgl_call(gs_scale(pgls->pgs, horz_scale, vert_scale)); } - return 0; } @@ -54,7 +53,7 @@ hpgl_set_picture_frame_scaling(hpgl_state_t *pgls) hpgl_set_pcl_to_plu_ctm(hpgl_state_t *pgls) { hpgl_call(pcl_set_ctm(pgls, false)); - hpgl_call(gs_translate(pgls->pgs, + hpgl_call(gs_translate(pgls->pgs, pgls->g.picture_frame.anchor_point.x, pgls->g.picture_frame.anchor_point.y)); /* move the origin */ @@ -71,7 +70,7 @@ hpgl_set_pcl_to_plu_ctm(hpgl_state_t *pgls) case 0 : hpgl_call(gs_translate(pgls->pgs, 0, 0)); break; - case 90 : + case 90 : hpgl_call(gs_translate(pgls->pgs, 0, -fw_plu)); break; case 180 : @@ -184,8 +183,11 @@ hpgl_set_graphics_dash_state(hpgl_state_t *pgls) int count; int i; + /* Make sure we always draw dots. */ + hpgl_call(gs_setdotlength(pgls->pgs, 0.00098, true)); + /* handle the simple case (no dash) and return */ - if ( pgls->g.line.current.is_solid ) + if ( pgls->g.line.current.is_solid ) { /* use a 0 count pattern to turn off dashing in case it is set */ @@ -193,8 +195,6 @@ hpgl_set_graphics_dash_state(hpgl_state_t *pgls) return 0; } - /* Make sure we always draw dots. */ - hpgl_call(gs_setdotlength(pgls->pgs, 0.00098, true)); if ( entry == 0 ) { /* dot length NOTE this is in absolute 1/72" units not @@ -208,12 +208,12 @@ hpgl_set_graphics_dash_state(hpgl_state_t *pgls) return 0; } - pat = ((adaptive) ? + pat = ((adaptive) ? (&pgls->g.adaptive_line_type[entry - 1]) : (&pgls->g.fixed_line_type[entry - 1])); length = ((pgls->g.line.current.pattern_length_relative) ? - (pgls->g.line.current.pattern_length * + (pgls->g.line.current.pattern_length * hpgl_compute_distance(pgls->g.P1.x, pgls->g.P1.y, pgls->g.P2.x, @@ -274,11 +274,11 @@ hpgl_set_graphics_line_attribute_state(hpgl_state_t *pgls, plotter units */ if ( pgls->g.pen.width[pgls->g.pen.selected] <= 14.0 ) { - hpgl_call(gs_setlinejoin(pgls->pgs, - gs_join_miter)); - hpgl_call(gs_setlinecap(pgls->pgs, + hpgl_call(gs_setlinejoin(pgls->pgs, + gs_join_miter)); + hpgl_call(gs_setlinecap(pgls->pgs, gs_cap_butt)); - hpgl_call(gs_setlinewidth(pgls->pgs, + hpgl_call(gs_setlinewidth(pgls->pgs, pgls->g.pen.width[pgls->g.pen.selected])); hpgl_call(gs_setmiterlimit(pgls->pgs, 5.0)); return 0; @@ -290,15 +290,15 @@ hpgl_set_graphics_line_attribute_state(hpgl_state_t *pgls, case hpgl_rm_polygon: case hpgl_rm_vector_fill: case hpgl_rm_clip_and_fill_polygon: - hpgl_call(gs_setlinejoin(pgls->pgs, - gs_join_round)); - hpgl_call(gs_setlinecap(pgls->pgs, + hpgl_call(gs_setlinejoin(pgls->pgs, + gs_join_round)); + hpgl_call(gs_setlinecap(pgls->pgs, gs_cap_round)); break; case hpgl_rm_vector: -vector: hpgl_call(gs_setlinejoin(pgls->pgs, - join_map[pgls->g.line.join])); - hpgl_call(gs_setlinecap(pgls->pgs, +vector: hpgl_call(gs_setlinejoin(pgls->pgs, + join_map[pgls->g.line.join])); + hpgl_call(gs_setlinecap(pgls->pgs, cap_map[pgls->g.line.cap])); break; default: @@ -310,16 +310,15 @@ vector: hpgl_call(gs_setlinejoin(pgls->pgs, #ifdef COMMENT /* I do not remember the rational for the large miter */ - hpgl_call(gs_setmiterlimit(pgls->pgs, + hpgl_call(gs_setmiterlimit(pgls->pgs, ( pgls->g.line.join == 1 ) ? 5000.0 : pgls->g.miter_limit)); #endif hpgl_call(gs_setmiterlimit(pgls->pgs, pgls->g.miter_limit)); - hpgl_call(gs_setlinewidth(pgls->pgs, + hpgl_call(gs_setlinewidth(pgls->pgs, pgls->g.pen.width[pgls->g.pen.selected])); - return 0; } @@ -354,7 +353,7 @@ hpgl_set_clipping_region(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) { gs_fixed_rect fixed_box; gs_rect pcl_clip_box; - gs_rect dev_clip_box; + gs_rect dev_clip_box; gs_matrix save_ctm; gs_matrix pcl_ctm; @@ -363,7 +362,6 @@ hpgl_set_clipping_region(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) hpgl_call(pcl_set_ctm(pgls, false)); hpgl_call(gs_currentmatrix(pgls->pgs, &pcl_ctm)); hpgl_call(gs_setmatrix(pgls->pgs, &save_ctm)); - /* find the clipping region defined by the picture frame which is defined in pcl coordinates */ pcl_clip_box.p.x = pgls->g.picture_frame.anchor_point.x; @@ -384,7 +382,7 @@ hpgl_set_clipping_region(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) gs_rect dev_soft_window_box; gs_matrix ctm; hpgl_call(gs_currentmatrix(pgls->pgs, &ctm)); - hpgl_call(gs_bbox_transform(&pgls->g.soft_clip_window.rect, + hpgl_call(gs_bbox_transform(&pgls->g.soft_clip_window.rect, &ctm, &dev_soft_window_box)); dev_clip_box.p.x = max(dev_clip_box.p.x, dev_soft_window_box.p.x); @@ -399,7 +397,7 @@ hpgl_set_clipping_region(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) fixed_box.q.x = float2fixed(dev_clip_box.q.x); fixed_box.q.y = float2fixed(dev_clip_box.q.y); hpgl_call(gx_clip_to_rectangle(pgls->pgs, &fixed_box)); - } + } return 0; } @@ -410,12 +408,33 @@ hpgl_draw_vector_absolute(hpgl_state_t *pgls, hpgl_real_t x0, hpgl_real_t y0, hpgl_rendering_mode_t render_mode) { bool set_ctm = (render_mode != hpgl_rm_character); - hpgl_call(hpgl_add_point_to_path(pgls, x0, y0, + hpgl_call(hpgl_add_point_to_path(pgls, x0, y0, hpgl_plot_move_absolute, set_ctm)); hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, hpgl_plot_draw_absolute, set_ctm)); + return 0; +} + + private int +hpgl_get_adjusted_corner(hpgl_real_t x_fill_increment, + hpgl_real_t y_fill_increment, gs_rect *bbox, gs_point *current_anchor_corner, + gs_point *adjusted_anchor_corner) +{ + adjusted_anchor_corner->x = current_anchor_corner->x; + adjusted_anchor_corner->y = current_anchor_corner->y; - return 0; + /* account for anchor corner greater than origin */ + if ( x_fill_increment != 0 ) + while ( adjusted_anchor_corner->x > bbox->p.x ) + adjusted_anchor_corner->x -= x_fill_increment; + else if ( adjusted_anchor_corner->x > bbox->p.x ) + adjusted_anchor_corner->x = bbox->p.x; + if ( y_fill_increment != 0 ) + while ( adjusted_anchor_corner->y > bbox->p.y ) + adjusted_anchor_corner->y -= y_fill_increment; + else if ( adjusted_anchor_corner->y > bbox->p.y ) + adjusted_anchor_corner->y = bbox->p.y; + return 0; } /* HAS should replicate lines beginning at the anchor corner to +X and @@ -424,8 +443,9 @@ hpgl_draw_vector_absolute(hpgl_state_t *pgls, hpgl_real_t x0, hpgl_real_t y0, private int hpgl_polyfill(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) { - hpgl_real_t diag_mag, startx, starty, endx, endy; + hpgl_real_t diag_mag, endx, endy; gs_sincos_t sincos; + gs_point start; #define sin_dir sincos.sin #define cos_dir sincos.cos gs_rect bbox; @@ -443,7 +463,7 @@ hpgl_polyfill(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) gs_matrix mat; hpgl_call(hpgl_compute_user_units_to_plu_ctm(pgls, &mat)); - spacing = + spacing = 0.01 * hpgl_compute_distance(pgls->g.P1.x, pgls->g.P1.y, pgls->g.P2.x, pgls->g.P2.y); /****** WHAT IF ANISOTROPIC SCALING? ******/ @@ -474,33 +494,27 @@ hpgl_polyfill(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) start: gs_sincos_degrees(direction, &sincos); if ( sin_dir < 0 ) sin_dir = -sin_dir, cos_dir = -cos_dir; /* ensure y_inc >= 0 */ - /* Draw one vector regardless of direction. */ - startx = pgls->g.anchor_corner.x; starty = pgls->g.anchor_corner.y; x_fill_increment = (sin_dir != 0) ? fabs(spacing / sin_dir) : 0; y_fill_increment = (cos_dir != 0) ? fabs(spacing / cos_dir) : 0; - - /* account for anchor corner greater than origin */ - if ( x_fill_increment != 0 ) - while ( startx > bbox.p.x ) startx -= x_fill_increment; - if ( y_fill_increment != 0 ) - while ( starty > bbox.p.y ) starty -= y_fill_increment; + hpgl_call(hpgl_get_adjusted_corner(x_fill_increment, + y_fill_increment, &bbox, &pgls->g.anchor_corner, &start)); + /* calculate the diagonals magnitude. Note we clip this latter in the library. If desired we could clip to the actual bbox here to save processing time. For now we simply draw all fill lines using the diagonals magnitude */ - diag_mag = - hpgl_compute_distance(startx, starty, bbox.q.x, bbox.q.y); - endx = (diag_mag * cos_dir) + startx; - endy = (diag_mag * sin_dir) + starty; - hpgl_call(hpgl_draw_vector_absolute(pgls, startx, starty, + diag_mag = + hpgl_compute_distance(start.x, start.y, bbox.q.x, bbox.q.y); + endx = (diag_mag * cos_dir) + start.x; + endy = (diag_mag * sin_dir) + start.y; + hpgl_call(hpgl_draw_vector_absolute(pgls, start.x, start.y, endx, endy, render_mode)); /* Travel along +x using current spacing. */ if ( x_fill_increment != 0 ) - while ( endx += x_fill_increment, - (startx += x_fill_increment) <= bbox.q.x - + while ( endx += x_fill_increment, + (start.x += x_fill_increment) <= bbox.q.x ) - hpgl_call(hpgl_draw_vector_absolute(pgls, startx, starty, + hpgl_call(hpgl_draw_vector_absolute(pgls, start.x, start.y, endx, endy, render_mode)); /* Travel along +Y similarly. */ if ( y_fill_increment != 0 ) @@ -511,17 +525,19 @@ start: gs_sincos_degrees(direction, &sincos); * the X loop left everything set up exactly right for this case. */ if ( cos_dir >= 0 ) - { startx = pgls->g.anchor_corner.x; starty = pgls->g.anchor_corner.y; - endx = (diag_mag * cos_dir) + startx; - endy = (diag_mag * sin_dir) + starty; + { + hpgl_call(hpgl_get_adjusted_corner(x_fill_increment, + y_fill_increment, &bbox, &pgls->g.anchor_corner, &start)); + endx = (diag_mag * cos_dir) + start.x; + endy = (diag_mag * sin_dir) + start.y; } else - starty -= y_fill_increment, endy -= y_fill_increment; + start.y -= y_fill_increment, endy -= y_fill_increment; while ( endy += y_fill_increment, - (starty += y_fill_increment) <= bbox.q.y + (start.y += y_fill_increment) <= bbox.q.y ) - hpgl_call(hpgl_draw_vector_absolute(pgls, startx, starty, + hpgl_call(hpgl_draw_vector_absolute(pgls, start.x, start.y, endx, endy, render_mode)); } if ( cross ) @@ -538,7 +554,7 @@ start: gs_sincos_degrees(direction, &sincos); } private int -hpgl_polyfill_using_current_line_type(hpgl_state_t *pgls, +hpgl_polyfill_using_current_line_type(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) { /* gsave and grestore used to preserve the clipping region */ @@ -571,6 +587,11 @@ hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) use a private hpgl/2 dictionary. */ pl_dict_t *pattern_dictp = &pgls->patterns; pcl_pattern_type_t pat; + /* A bizarre HPISM */ + if ( pgls->g.pen.selected == 0 ) { + pat = pcpt_solid_white; + goto set; + } switch ( render_mode ) { case hpgl_rm_clip_and_fill_polygon: @@ -585,12 +606,12 @@ hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) break; case hpgl_char_fill: case hpgl_char_fill_edge: - if ( pgls->g.fill.type == hpgl_fill_hatch || + if ( pgls->g.fill.type == hpgl_fill_hatch || pgls->g.fill.type == hpgl_fill_crosshatch ) { hpgl_call(hpgl_polyfill_using_current_line_type(pgls, render_mode)); return 0; - } + } else goto fill; default: @@ -602,7 +623,7 @@ hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) case hpgl_rm_polygon: fill: switch ( pgls->g.fill.type ) { - case hpgl_fill_solid: + case hpgl_fill_solid: case hpgl_fill_solid2: /* fall through */ /* this is documented incorrectly PCLTRM 22-12 says these should be solid black but they are actually @@ -618,7 +639,7 @@ fill: switch ( pgls->g.fill.type ) case hpgl_fill_pcl_crosshatch: id_set_value(pcl_id, pgls->g.fill.param.pattern_type); pat = pcpt_cross_hatch; - hpgl_call(hpgl_set_pcl_pattern_origin(pgls, + hpgl_call(hpgl_set_pcl_pattern_origin(pgls, &pgls->g.anchor_corner)); break; case hpgl_fill_shaded: @@ -626,7 +647,7 @@ fill: switch ( pgls->g.fill.type ) pat = pcpt_shading; break; case hpgl_fill_pcl_user_defined: - hpgl_call(hpgl_set_pcl_pattern_origin(pgls, + hpgl_call(hpgl_set_pcl_pattern_origin(pgls, &pgls->g.anchor_corner)); id_set_value(pcl_id, pgls->g.fill.param.pattern_id); pat = pcpt_user_defined; @@ -660,7 +681,7 @@ fill: switch ( pgls->g.fill.type ) pat = pcpt_shading; id_set_value(pcl_id, pgls->g.screen.param.shading); break; - case hpgl_screen_crosshatch: + case hpgl_screen_crosshatch: pat = pcpt_cross_hatch; id_set_value(pcl_id, pgls->g.screen.param.pattern_type); break; @@ -677,12 +698,12 @@ fill: switch ( pgls->g.fill.type ) } break; case hpgl_screen_pcl_user_defined: - hpgl_call(hpgl_set_pcl_pattern_origin(pgls, + hpgl_call(hpgl_set_pcl_pattern_origin(pgls, &pgls->g.anchor_corner)); pat = pcpt_user_defined; id_set_value(pcl_id, pgls->g.screen.param.pattern_id); break; - default: + default: dprintf("hpgl_set_drawing_color: internal error illegal fill\n"); break; } @@ -691,11 +712,11 @@ fill: switch ( pgls->g.fill.type ) dprintf("hpgl_set_drawing_color: internal error illegal mode\n"); break; } - gs_setrasterop(pgls->pgs, pgls->logical_op); +set: gs_setrasterop(pgls->pgs, pgls->logical_op); gs_setsourcetransparent(pgls->pgs, pgls->g.source_transparent); gs_settexturetransparent(pgls->pgs, pgls->g.source_transparent); /* set up the halftone phase origin in device space */ - hpgl_call(gs_transform(pgls->pgs, pgls->g.anchor_corner.x, + hpgl_call(gs_transform(pgls->pgs, pgls->g.anchor_corner.x, pgls->g.anchor_corner.y, &pattern_origin)); gs_setfilladjust(pgls->pgs, pgls->grid_adjust, pgls->grid_adjust); hpgl_call(pcl_set_drawing_color_rotation(pgls, @@ -727,7 +748,7 @@ hpgl_get_current_position(hpgl_state_t *pgls, gs_point *pt) { *pt = pgls->g.pos; return 0; -} +} int hpgl_set_current_position(hpgl_state_t *pgls, gs_point *pt) @@ -756,8 +777,8 @@ hpgl_add_point_to_path(hpgl_state_t *pgls, floatp x, floatp y, /* moveto the current position */ hpgl_call(hpgl_get_current_position(pgls, ¤t_pt)); - hpgl_call_check_lost(gs_moveto(pgls->pgs, - current_pt.x, + hpgl_call_check_lost(gs_moveto(pgls->pgs, + current_pt.x, current_pt.y)); } { int code = (*gs_procs[func])(pgls->pgs, x, y); @@ -783,7 +804,7 @@ hpgl_add_point_to_path(hpgl_state_t *pgls, floatp x, floatp y, } /* destroy the current path. */ - int + int hpgl_clear_current_path(hpgl_state_t *pgls) { hpgl_call(gs_newpath(pgls->pgs)); @@ -791,7 +812,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)); @@ -815,9 +836,9 @@ hpgl_add_pcl_point_to_path(hpgl_state_t *pgls, const gs_point *pcl_pt) } int -hpgl_add_arc_to_path(hpgl_state_t *pgls, floatp center_x, floatp center_y, +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, bool start_moveto, hpgl_plot_function_t draw, + floatp chord_angle, bool start_moveto, hpgl_plot_function_t draw, bool set_ctm) { /* @@ -827,45 +848,45 @@ hpgl_add_arc_to_path(hpgl_state_t *pgls, floatp center_x, floatp center_y, int num_chords = (int)ceil(sweep_angle / chord_angle); floatp integral_chord_angle = sweep_angle / num_chords; int i; - floatp arccoord_x, arccoord_y; + floatp arccoord_x, arccoord_y; - (void)hpgl_compute_arc_coords(radius, center_x, center_y, - start_angle, + (void)hpgl_compute_arc_coords(radius, center_x, center_y, + start_angle, &arccoord_x, &arccoord_y); - hpgl_call(hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, - (draw && !start_moveto ? + hpgl_call(hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, + (draw && !start_moveto ? hpgl_plot_draw_absolute : hpgl_plot_move_absolute), set_ctm)); /* HAS - pen up/down is invariant in the loop */ - for ( i = 0; i < num_chords; i++ ) + for ( i = 0; i < num_chords; i++ ) { start_angle += integral_chord_angle; - hpgl_compute_arc_coords(radius, center_x, center_y, + hpgl_compute_arc_coords(radius, center_x, center_y, start_angle, &arccoord_x, &arccoord_y); - hpgl_call(hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, + hpgl_call(hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, (draw ? hpgl_plot_draw_absolute : hpgl_plot_move_absolute), set_ctm)); } return 0; } -/* add a 3 point arc to the path */ +/* add a 3 point arc to the path */ int hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp - start_y, floatp inter_x, floatp inter_y, + start_y, floatp inter_x, floatp inter_y, floatp end_x, floatp end_y, floatp chord_angle, hpgl_plot_function_t draw) { /* handle unusual cases as per pcltrm */ - if ( hpgl_3_same_points(start_x, start_y, - inter_x, inter_y, + if ( hpgl_3_same_points(start_x, start_y, + inter_x, inter_y, end_x, end_y) ) { hpgl_call(hpgl_add_point_to_path(pgls, start_x, start_y, draw, true)); return 0; } - if ( hpgl_3_no_intermediate(start_x, start_y, + if ( hpgl_3_no_intermediate(start_x, start_y, inter_x, inter_y, end_x, end_y) ) { @@ -873,9 +894,9 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp hpgl_call(hpgl_add_point_to_path(pgls, end_x, end_y, draw, true)); return 0; } - if ( hpgl_3_same_endpoints(start_x, start_y, - inter_x, y_inter, - end_x, end_y) ) + if ( hpgl_3_same_endpoints(start_x, start_y, + inter_x, y_inter, + end_x, end_y) ) { hpgl_call(hpgl_add_arc_to_path(pgls, (start_x + inter_x) / 2.0, (start_y + inter_y) / 2.0, @@ -886,16 +907,16 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp return 0; } - if ( hpgl_3_colinear_points(start_x, start_y, inter_x, inter_y, end_x, end_y) ) + if ( hpgl_3_colinear_points(start_x, start_y, inter_x, inter_y, end_x, end_y) ) { - if ( hpgl_3_intermediate_between(start_x, start_y, - inter_x, inter_y, - end_x, end_y) ) + if ( hpgl_3_intermediate_between(start_x, start_y, + inter_x, inter_y, + end_x, end_y) ) { hpgl_call(hpgl_add_point_to_path(pgls, start_x, start_y, draw, true)); hpgl_call(hpgl_add_point_to_path(pgls, end_x, end_x, draw, true)); } - else + else { hpgl_call(hpgl_add_point_to_path(pgls, start_x, start_y, draw, true)); hpgl_call(hpgl_add_point_to_path(pgls, inter_x, inter_y, draw, true)); @@ -910,13 +931,12 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp hpgl_real_t start_angle, inter_angle, end_angle; hpgl_real_t sweep_angle; - hpgl_call(hpgl_compute_arc_center(start_x, start_y, - inter_x, inter_y, - end_x, end_y, + hpgl_call(hpgl_compute_arc_center(start_x, start_y, + inter_x, inter_y, + end_x, end_y, ¢er_x, ¢er_y)); radius = hypot(start_x - center_x, start_y - center_y); - start_angle = radians_to_degrees * hpgl_compute_angle(start_x - center_x, start_y - center_y); @@ -925,7 +945,6 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp end_angle = radians_to_degrees * hpgl_compute_angle(end_x - center_x, end_y - center_y); - sweep_angle = end_angle - start_angle; /* @@ -950,25 +969,25 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp sweep_angle += 360; } - hpgl_call(hpgl_add_arc_to_path(pgls, center_x, center_y, - radius, start_angle, sweep_angle, + hpgl_call(hpgl_add_arc_to_path(pgls, center_x, center_y, + radius, start_angle, sweep_angle, (sweep_angle < 0.0 ) ? -chord_angle : chord_angle, false, draw, true)); return 0; } } - + /* Bezier's are handled a bit differently than arcs as we use the gs_curveto() operator directly in lieue of flattening and using gs_moveto() and gs_lineto(). */ int -hpgl_add_bezier_to_path(hpgl_state_t *pgls, floatp x1, floatp y1, - floatp x2, floatp y2, floatp x3, floatp y3, +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, hpgl_plot_function_t draw) { - hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, + hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, hpgl_plot_move_absolute, true)); if ( draw ) hpgl_call(gs_curveto(pgls->pgs, x2, y2, x3, y3, x4, y4)); @@ -983,22 +1002,22 @@ 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. HAS - eliminate CSE gx_current_path */ - private int + int hpgl_close_path(hpgl_state_t *pgls) { gs_point first, first_device, last; /* if we do not have a subpath there is nothing to do. HAS perhaps hpgl_draw_current_path() should make this observation instead of checking for a null path??? */ - if ( !gx_current_path(pgls->pgs)->first_subpath ) return 0; + if ( !gx_current_path(pgls->pgs)->current_subpath ) return 0; /* get the first points of the path in device space */ - first_device.x = (gx_current_path(pgls->pgs))->first_subpath->pt.x; - first_device.y = (gx_current_path(pgls->pgs))->first_subpath->pt.y; + first_device.x = (gx_current_path(pgls->pgs))->current_subpath->pt.x; + first_device.y = (gx_current_path(pgls->pgs))->current_subpath->pt.y; /* convert to user/plu space */ hpgl_call(gs_itransform(pgls->pgs, - fixed2float(first_device.x), - fixed2float(first_device.y), + fixed2float(first_device.x), + fixed2float(first_device.y), &first)); /* get gl/2 current position -- always current units */ @@ -1051,6 +1070,7 @@ hpgl_draw_current_path(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) break; /* no edging */ if ( pgls->g.character.edge_pen != 0 ) { gs_setgray(pgs, 0.0); /* solid edge */ + hpgl_call(hpgl_set_plu_ctm(pgls)); gs_setlinewidth(pgs, 0.1); hpgl_call(gs_stroke(pgs)); } @@ -1064,10 +1084,11 @@ hpgl_draw_current_path(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) if ( pgls->g.bitmap_fonts_allowed ) break; /* no edging */ if ( pgls->g.character.edge_pen != 0 ) - { + { hpgl_call(hpgl_gsave(pgls)); gs_setgray(pgs, 0.0); /* solid edge */ gs_setlinewidth(pgs, 0.1); + hpgl_call(hpgl_set_plu_ctm(pgls)); hpgl_call(gs_stroke(pgs)); hpgl_call(hpgl_grestore(pgls)); } @@ -1082,7 +1103,13 @@ hpgl_draw_current_path(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) hpgl_call(gs_fill(pgs)); break; case hpgl_rm_clip_and_fill_polygon: - /* HACK handled by hpgl_set_drawing_color */ + /* A bizarre HPISM - If the pen is white we do a solid + white fill this is true for *all* fill types (arg!) as + tested on the 6mp. If pen 1 (black) + hpgl_set_drawing_color() handles this case by drawing + the lines that comprise the vector fill */ + if ( pgls->g.pen.selected == 0 ) + hpgl_call(gs_fill(pgls->pgs)); break; case hpgl_rm_vector: case hpgl_rm_vector_fill: @@ -1100,7 +1127,7 @@ hpgl_draw_current_path(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) return 0; } - int + int hpgl_copy_current_path_to_polygon_buffer(hpgl_state_t *pgls) { gx_path *ppath = gx_current_path(pgls->pgs); @@ -1124,7 +1151,7 @@ hpgl_grestore(hpgl_state_t *pgls) } - int + int hpgl_copy_polygon_buffer_to_current_path(hpgl_state_t *pgls) { gx_path *ppath = gx_current_path(pgls->pgs); diff --git a/pcl/pgdraw.h b/pcl/pgdraw.h index cc5b9ca5a..54a4d8dc1 100644 --- a/pcl/pgdraw.h +++ b/pcl/pgdraw.h @@ -33,14 +33,14 @@ int hpgl_set_drawing_color(P2(hpgl_state_t *pgls, hpgl_rendering_mode_t render_m int hpgl_get_current_position(P2(hpgl_state_t *pgls, gs_point *pt)); /* puts a point into the path using the operation specified by func */ -int hpgl_add_point_to_path(P5(hpgl_state_t *pgls, floatp x, floatp y, +int hpgl_add_point_to_path(P5(hpgl_state_t *pgls, floatp x, floatp y, hpgl_plot_function_t func, bool set_ctm)); /* puts an arc into the current path. start moveto indicates that we use moveto to go from the arc center to arc circumference. */ -int hpgl_add_arc_to_path(P10(hpgl_state_t *pgls, floatp center_x, - floatp center_y, floatp radius, - floatp start_angle, floatp sweep_angle, +int hpgl_add_arc_to_path(P10(hpgl_state_t *pgls, floatp center_x, + floatp center_y, floatp radius, + floatp start_angle, floatp sweep_angle, floatp chord_angle, bool start_moveto, hpgl_plot_function_t draw, bool set_ctm)); @@ -49,18 +49,18 @@ int hpgl_add_arc_to_path(P10(hpgl_state_t *pgls, floatp center_x, wedge routines use this function as well */ int hpgl_add_arc_3point_to_path(P9(hpgl_state_t *pgls, floatp start_x, floatp - start_y, floatp inter_x, floatp inter_y, + start_y, floatp inter_x, floatp inter_y, floatp end_x, floatp end_y, floatp chord_angle, hpgl_plot_function_t draw)); /* put bezier into the current path */ -int hpgl_add_bezier_to_path(P10(hpgl_state_t *pgls, floatp x1, - floatp y1, floatp x2, floatp y2, - floatp x3, floatp y3, floatp x4, +int hpgl_add_bezier_to_path(P10(hpgl_state_t *pgls, floatp x1, + floatp y1, floatp x2, floatp y2, + floatp x3, floatp y3, floatp x4, floatp y4, hpgl_plot_function_t draw)); /* clears the current path with stroke or fill */ -int hpgl_draw_current_path(P2(hpgl_state_t *pgls, +int hpgl_draw_current_path(P2(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)); /* save gs graphics state + HPGL/2's first moveto state */ @@ -75,7 +75,7 @@ int hpgl_copy_polygon_buffer_to_current_path(P1(hpgl_state_t *pgls)); int hpgl_copy_current_path_to_polygon_buffer(P1(hpgl_state_t *pgls)); /* draw the current path with stroke or fill, but do not clear */ -int hpgl_draw_and_preserve_path(P2(hpgl_state_t *pgls, +int hpgl_draw_and_preserve_path(P2(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode)); /* destroy the current path */ diff --git a/pcl/pgfdata.c b/pcl/pgfdata.c index f88c4f66c..9afb611a6 100644 --- a/pcl/pgfdata.c +++ b/pcl/pgfdata.c @@ -200,7 +200,7 @@ hpgl_stick_arc_width(uint char_index) /* * Main program for computing escapements. Compile with: - * gcc -I../gs -DESCAPEMENTS -lm pgfdata.c + * gcc -I../gs -DESCAPEMENTS -lm pgfdata.c */ #include "math_.h" typedef struct esc_data_s { diff --git a/pcl/pgframe.c b/pcl/pgframe.c index 3c9c52535..fcc321e3a 100644 --- a/pcl/pgframe.c +++ b/pcl/pgframe.c @@ -11,7 +11,7 @@ #include "gstypes.h" /* for gsstate.h */ #include "gsmatrix.h" /* for gsstate.h */ #include "gsmemory.h" /* for gsstate.h */ -#include "gsstate.h" +#include "gsstate.h" #include "pcdraw.h" #include "pcfont.h" /* for pcl_continue_underline */ @@ -21,7 +21,7 @@ extern pcl_command_proc(rtl_enter_pcl_mode); /* Even though these are PCL commands, */ /* they are only relevant to HPGL. */ -int /* ESC * c <w_dp> X */ +int /* ESC * c <w_dp> X */ pcl_horiz_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcls) { coord size = (coord)(float_arg(pargs) * 10.0); /* --> centipoints */ @@ -48,7 +48,7 @@ pcl_horiz_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcls) return 0; } -int /* ESC * c <h_dp> Y */ +int /* ESC * c <h_dp> Y */ pcl_vert_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcls) { coord size = (coord)(float_arg(pargs) * 10.0); /* --> centipoints */ @@ -81,7 +81,7 @@ pcl_vert_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcls) return 0; } -int /* ESC * c 0 T */ +int /* ESC * c 0 T */ pcl_set_pic_frame_anchor_point(pcl_args_t *pargs, pcl_state_t *pcls) { uint i = uint_arg(pargs); if ( i != 0 ) @@ -112,7 +112,7 @@ pcl_set_pic_frame_anchor_point(pcl_args_t *pargs, pcl_state_t *pcls) return 0; } -int /* ESC * c <w_in> K */ +int /* ESC * c <w_in> K */ pcl_hpgl_plot_horiz_size(pcl_args_t *pargs, pcl_state_t *pcls) { /* convert to centipoints as to match the picture frame */ @@ -132,7 +132,7 @@ pcl_hpgl_plot_horiz_size(pcl_args_t *pargs, pcl_state_t *pcls) return 0; } -int /* ESC * c <h_in> L */ +int /* ESC * c <h_in> L */ pcl_hpgl_plot_vert_size(pcl_args_t *pargs, pcl_state_t *pcls) { /* convert to centipoints as to match the picture frame */ @@ -152,7 +152,7 @@ pcl_hpgl_plot_vert_size(pcl_args_t *pargs, pcl_state_t *pcls) /* We redefine this command so we can draw the current GL path */ /* and, if appropriate, reset the underline bookkeeping. */ -private int /* ESC % <enum> A */ +private int /* ESC % <enum> A */ pcl_enter_pcl_mode(pcl_args_t *pargs, pcl_state_t *pcls) { int code; diff --git a/pcl/pggeom.c b/pcl/pggeom.c index 4940c2e6d..60154c9f1 100644 --- a/pcl/pggeom.c +++ b/pcl/pggeom.c @@ -6,7 +6,6 @@ /* HP-GL/2 geometry routines */ #include "stdio_.h" -#include "math_.h" #include "pggeom.h" #include "gxfarith.h" /* for gs_sincos */ @@ -16,7 +15,7 @@ /* compute the angle between 0 and 2*PI given the slope */ floatp -hpgl_compute_angle(floatp dx, floatp dy) +hpgl_compute_angle(floatp dx, floatp dy) { floatp alpha = atan2(dy, dx); @@ -25,7 +24,7 @@ hpgl_compute_angle(floatp dx, floatp dy) /* compute the center of an arc given 3 points on the arc */ int -hpgl_compute_arc_center(floatp x1, floatp y1, floatp x2, floatp y2, +hpgl_compute_arc_center(floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3, floatp *pcx, floatp *pcy) { @@ -80,7 +79,7 @@ hpgl_compute_arc_center(floatp x1, floatp y1, floatp x2, floatp y2, /* compute the coordinates of a point on an arc */ int -hpgl_compute_arc_coords(floatp radius, floatp center_x, floatp center_y, +hpgl_compute_arc_coords(floatp radius, floatp center_x, floatp center_y, floatp angle, floatp *px, floatp *py) { gs_sincos_t sincos; @@ -93,10 +92,10 @@ hpgl_compute_arc_coords(floatp radius, floatp center_x, floatp center_y, /* given a start point, angle (degrees) and magnitude of a vector compute its endpoints */ int -hpgl_compute_vector_endpoints(floatp magnitude, floatp x, floatp y, +hpgl_compute_vector_endpoints(floatp magnitude, floatp x, floatp y, floatp angle_degrees, floatp *endx, floatp *endy) { - return hpgl_compute_arc_coords(magnitude, x, y, + return hpgl_compute_arc_coords(magnitude, x, y, angle_degrees, endx, endy); } diff --git a/pcl/pggeom.h b/pcl/pggeom.h index ccb0c93e0..c46f153b6 100644 --- a/pcl/pggeom.h +++ b/pcl/pggeom.h @@ -33,18 +33,18 @@ floatp hpgl_compute_angle(P2(floatp dx, floatp dy)); /* compute the center of an arc given 3 points on the arc */ -int hpgl_compute_arc_center(P8(floatp x1, floatp y1, floatp x2, - floatp y2, floatp x3, floatp y3, +int hpgl_compute_arc_center(P8(floatp x1, floatp y1, floatp x2, + floatp y2, floatp x3, floatp y3, floatp *pcx, floatp *pcy)); /* compute the coordinates of a point on an arc */ -int hpgl_compute_arc_coords(P6(floatp radius, floatp center_x, - floatp center_y, floatp angle, +int hpgl_compute_arc_coords(P6(floatp radius, floatp center_x, + floatp center_y, floatp angle, floatp *px, floatp *py)); /* given a start point, angle (degrees) and magnitude of a vector compute its endpoints */ -int hpgl_compute_vector_endpoints(P6(floatp magnitude, floatp x, floatp y, +int hpgl_compute_vector_endpoints(P6(floatp magnitude, floatp x, floatp y, floatp angle_degrees, floatp *endx, floatp *endy)); diff --git a/pcl/pginit.c b/pcl/pginit.c index 3204169bc..64a7e426b 100644 --- a/pcl/pginit.c +++ b/pcl/pginit.c @@ -4,7 +4,11 @@ /* pginit.c */ /* Initialization and resetting for HP-GL/2. */ -#include "memory_.h" /* for memset */ +#include "std.h" +#include "gstypes.h" /* for gsstate.h */ +#include "gsmatrix.h" /* for gsstate.h */ +#include "gsmemory.h" /* for gsstate.h */ +#include "gsstate.h" /* for gs_setlimitclamp */ #include "pgmand.h" #include "pginit.h" #include "pgdraw.h" @@ -56,9 +60,9 @@ hpgl_default_pen_color(hpgl_state_t *pgls, int pen) private void hpgl_default_coordinate_system(hpgl_state_t *pcls) { - pcls->g.plot_width = pcls->g.picture_frame_width = + pcls->g.plot_width = pcls->g.picture_frame_width = pcls->logical_page_width; - pcls->g.plot_height = pcls->g.picture_frame_height = + pcls->g.plot_height = pcls->g.picture_frame_height = pcl_text_length(pcls); pcls->g.picture_frame.anchor_point.x = pcl_left_margin(pcls); pcls->g.picture_frame.anchor_point.y = pcl_top_margin(pcls); @@ -90,18 +94,6 @@ hpgl_default_all_fill_patterns(hpgl_state_t *pgls) hpgl_default_fill_pattern(pgls, i); } -/* fill the state with a bogus value -- debug only. */ - - private void -hpgl_clear_state(pcl_state_t *pcls) -{ - -#ifdef DEBUG - memset(&pcls->g, 0xee, sizeof(pcls->g)); -#endif - return; -} - void hpgl_do_reset(pcl_state_t *pcls, pcl_reset_type_t type) { /* pgframe.c (Chapter 18) */ @@ -111,11 +103,13 @@ hpgl_do_reset(pcl_state_t *pcls, pcl_reset_type_t type) { if ( type & (pcl_reset_initial | pcl_reset_cold) ) { - hpgl_clear_state(pcls); pl_dict_init(&pcls->g.raster_patterns, pcls->memory, NULL); hpgl_default_all_fill_patterns(pcls); gx_path_init(&pcls->g.polygon.buffer.path, pcls->memory); + /* HAS This is required for GL/2 but probably should + be maintained locally in gl/2's state machinery */ + gs_setlimitclamp(pcls->pgs, true); } else { @@ -134,7 +128,7 @@ hpgl_do_reset(pcl_state_t *pcls, pcl_reset_type_t type) /* execute IN */ hpgl_args_setup(&hpgl_args); hpgl_IN(&hpgl_args, pcls); - } + } if ( type & (pcl_reset_page_params) ) { hpgl_default_coordinate_system(pcls); diff --git a/pcl/pglabel.c b/pcl/pglabel.c index 5dec3add5..f692c1e46 100644 --- a/pcl/pglabel.c +++ b/pcl/pglabel.c @@ -228,7 +228,7 @@ hpgl_get_char_width(const hpgl_state_t *pgls, uint ch, hpgl_real_t *width, bool with_extra_space) { uint glyph = hpgl_map_symbol(ch, pgls); - const pcl_font_selection_t *pfs = + const pcl_font_selection_t *pfs = &pgls->g.font_selection[pgls->g.font_selected]; int code = 0; gs_point gs_width; @@ -273,7 +273,7 @@ private int hpgl_get_current_cell_height(const hpgl_state_t *pgls, hpgl_real_t *height, bool cell_height, bool with_extra_space) { - const pcl_font_selection_t *pfs = + const pcl_font_selection_t *pfs = &pgls->g.font_selection[pgls->g.font_selected]; *height = @@ -376,7 +376,7 @@ hpgl_CP(hpgl_args_t *pargs, hpgl_state_t *pgls) hpgl_real_t spaces, lines; if ( hpgl_arg_c_real(pargs, &spaces) ) - { + { if ( !hpgl_arg_c_real(pargs, &lines) ) return e_Range; } @@ -446,11 +446,11 @@ hpgl_buffer_char(hpgl_state_t *pgls, byte ch) /* ------ LB command ------ */ /* build the path and render it */ - private int + static int hpgl_print_char(hpgl_state_t *pgls, uint ch) { int text_path = pgls->g.character.text_path; - const pcl_font_selection_t *pfs = + const pcl_font_selection_t *pfs = &pgls->g.font_selection[pgls->g.font_selected]; const pl_font_t *font = pfs->font; gs_state *pgs = pgls->pgs; @@ -474,10 +474,7 @@ hpgl_print_char(hpgl_state_t *pgls, uint ch) * Reset the CTM if GL/2 scaling is on but we aren't using * relative-size characters (SR). */ - if ( pgls->g.scaling_type != hpgl_scaling_none && - pgls->g.character.size_mode != hpgl_size_relative - ) - hpgl_call(hpgl_set_plu_ctm(pgls)); + hpgl_call(hpgl_set_plu_ctm(pgls)); /* * We know that the drawing machinery only sets the CTM * once, at the beginning of the path. We now impose the scale @@ -534,7 +531,10 @@ hpgl_print_char(hpgl_state_t *pgls, uint ch) * Note that the CTM takes P1/P2 into account unless * an absolute character size is in effect. */ - scale = pgls->g.character.size; + /* * HACKS - I am not sure what this should be the + actual values ??? * */ + scale.x = pgls->g.character.size.x * 2.0; + scale.y = pgls->g.character.size.y * (4.0/3.0); if ( pgls->g.character.size_mode == hpgl_size_relative ) scale.x *= pgls->g.P2.x - pgls->g.P1.x, scale.y *= pgls->g.P2.y - pgls->g.P1.y; @@ -659,7 +659,7 @@ hpgl_print_char(hpgl_state_t *pgls, uint ch) case hpgl_char_fill: switch ( pgls->g.fill.type ) { - case hpgl_fill_solid: + case hpgl_fill_solid: case hpgl_fill_solid2: break; /* Eventually we will be able to do better than this.... */ @@ -762,6 +762,7 @@ hpgl_can_concat_labels(const hpgl_state_t *pgls) (1 << pgls->g.character.text_path)) != 0; } + /* return relative coordinates to compensate for origin placement -- LO */ private int hpgl_get_character_origin_offset(hpgl_state_t *pgls, int origin, @@ -840,7 +841,7 @@ hpgl_get_character_origin_offset(hpgl_state_t *pgls, int origin, hpgl_call(gs_itransform(pgls->pgs, (floatp)pcl_pos_dev.x, (floatp)pcl_pos_dev.y, &label_origin)); pos_x = -(pgls->g.pos.x - label_origin.x); - pos_y = -(pgls->g.pos.y - label_origin.y); + pos_y = (pgls->g.pos.y - label_origin.y); } break; default: @@ -864,50 +865,7 @@ hpgl_process_buffer(hpgl_state_t *pgls) /* * NOTE: the two loops below must be consistent with each other! */ - -#if 0 /* **************** */ - /**************** - -The algorithm below for deciding whether to compute the label length is -wrong: hpgl_can_concat_labels is *not* the correct way to determine what -needs to be computed. To minimize the computation, what we need is a table -that maps - <int label_origin, int text_path> -to - <bool need_width, bool need_height>. -If both need_width and need_height are false, we can skip the loop entirely; -if only one is true, we can omit some of the computations in the loop (e.g., -if we are writing horizontally and only need the height, for example for LO -3, we can omit the calls on hpgl_get_char_width and the special stuff for BS -and HT). I would choose to do this with a table of bytes, similar to -can_concat, in which the bits of each byte contained - h3 h2 h1 h0 w3 w2 w1 w0 -i.e., <height needed for text path 3>, <height needed for text path 2>, ..., -<width needed for text path 0>: - { static const byte width_height_needed[22] = { - ... - }; - byte mask = width_height_needed[pgls->g.label.origin] >> - pgls->g.character.text_path; - - need_width = (mask & 1) != 0; - need_height = (mask & 0x10) != 0; - } -We still need some special code to handle LFs. - - ****************/ - /* - * Compute the label length if the combination of text path and - * label origin needs it. Note that we always need the label - * width if the text path is vertical and there are any LF - * characters in the string, since LF is horizontal in this case. - */ - if ( !hpgl_can_concat_labels(pgls) || - (vertical && - memchr(pgls->g.label.buffer, LF, pgls->g.label.char_count) != 0) - ) -#endif /* **************** */ { hpgl_real_t width = 0.0, height = 0.0; int save_index = pgls->g.font_selected; @@ -918,7 +876,7 @@ We still need some special code to handle LFs. byte ch = pgls->g.label.buffer[i++]; if ( ch < 0x20 && !pgls->g.transparent_data ) - switch (ch) + switch (ch) { case BS : if ( width == 0.0 ) /* BS as first char of string */ @@ -929,13 +887,13 @@ We still need some special code to handle LFs. if ( vertical ) { /* Vertical text path, back up in Y. */ label_height -= height; - if ( label_height < 0.0 ) + if ( label_height < 0.0 ) label_height = 0.0; } else { /* Horizontal text path, back up in X. */ label_length -= width; - if ( label_length < 0.0 ) + if ( label_length < 0.0 ) label_length = 0.0; } continue; @@ -992,16 +950,16 @@ acc_ht: hpgl_call(hpgl_get_current_cell_height(pgls, &height, vertical, ve DO_NOTHING; } - /* these units should be strictly plu */ - { gs_matrix mat; - - hpgl_compute_user_units_to_plu_ctm(pgls, &mat); + /* these units should be strictly plu except for LO 21 */ + if ( pgls->g.label.origin != 21 ) + { gs_matrix mat; + hpgl_compute_user_units_to_plu_ctm(pgls, &mat); - offset.x /= mat.xx; - offset.y /= mat.yy; - hpgl_call(hpgl_add_point_to_path(pgls, -offset.x, -offset.y, + offset.x /= mat.xx; + offset.y /= mat.yy; + } + hpgl_call(hpgl_add_point_to_path(pgls, -offset.x, -offset.y, hpgl_plot_move_relative, true)); - } { int i; @@ -1060,7 +1018,7 @@ print: hpgl_ensure_font(pgls); pgls->g.label.char_count = 0; return 0; -} +} /* LB ..text..terminator */ int @@ -1135,19 +1093,26 @@ hpgl_LB(hpgl_args_t *pargs, hpgl_state_t *pgls) int hpgl_print_symbol_mode_char(hpgl_state_t *pgls) { + /* save the original origin since symbol mode character are + always centered */ int saved_origin = pgls->g.label.origin; + gs_point save_pos = pgls->g.pos; hpgl_call(hpgl_gsave(pgls)); + /* HAS this need checking. I don't know how text direction + and label origin interact in symbol mode */ pgls->g.label.origin = 5; + /* HAS - alot of work for one character */ hpgl_call(hpgl_clear_current_path(pgls)); hpgl_call(hpgl_init_label_buffer(pgls)); hpgl_call(hpgl_buffer_char(pgls, pgls->g.symbol_mode)); hpgl_call(hpgl_process_buffer(pgls)); hpgl_call(hpgl_destroy_label_buffer(pgls)); hpgl_call(hpgl_grestore(pgls)); + /* restore the origin */ pgls->g.label.origin = saved_origin; + pgls->g.pos = save_pos; return 0; } - /* Initialization */ private int diff --git a/pcl/pglfill.c b/pcl/pglfill.c index e7e31faab..8864a7b2e 100644 --- a/pcl/pglfill.c +++ b/pcl/pglfill.c @@ -171,7 +171,7 @@ hpgl_LA(hpgl_args_t *pargs, hpgl_state_t *pgls) /* LA1,1,2,1,3,5 is the same as LA */ if (no_args) { - hpgl_args_setup(pargs); + hpgl_args_setup(pargs); hpgl_args_add_int(pargs, 1); hpgl_args_add_int(pargs, 1); hpgl_args_add_int(pargs, 2); @@ -225,7 +225,7 @@ hpgl_LT(hpgl_args_t *pargs, hpgl_state_t *pgls) hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); if ( hpgl_arg_c_int(pargs, &type) ) - { + { /* restore old saved line if we have a solid line, otherwise the instruction is ignored. */ if ( type == 99 ) @@ -258,11 +258,11 @@ hpgl_LT(hpgl_args_t *pargs, hpgl_state_t *pgls) command. */ pgls->g.line.saved = pgls->g.line.current; pgls->g.line.current.is_solid = true; - memcpy(&pgls->g.fixed_line_type, - &hpgl_fixed_pats, + memcpy(&pgls->g.fixed_line_type, + &hpgl_fixed_pats, sizeof(hpgl_fixed_pats)); - memcpy(&pgls->g.adaptive_line_type, - &hpgl_adaptive_pats, + memcpy(&pgls->g.adaptive_line_type, + &hpgl_adaptive_pats, sizeof(hpgl_adaptive_pats)); } @@ -278,10 +278,13 @@ hpgl_MC(hpgl_args_t *pargs, hpgl_state_t *pgls) if ( hpgl_arg_c_int(pargs, &mode) && (mode & ~1) ) return e_Range; - opcode = ( mode ) ? 168 : 252; + opcode = mode ? 168 : 252; if ( mode != 0 && hpgl_arg_c_int(pargs, &opcode) ) if (opcode < 0 || opcode > 255 ) - return e_Range; + { + pgls->logical_op = 252; + return e_Range; + } hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); pgls->logical_op = opcode; return 0; @@ -315,11 +318,11 @@ hpgl_PW(hpgl_args_t *pargs, hpgl_state_t *pgls) /* we maintain the line widths in plotter units, irrespective of current units (WU). They width argument to PW are mm */ if ( hpgl_arg_c_real(pargs, ¶m) ) - { - if ( hpgl_arg_c_int(pargs, &pmin) ) - if ( pmin < 0 || pmin > pmax ) + { + if ( hpgl_arg_c_int(pargs, &pmin) ) + if ( pmin < 0 || pmin > pmax ) return e_Range; - else + else pmax = pmin; } /* width is maintained in plu only */ @@ -336,7 +339,7 @@ hpgl_PW(hpgl_args_t *pargs, hpgl_state_t *pgls) ((hpgl_real_t)pgls->g.picture_frame_width / (hpgl_real_t)pgls->g.plot_width))); hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); - { + { int i; for ( i = pmin; i <= pmax; ++i ) @@ -351,16 +354,16 @@ hpgl_RF(hpgl_args_t *pargs, hpgl_state_t *pgls) { uint index, width, height; if ( pargs->phase == 0 ) - { + { if ( !hpgl_arg_c_int(pargs, &index) ) - { + { hpgl_default_all_fill_patterns(pgls); return 0; } if ( index < 1 || index > 8 ) return e_Range; if ( !hpgl_arg_c_int(pargs, &width) ) - { + { hpgl_default_fill_pattern(pgls, index); return 0; } @@ -396,7 +399,6 @@ hpgl_RF(hpgl_args_t *pargs, hpgl_state_t *pgls) ((uint)floor(pgls->resolution.x + 0.5)) & 0xff, ((uint)floor(pgls->resolution.y + 0.5)) >> 8, ((uint)floor(pgls->resolution.y + 0.5)) & 0xff); - /* global id to uniquely identify the dictionary key. FT selects the pattern */ id_set_value(pgls->g.raster_pattern_id, index); @@ -408,7 +410,7 @@ hpgl_RF(hpgl_args_t *pargs, hpgl_state_t *pgls) /* bit offset of data */ #define bitindx ((pargs->phase-1) + (pattern_data_offset * 8)) while ( (pargs->phase-1) < pgls->g.raster_fill.width * pgls->g.raster_fill.height ) - { + { int pixel; if ( !hpgl_arg_c_int(pargs, &pixel) ) break; @@ -568,7 +570,7 @@ hpgl_UL(hpgl_args_t *pargs, hpgl_state_t *pgls) } if ( total == 0 ) return e_Range; - + for ( k = 0; k < i; k++ ) gap[k] /= total; @@ -579,7 +581,7 @@ hpgl_UL(hpgl_args_t *pargs, hpgl_state_t *pgls) 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)); - } + } } else { diff --git a/pcl/pgmand.h b/pcl/pgmand.h index 52bab77fc..c9f637205 100644 --- a/pcl/pgmand.h +++ b/pcl/pgmand.h @@ -57,7 +57,7 @@ typedef struct hpgl_command_s { hpgl_command_proc_t proc; byte flags; #define hpgl_cdf_polygon 1 /* execute command even in polygon mode */ -#define hpgl_cdf_lost_mode_cleared 2 /* exectute command only if +#define hpgl_cdf_lost_mode_cleared 2 /* exectute command only if lost mode cleared */ } hpgl_command_definition_t; @@ -200,91 +200,93 @@ bool hpgl_arg_units(P2(hpgl_args_t *pargs, hpgl_real_t *pu)); */ /* commands from pgchar.c -- HP-GL/2 character commands */ -int hpgl_AD(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_CF(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_CP(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_DI(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_DR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_DT(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_DV(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_ES(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_FI(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_FN(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_LB(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_LM(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_LO(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SA(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SB(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SD(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SI(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SL(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SS(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_TD(hpgl_args_t *pargs, hpgl_state_t *pgls); +int hpgl_AD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_CF(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_CP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_DI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_DR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_DT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_DV(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_ES(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_FI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_FN(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_LB(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_LM(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_LO(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SB(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SL(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SS(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_TD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); /* commands from pgcolor.c - HP-GL/2 color vector graphics commands */ -int hpgl_MC(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PC(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_NP(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_CR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PP(hpgl_args_t *pargs, hpgl_state_t *pgls); +int hpgl_MC(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PC(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_NP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_CR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); /* commands from pgconfig.c - HP-GL/2 configuration and status commands */ -int hpgl_CO(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_DF(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_IN(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_IP(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_IR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_IW(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PG(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_RO(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_RP(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SC(hpgl_args_t *pargs, hpgl_state_t *pgls); +int hpgl_CO(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_DF(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_IN(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_IP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_IR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_IW(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PG(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_RO(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_RP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SC(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); /* commands from pglfill.c - HP-GL/2 line and fill attributes commands */ -int hpgl_AC(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_FT(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_LA(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_LT(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PW(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_RF(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SM(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SP(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_SV(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_TR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_UL(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_WU(hpgl_args_t *pargs, hpgl_state_t *pgls); +int hpgl_AC(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_FT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_LA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_LT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PW(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_RF(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SM(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_SV(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_TR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_UL(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_WU(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); /* commands from pgpoly.c -- HP-GL/2 polygon commands */ -int hpgl_EA(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_EP(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_ER(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_EW(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_FP(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PM(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_RA(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_RR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_WG(hpgl_args_t *pargs, hpgl_state_t *pgls); +int hpgl_EA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_EP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_ER(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_EW(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_FP(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PM(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_RA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_RR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_WG(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); /* commands from pgvector.c - HP-GL/2 vector commands */ -int hpgl_AA(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_AR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_AT(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_BR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_BZ(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_CI(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PA(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PD(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PE(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PR(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_PU(hpgl_args_t *pargs, hpgl_state_t *pgls); -int hpgl_RT(hpgl_args_t *pargs, hpgl_state_t *pgls); +int hpgl_AA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_AR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_AT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_BR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_BZ(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_CI(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PA(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PD(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PE(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PR(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_PU(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); +int hpgl_RT(P2(hpgl_args_t *pargs, hpgl_state_t *pgls)); /* commands from pgframe.c -- PCL5/HP-GL/2 picture frame commands */ -int pcl_horiz_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcls); -int pcl_vert_pic_frame_size_decipoints(pcl_args_t *pargs, pcl_state_t *pcls); -int pcl_set_pic_frame_anchor_point(pcl_args_t *pargs, pcl_state_t *pcls); -int pcl_hpgl_plot_horiz_size(pcl_args_t *pargs, pcl_state_t *pcls); -int pcl_hpgl_plot_vert_size(pcl_args_t *pargs, pcl_state_t *pcls); +int pcl_horiz_pic_frame_size_decipoints(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); +int pcl_vert_pic_frame_size_decipoints(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); +int pcl_set_pic_frame_anchor_point(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); +int pcl_hpgl_plot_horiz_size(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); +int pcl_hpgl_plot_vert_size(P2(pcl_args_t *pargs, hpgl_state_t *pgls)); +/* this should find a new home but for now we list it here. */ +int hpgl_print_symbol_mode_char(P1(hpgl_state_t *pgls)); #endif /* pgmand_INCLUDED */ diff --git a/pcl/pgmisc.c b/pcl/pgmisc.c index 359708c0c..80af7c9be 100644 --- a/pcl/pgmisc.c +++ b/pcl/pgmisc.c @@ -11,7 +11,7 @@ void hpgl_set_lost_mode(hpgl_state_t *pgls, hpgl_lost_mode_t lost_mode) { - if ( lost_mode == hpgl_lost_mode_entered ) + if ( lost_mode == hpgl_lost_mode_entered ) { #ifdef INFINITE_LOOP hpgl_args_t args; diff --git a/pcl/pgparse.c b/pcl/pgparse.c index 521741e32..2099e3f4d 100644 --- a/pcl/pgparse.c +++ b/pcl/pgparse.c @@ -161,7 +161,7 @@ call: if ( pst->command ) pst->command = 0; else { /* similarly if we are in lost mode we do not - execute the commands that are only defined to + execute the commands that are only defined to be used when lost mode is cleared. */ if (( pgls->g.lost_mode == hpgl_lost_mode_entered ) && (pst->command->flags & hpgl_cdf_lost_mode_cleared) diff --git a/pcl/pgpoly.c b/pcl/pgpoly.c index 659666eda..9450c2866 100644 --- a/pcl/pgpoly.c +++ b/pcl/pgpoly.c @@ -68,7 +68,7 @@ hpgl_wedge(hpgl_args_t *pargs, hpgl_state_t *pgls) if ( sweep == 360.0 ) /* HAS needs epsilon */ hpgl_call(hpgl_add_arc_to_path(pgls, pgls->g.pos.x, pgls->g.pos.y, - radius, 0.0, 360.0, chord, true, + radius, 0.0, 360.0, chord, true, hpgl_plot_draw_absolute, true)); else /* draw the 2 lines and the arc using 3 point this does seem @@ -86,13 +86,13 @@ hpgl_wedge(hpgl_args_t *pargs, hpgl_state_t *pgls) hpgl_plot_move_absolute, true)); hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, hpgl_plot_draw_absolute, true)); - hpgl_call(hpgl_add_arc_3point_to_path(pgls, - x1, y1, + hpgl_call(hpgl_add_arc_3point_to_path(pgls, + x1, y1, x2, y2, x3, y3, chord, hpgl_plot_draw_absolute)); } - + /* exit polygon mode, this should close the path and the wedge is complete */ hpgl_args_set_int(pargs,2); @@ -150,7 +150,7 @@ hpgl_EW(hpgl_args_t *pargs, hpgl_state_t *pgls) private hpgl_rendering_mode_t hpgl_get_poly_render_mode(hpgl_state_t *pgls) { - return (((pgls->g.fill.type == hpgl_fill_hatch) || + return (((pgls->g.fill.type == hpgl_fill_hatch) || (pgls->g.fill.type == hpgl_fill_crosshatch)) ? hpgl_rm_clip_and_fill_polygon : hpgl_rm_polygon); @@ -165,13 +165,13 @@ hpgl_FP(hpgl_args_t *pargs, hpgl_state_t *pgls) if ( hpgl_arg_c_int(pargs, &method) && (method & ~1) ) return e_Range; - pgls->g.fill_type = (method == 0) ? + pgls->g.fill_type = (method == 0) ? hpgl_even_odd_rule : hpgl_winding_number_rule; /* preserve the current path and copy the polygon buffer to the current path */ hpgl_call(hpgl_gsave(pgls)); hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, + hpgl_call(hpgl_draw_current_path(pgls, hpgl_get_poly_render_mode(pgls))); hpgl_call(hpgl_grestore(pgls)); return 0; @@ -182,12 +182,12 @@ int hpgl_PM(hpgl_args_t *pargs, hpgl_state_t *pgls) { int op; - if ( hpgl_arg_c_int(pargs, &op) == 0 ) + if ( hpgl_arg_c_int(pargs, &op) == 0 ) op = 0; switch( op ) { - case 0 : + case 0 : /* clear the current path if there is one */ hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector)); /* clear the polygon buffer as well */ @@ -195,9 +195,9 @@ hpgl_PM(hpgl_args_t *pargs, hpgl_state_t *pgls) /* global flag to indicate that we are in polygon mode */ pgls->g.polygon_mode = true; /* save the pen state, to be restored by PM2 */ - hpgl_save_pen_state(pgls, + hpgl_save_pen_state(pgls, &pgls->g.polygon.pen_state, - hpgl_pen_all); + hpgl_pen_down | hpgl_pen_pos); break; case 1 : hpgl_call(hpgl_close_current_path(pgls)); @@ -214,11 +214,11 @@ hpgl_PM(hpgl_args_t *pargs, hpgl_state_t *pgls) /* restore the pen state */ hpgl_restore_pen_state(pgls, &pgls->g.polygon.pen_state, - hpgl_pen_all); + hpgl_pen_down | hpgl_pen_pos); break; default: return e_Range; - } + } return 0; } @@ -228,7 +228,7 @@ hpgl_RA(hpgl_args_t *pargs, hpgl_state_t *pgls) { hpgl_call(hpgl_rectangle(pargs, pgls, 0)); hpgl_call(hpgl_copy_polygon_buffer_to_current_path(pgls)); - hpgl_call(hpgl_draw_current_path(pgls, + hpgl_call(hpgl_draw_current_path(pgls, hpgl_get_poly_render_mode(pgls))); return 0; } diff --git a/pcl/pgstate.h b/pcl/pgstate.h index 675dc17f9..fffb5fa1e 100644 --- a/pcl/pgstate.h +++ b/pcl/pgstate.h @@ -49,8 +49,8 @@ typedef struct hpgl_line_type_s { } hpgl_line_type_t; typedef struct hpgl_path_state_s { - bool have_first_moveto; - gx_path path; + bool have_first_moveto; + gx_path path; } hpgl_path_state_t; /* Define rendering modes - character, polygon, or vector. @@ -116,12 +116,12 @@ typedef enum { typedef struct pcl_hpgl_state_s { /* Chapter 17 lost mode (pgmisc.c) */ - + /* According to PCLTRM IN, PG, RP and PA with args in range clears lost mode. Note that all these commands have PA with valid args as a side effect so only PA needs to clear lost mode. */ - hpgl_lost_mode_t lost_mode; + hpgl_lost_mode_t lost_mode; /* Chapter 18 (pgframe.c) */ @@ -160,7 +160,6 @@ typedef struct pcl_hpgl_state_s { gs_point P1, P2; /* in plotter units */ /* Chapter 20 (pgvector.c) */ - int move_or_draw; /* hpgl_plot_move/draw */ int relative_coords; /* hpgl_plot_absolute/relative */ gs_point pos; diff --git a/pcl/pgvector.c b/pcl/pgvector.c index 1c1e98768..fd734fb06 100644 --- a/pcl/pgvector.c +++ b/pcl/pgvector.c @@ -35,20 +35,20 @@ hpgl_arc(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) x_current = pgls->g.pos.x; y_current = pgls->g.pos.y; - if ( relative ) + if ( relative ) { x_center += x_current; y_center += y_current; } - radius = + 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, + hpgl_call(hpgl_add_arc_to_path(pgls, x_center, y_center, + radius, start_angle, sweep, (sweep < 0.0 ) ? -chord_angle : chord_angle, false, pgls->g.move_or_draw, true)); @@ -101,10 +101,10 @@ hpgl_bezier(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) * we reset the argument bookkeeping after each group. */ for ( ; ; ) - { + { hpgl_real_t coords[6]; int i; - + for ( i = 0; i < 6 && hpgl_arg_units(pargs, &coords[i]); ++i ) ; switch ( i ) @@ -120,27 +120,25 @@ hpgl_bezier(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) default: 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], + x_start + coords[0], y_start + coords[1], - x_start + coords[2], + x_start + coords[2], y_start + coords[3], - x_start + coords[4], + 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], + 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); } @@ -157,36 +155,34 @@ hpgl_plot(hpgl_args_t *pargs, hpgl_state_t *pgls, hpgl_plot_function_t func) */ hpgl_real_t x, y; + if ( hpgl_plot_is_move(func) ) + hpgl_call(hpgl_close_path(pgls)); - while ( hpgl_arg_units(pargs, &x) && hpgl_arg_units(pargs, &y) ) - { + while ( hpgl_arg_units(pargs, &x) && hpgl_arg_units(pargs, &y) ) + { pargs->phase = 1; /* we have arguments */ hpgl_call(hpgl_add_point_to_path(pgls, x, y, func, true)); /* Prepare for the next set of points. */ if ( pgls->g.symbol_mode != 0 ) - hpgl_call(hpgl_print_symbol_mode_char(pgls, pgls->g.symbol_mode)); + hpgl_call(hpgl_print_symbol_mode_char(pgls)); hpgl_args_init(pargs); } /* check for no argument case */ - if ( !pargs->phase) + if ( !pargs->phase) { if ( hpgl_plot_is_relative(func) ) - { - hpgl_call(hpgl_add_point_to_path(pgls, 0.0, 0.0, func, true)); - } + /*hpgl_call(hpgl_add_point_to_path(pgls, 0.0, 0.0, func, true)) */; else { gs_point cur_point; - hpgl_call(hpgl_get_current_position(pgls, &cur_point)); - hpgl_call(hpgl_add_point_to_path(pgls, cur_point.x, + 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, pgls->g.symbol_mode)); } - + if ( pgls->g.symbol_mode != 0 ) + hpgl_call(hpgl_print_symbol_mode_char(pgls)); pgls->g.carriage_return_pos = pgls->g.pos; return 0; } @@ -244,31 +240,21 @@ int hpgl_CI(hpgl_args_t *pargs, hpgl_state_t *pgls) { hpgl_real_t radius, chord = 5; - hpgl_pen_state_t saved_pen_state; bool reset_ctm = true; + gs_point pos = pgls->g.pos; /* center */ if ( !hpgl_arg_units(pargs, &radius) ) return e_Range; hpgl_arg_c_real(pargs, &chord); - hpgl_save_pen_state(pgls, &saved_pen_state, hpgl_pen_pos); /* draw the arc/circle */ hpgl_call(hpgl_add_arc_to_path(pgls, pgls->g.pos.x, pgls->g.pos.y, - radius, 0.0, 360.0, chord, true, + radius, 0.0, 360.0, chord, true, hpgl_plot_draw_absolute, reset_ctm)); - /* It appears from experiment that a CI in polygon mode leaves - the pen up .. or something like that. */ - if ( pgls->g.polygon_mode ) - { - hpgl_args_t args; - hpgl_restore_pen_state(pgls, &saved_pen_state, hpgl_pen_pos); - hpgl_args_setup(&args); - hpgl_PU(&args, pgls); - } - else - { - hpgl_call(hpgl_draw_arc(pgls)); - hpgl_restore_pen_state(pgls, &saved_pen_state, hpgl_pen_pos); - } + if ( !pgls->g.polygon_mode ) + hpgl_call(hpgl_draw_arc(pgls)); + /* move back to the center */ + hpgl_call(hpgl_add_point_to_path(pgls, pos.x, pos.y, + hpgl_plot_move_absolute, true)); /* restore the ctm - i.e. the ctm with picture frame scaling */ hpgl_set_ctm(pgls); return 0; @@ -384,7 +370,7 @@ hpgl_PE(hpgl_args_t *pargs, hpgl_state_t *pgls) if ( (ch & 127) <= 32 || (ch & 127) == 127 ) continue; pargs->source.ptr = p - 1; - { + { int32 xy[2]; hpgl_plot_function_t func; @@ -417,10 +403,10 @@ pe_args(hpgl_args_t *pargs, int32 *pvalues, int count) for ( i = 0; i < count; ++i ) { int32 value = 0; int shift = 0; - + for ( ; ; ) { int ch; - + if ( p >= rlimit ) return false; ch = *++p; diff --git a/pcl/rtcrastr.c b/pcl/rtcrastr.c index 0657889a3..ef1a1f9fd 100644 --- a/pcl/rtcrastr.c +++ b/pcl/rtcrastr.c @@ -62,7 +62,7 @@ uncompress_row_9(pcl_raster_row_t *row, uint in_size, stream_cursor_read *pr) /* ------ Commands ------ */ /* This replaces the implementation in pcraster.c. */ -private int /* ESC * r <cap_enum> A */ +private int /* ESC * r <cap_enum> A */ pcl_c_start_raster_graphics(pcl_args_t *pargs, pcl_state_t *pcls) { int setting = int_arg(pargs); diff --git a/pcl/rtmisc.c b/pcl/rtmisc.c index d2028d2b8..dd652d97b 100644 --- a/pcl/rtmisc.c +++ b/pcl/rtmisc.c @@ -10,7 +10,7 @@ #include "pgdraw.h" /* for hpgl_add_pcl_point_to_path() */ #include "pgmisc.h" /* for hpgl_call */ #include "gsmemory.h" -#include "gsrop.h" +#include "gsrop.h" #include "gscoord.h" #include "pcdraw.h" @@ -52,7 +52,7 @@ pcl_source_transparency_mode(pcl_args_t *pargs, pcl_state_t *pcls) /* ---------------- Chapter 18 ---------------- */ -private int /* ESC % <enum> B */ +private int /* ESC % <enum> B */ rtl_enter_hpgl_mode(pcl_args_t *pargs, pcl_state_t *pcls) { int i = int_arg(pargs); @@ -84,7 +84,7 @@ rtl_enter_hpgl_mode(pcl_args_t *pargs, pcl_state_t *pcls) /* We export this so we can call it from HP-GL/2 configurations. */ /* Note that it returns 1 iff it changed the PCL CAP. */ -int /* ESC % <enum> A */ +int /* ESC % <enum> A */ rtl_enter_pcl_mode(pcl_args_t *pargs, pcl_state_t *pcls) { int b = int_arg(pargs) & 1; |