diff options
-rw-r--r-- | pcl/news-pcl | 138 | ||||
-rw-r--r-- | pcl/pcdraw.c | 52 | ||||
-rw-r--r-- | pcl/pcdraw.h | 16 | ||||
-rw-r--r-- | pcl/pcifont.c | 5 | ||||
-rw-r--r-- | pcl/pcl_ugcc.mak | 3 | ||||
-rw-r--r-- | pcl/pclfont.c | 214 | ||||
-rw-r--r-- | pcl/pcmain.c | 2 | ||||
-rw-r--r-- | pcl/pcprint.c | 8 | ||||
-rw-r--r-- | pcl/pcsfont.c | 3 | ||||
-rw-r--r-- | pcl/pcsymbol.c | 41 | ||||
-rw-r--r-- | pcl/pctext.c | 78 | ||||
-rw-r--r-- | pcl/pcursor.c | 2 | ||||
-rw-r--r-- | pcl/pgconfig.c | 37 | ||||
-rw-r--r-- | pcl/pgdraw.c | 251 | ||||
-rw-r--r-- | pcl/pgdraw.h | 20 | ||||
-rw-r--r-- | pcl/pgframe.c | 21 | ||||
-rw-r--r-- | pcl/pglabel.c | 34 | ||||
-rw-r--r-- | pcl/pglfill.c | 60 | ||||
-rw-r--r-- | pcl/pgstate.h | 3 | ||||
-rw-r--r-- | pcl/pgvector.c | 23 |
20 files changed, 624 insertions, 387 deletions
diff --git a/pcl/news-pcl b/pcl/news-pcl index f39a1b68e..d38264a12 100644 --- a/pcl/news-pcl +++ b/pcl/news-pcl @@ -6,6 +6,133 @@ This file, NEWS-PCL, describes the changes in the most recent releases of Aladdin's PCL5 code, in reverse chronological order. +Version 0.38 (11/20/97) +======================= + +(LPD) + - Adds PCL XL output to the Unix makefile. Note that this required +a minor, backward-compatible change in common/ugcc_top.mak and +common/watc_top.mak. (pcl_ugcc.mak) + - Adds fonts/ to the list of directories to search for fonts. +(pcmain.c) + +The following PCL5e commands and facilities are parsed correctly, but their +functionality is not implemented yet: + - Select default font (ESC (|) 3 @). (pcfont.c) + - Conditional pattern rotation (ESC * p # R). (pcprint.c) + - Assign font id to copy of current font (ESC * c 6 F). (pcsfont.c) + - Continuation blocks for character data (for ESC ( s # W). +(pcsfont.c) + - Variable text path (ESC & c # T). (pctext.c) + +The following HP-GL/2 commands and facilities are still unimplemented: + - Double-byte characters (LM command is implemented but has no + effect). + +(HAS) Fixes bug in design window origin for Intellifonts. (pcifont.c) + +Version 0.37 (11/6/97) +===================== + +Fixes problem in updated LJ5 FTS and integrates complete set of +resident fonts except lineprinter. + +The only new functionality in this release is label origin mode that +allows positioning of the hpgl/2 character origin at the current pcl +cursor position, (pglabel.c) and the new fonts. + +(LPD) added documentation for common makefiles and added gdevbbox and +bbox.dev dependencies. + +(HAS) Changes associated with bug LJ5 FTS fixes include: + +- Pattern phases/rotation not correct. +pcdraw.c:pcl_set_drawing_color_rotation() pattern phase set here, +added device space origin parameter, removed reflection code. Added +function pcdraw.c:pcl_set_drawing_color() initializes rotation and +pattern origin. Updated prototypes for changes are in pcdraw.h. +pcprint.c:pcl_set_pattern_reference_point() updated to only set state +values that affect how the reference point will be set. +- pclfont.c:pcl_lood_built_in_fonts() restructured to support new +resident fonts. +- pcsfont.c:pcl_font_header() interpreted bitmap font height +incorrectly, using 1/4 points instead of 1/4 dots. +- pcltext.c:pcl_show_chars() restructure to properly clip/drop text at +the right margin. This will be a major performance bottleneck since +the code now renders one character at a time. This will be addressed +when the FTS tests are correct. +- pcltext.c:pcl_text() removed device space clipping code. +- pcltext.c:pcl_text() explicit hmi was ignored for proportional fonts. +- pccursor.c:move_down() half line was not working because function +was using global vmi instead of passed in parameter. +- pgconfig.c:hpgl_picture_frame_coords() picture frame coordinates not +specified correctly. +- pgdraw.c:hpgl_set_picture_frame_scaline() new function added to +simplify hpgl_set_ctm(). +- pgdraw.c: several functions were ignoring GS return values. This is +now fixed. +- pgdraw.c:hpgl_set_drawing_color() updated to handle pcl drawing +attributes for rendering characters. +- pgdraw.c and pgvector.c: hpgl_plot_function_t is not "fungible" with +bool. This has been straightened out. +- pgframe.c - added state variable to indicate if plot mode has been set. +- pglfill.c: hpgl_PU() and hpgl_WU() - redone. +- pcsymbol.c:pcl_define_symbol_set() symbol codes not byte swapped. + +Known problems: + +-The left margin is set to the left of the right margin. PCLTRM 5-15 +says the left margin should not be reset. anomaly. fts 111. +Height of bars is incorrect. We use a scalable courier font. +anomaly. fts 140. +-Pattern reference point is not the same as the 6mp. We are doing what +the manual says (PCLTRM 13-16), using a default reference point of 0, +0, the 6mp does not seem to do the same. anomaly. fts 102, 125, 174, +194. 225, 1072, 1074, 1092, 1094, 2276. +-Space character is still marginally different this results in an +accumulation error on the right margin. Bug. fts 260. +-Wrong or missing glyphs in character set. Bug. fts 260, 261, 263, +264, 270, 271, 274, 1810, 1820, 2063, 1150, 2330. +-Extra space before string. Bug. fts 311. +-Font selection incorrect. bug. fts 291, 341, 390, 401, 2272, 1612, +1700, 2300. +-Wrong baseline for string. intellifont scalar not properly +interpreting measuring baseline for font. fts 342, 351, 360. 410, +411. +-Dashed lines not offset wrt anchor corner dashed lines are not offset +for gl/2 fills. fts 1132, 1133. +-Character fill mode not working for stick fonts. I believe this is an +HP bug since vectors should be filled with using SV and not FT since +stick fonts are actually vector data. anomaly. fts 1221. +-The glyph for "t" in a dounloaded intellifont font is corrupt. The +number of auxillary point in the font is set to 0xffff. I have no +documentation that says what to do if this is the case. Bug. fts +1800. +-GL/2 transparency problem. Bug. fts 1541, 1542, 1563. 1810 page 3. +-GL/2 anchor corner. Bug fts 1611, 1620, 1621, 1630. +-wrong font selected - 1612, 1700, 2300. +-black boxes on panel border are too large - 1613. +-one of the scaling modes is not correct 1634, 1635. +-gl/2 vector fill not working properly with character data and gl/2 +-vector fills not properly implemented with fill polygon mode. we will +probably need to rewrite the filling algorithms to handle both +-odd-even and non-zero winding fills. Bug. fts - 1810 +-stray line probably due to clipping difference Bug. 1810 page 5. +-extra raster data Bug. 1833, 1836 +-wrong pattern - pattern state not properly updated. Bug. fts - 2040, +2041, 2042 +-missing line. Bug. fts 2120, 2122, 2125. +-missing line drawing characters from character set. Bug. fts 2240. +-missing overlay - hpgl/2 in pcl5 macro not properly implemented. Bug +fts 2290, 2291. +-downloaded font not rendered Bug fts 2321. +-not selecting correct secondary font. Bug fts 2322 +-stray lines on bezier curver Bug fts 2342, 2352 +-raster operation incorrect and pixel placement not implemented. Bug +fts 2380-2412. +-text parsing method - double byte characters not done. Bug fts +2420-2422. + Version 0.36 (9/4/97) ===================== @@ -82,17 +209,6 @@ univers typeface. We do not have a univers typeface in our font repotoire. 54. pen color wrong - 1512. *55. left offset clipped incorrectly - 1761. -The following PCL5e commands and facilities are still unimplemented: - - Select default font (ESC (|) 3 @). (pcfont.c) - - Assign font id to copy of current font (ESC * c 6 F). (pcsfont.c) - - Continuation blocks for character data (for ESC ( s # W). -(pcsfont.c) - - Variable text path (ESC & c # T). (pctext.c) - -The following HP-GL/2 commands and facilities are still unimplemented: - - Double-byte characters (LM command is implemented but has no - effect). - (LPD) Fixes bugs: - Symbol sets weren't supported in GL/2. (pglabel.c) - The Windows Symbol and Wingdings fonts were identified as bound diff --git a/pcl/pcdraw.c b/pcl/pcdraw.c index 952d5d42f..5462ba812 100644 --- a/pcl/pcdraw.c +++ b/pcl/pcdraw.c @@ -386,8 +386,7 @@ pcl_makebitmappattern(gs_client_color *pcc, const gx_tile_bitmap *tile, gs_state *pgs, floatp scale_x, floatp scale_y, int rotation /* 0..3 */, uint id) { gs_client_pattern pat; - gs_matrix mat, dmat, smat; - bool d_reflected, s_reflected; + gs_matrix mat, smat; int angle = rotation * 90; if ( tile->raster != bitmap_raster(tile->size.x) ) @@ -403,23 +402,11 @@ pcl_makebitmappattern(gs_client_color *pcc, const gx_tile_bitmap *tile, pat.YStep = tile->rep_height; pat.PaintProc = pcl_bitmap_PaintProc; pat.client_data = tile->data; - gs_defaultmatrix(pgs, &dmat); gs_currentmatrix(pgs, &smat); gs_make_identity(&mat); gs_setmatrix(pgs, &mat); gs_make_scaling(scale_x, scale_y, &mat); - /* - * We know that the default matrix imposes a PCL coordinate system, - * i.e., (0,0) in the upper left corner. Check whether the current - * matrix is reflected with respect to this, e.g., for HP-GL/2. - */ - d_reflected = dmat.xy * dmat.yx > dmat.xx * dmat.yy; - s_reflected = smat.xy * smat.yx > smat.xx * smat.yy; - if ( s_reflected != d_reflected ) - mat.yy = -mat.yy; - else - angle = -angle; - gs_matrix_rotate(&mat, angle, &mat); + gs_matrix_rotate(&mat, -angle, &mat); /* * Reset the current color in the graphics state so that we don't * wind up with a stale pointer to a deleted pattern. @@ -458,7 +445,7 @@ pcl_bitmap_PaintProc(const gs_client_color *pcolor, gs_state *pgs) /* Note that we pass the pattern rotation explicitly. */ int pcl_set_drawing_color_rotation(pcl_state_t *pcls, pcl_pattern_type_t type, - const pcl_id_t *pid, pl_dict_t *patterns, int rotation) + const pcl_id_t *pid, pl_dict_t *patterns, int rotation, gs_point *origin) { gs_state *pgs = pcls->pgs; gs_pattern_instance **ppi; gs_int_point resolution; @@ -618,10 +605,43 @@ pcl_set_drawing_color_rotation(pcl_state_t *pcls, pcl_pattern_type_t type, *ppi = ccolor.pattern; } gs_setpattern(pgs, &ccolor); + gs_sethalftonephase(pgs, origin->x, origin->y); } return 0; } +/* set pcl's drawing color. Uses pcl state values to determine + rotation and translation of patterns */ + int +pcl_set_drawing_color(pcl_state_t *pcls, pcl_pattern_type_t type, const pcl_id_t *pid) +{ + gs_point pattern_origin; + gs_point pattern_origin_device; + int rotation; + /* if the pattern reference point has been set than we use the + current cap otherwise the coordinate 0, 0 is used. The 0,0 + reference point does not seem to be used on the 6mp but + this is in accordance with PCLTRM 13-16. */ + if ( pcls->shift_patterns ) + { + pattern_origin.x = (float)pcls->cap.x; + pattern_origin.y = (float)pcls->cap.y; + } + else + { + pattern_origin.x = 0.0; + pattern_origin.y = 0.0; + } + gs_transform(pcls->pgs, pattern_origin.x, pattern_origin.y, + &pattern_origin_device); + /* setting the pattern reference point also decides whether we + rotate patterns, see pcl_set_pattern_reference_point(). */ + rotation = pcls->rotate_patterns ? pcls->print_direction : 0; + pcl_set_drawing_color_rotation(pcls, type, pid, + &pcls->patterns, rotation, &pattern_origin_device); + return 0; +} + /* Initialization */ private int pcdraw_do_init(gs_memory_t *mem) diff --git a/pcl/pcdraw.h b/pcl/pcdraw.h index 5a8b8dc22..40d6ca18e 100644 --- a/pcl/pcdraw.h +++ b/pcl/pcdraw.h @@ -85,14 +85,16 @@ typedef struct pcl_pattern_s { /* Set the color and pattern for drawing. */ /* We pass the pattern rotation explicitly, since it is different */ /* for PCL and HP-GL. The rotation is expressed as the multiple of */ -/* 90 degrees (i.e., 0..3) to be added to the page orientation. */ -int pcl_set_drawing_color_rotation(P5(pcl_state_t *pcls, +/* 90 degrees (i.e., 0..3) to be added to the page orientation. Also */ +/* 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, - int rotation)); -#define pcl_set_drawing_color(pcls, type, pid)\ - pcl_set_drawing_color_rotation(pcls, type, pid, &(pcls)->patterns,\ - ((pcls)->rotate_patterns ?\ - (pcls)->print_direction : 0)) + 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, + const pcl_id_t *pid)); #endif /* pcdraw_INCLUDED */ diff --git a/pcl/pcifont.c b/pcl/pcifont.c index 581c66c04..c0e10603c 100644 --- a/pcl/pcifont.c +++ b/pcl/pcifont.c @@ -224,7 +224,10 @@ pcl_intelli_char_width(const pl_font_t *plfont, const pl_symbol_map_t *map, void pcl_fill_in_intelli_font(gs_font_base *pfont, long unique_id) { /* Intellifonts have an 8782-unit design space. */ - gs_make_scaling(1.0/8782, 1.0/8782, &pfont->FontMatrix); + { gs_matrix mat; + gs_make_scaling(1.0/8782, 1.0/8782, &mat); + gs_matrix_translate(&mat, -2980.0, -5380.0, &pfont->FontMatrix); + } pfont->FontType = ft_user_defined; pfont->BitmapWidths = true; pfont->ExactSize = fbit_use_outlines; diff --git a/pcl/pcl_ugcc.mak b/pcl/pcl_ugcc.mak index 57c4b8103..286ec6c74 100644 --- a/pcl/pcl_ugcc.mak +++ b/pcl/pcl_ugcc.mak @@ -42,7 +42,8 @@ CCLD=gcc DEVICE_DEVS=x11.dev x11mono.dev x11alpha.dev x11cmyk.dev\ djet500.dev ljet4.dev\ pcxmono.dev pcxgray.dev\ - pbmraw.dev pgmraw.dev ppmraw.dev + pbmraw.dev pgmraw.dev ppmraw.dev\ + pxlmono.dev pxlcolor.dev # Generic makefile include $(COMMONDIR)/ugcc_top.mak diff --git a/pcl/pclfont.c b/pcl/pclfont.c index f346d9b55..40603b399 100644 --- a/pcl/pclfont.c +++ b/pcl/pclfont.c @@ -28,59 +28,148 @@ bool pcl_load_built_in_fonts(pcl_state_t *pcls, const char *prefixes[]) { const char **pprefix; - typedef struct font_hack { + typedef struct font_resident { const char *ext_name; pl_font_params_t params; byte character_complement[8]; - } font_hack_t; - static const font_hack_t hack_table[] = { - /* - * Symbol sets, typeface family values, and character complements - * are faked; they do not (necessarily) match the actual fonts. - */ + } font_resident_t; + static const font_resident_t resident_table[] = { + /* + * Symbol sets, typeface family values, and character complements + * are faked; they do not (necessarily) match the actual fonts. + */ #define C(b) ((byte)((b) ^ 0xff)) #define cc_alphabetic\ - { C(0), C(0), C(0), C(0), C(0xff), C(0xc0), C(0), C(plgv_Unicode) } + { 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_Unicode) } #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_Unicode) } #define pitch_1 fp_pitch_value_cp(1) /* * Per TRM 23-87, PCL5 printers are supposed to have Univers * and CG Times fonts. Substitute Arial for Univers and * Times for CG Times. */ -#define tf_arial 4148 /* Univers; should be 16602 */ -#define tf_cour 4099 -#define tf_times 4101 /* CG Times; should be 16901 */ - {"arial", {0, 1, pitch_1, 0, 0, 0, tf_arial}, cc_alphabetic }, - {"arialbd", {0, 1, pitch_1, 0, 0, 3, tf_arial}, cc_alphabetic }, - {"arialbi", {0, 1, pitch_1, 0, 1, 3, tf_arial}, cc_alphabetic }, - {"ariali", {0, 1, pitch_1, 0, 1, 0, tf_arial}, cc_alphabetic }, - {"cour", {0, 0, pitch_1, 0, 0, 0, tf_cour}, cc_alphabetic }, - {"courbd", {0, 0, pitch_1, 0, 0, 3, tf_cour}, cc_alphabetic }, - {"courbi", {0, 0, pitch_1, 0, 1, 3, tf_cour}, cc_alphabetic }, - {"couri", {0, 0, pitch_1, 0, 1, 0, tf_cour}, cc_alphabetic }, - {"times", {0, 1, pitch_1, 0, 0, 0, tf_times}, cc_alphabetic }, - {"timesbd", {0, 1, pitch_1, 0, 0, 3, tf_times}, cc_alphabetic }, - {"timesbi", {0, 1, pitch_1, 0, 1, 3, tf_times}, cc_alphabetic }, - {"timesi", {0, 1, pitch_1, 0, 1, 0, tf_times}, cc_alphabetic }, - /* Note that "bound" TrueType fonts are indexed starting at 0xf000, */ - /* not at 0. */ - {"symbol", {621,1,pitch_1, 0, 0, 0, 16686}, cc_symbol }, - {"wingding",{2730,1,pitch_1,0, 0, 0, 19114}, cc_dingbats }, - {NULL, {0, 0, pitch_1, 0, 0, 0, 0} } + /* hack the vendor value to be agfa's. */ +#define agfa (4096) + /* the actual typeface number is vendor + base value. Base + values are found in the pcl 5 Comparison guide - Appendix + C-6. We can add a parameter for vendor if necessary, for + now it is agfa. */ +#define face_val(base_value, vendor) (vendor + (base_value)) + /* definition for style word as defined on 11-19 PCLTRM */ +#define style_word(posture, width, structure) \ + ((posture) + (4 * (width)) + (32 * (structure))) + {"letri", {0, 0, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(6, agfa)}, cc_alphabetic}, + {"letrbi", {0, 0, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(6, agfa)}, cc_alphabetic}, + {"letrb", {0, 0, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(6, agfa)}, cc_alphabetic}, + {"letr", {0, 0, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(6, agfa)}, cc_alphabetic }, + {"courbi", {0, 0, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(3, agfa)}, cc_alphabetic}, + {"couri", {0, 0, pitch_1, 0, style_word(1, 0, 0), + 0, face_val(3, agfa)}, cc_alphabetic }, + {"courbd", {0, 0, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(3, agfa)}, cc_alphabetic }, + {"cour", {0, 0, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(3, agfa)}, cc_alphabetic}, + /* Note that "bound" TrueType fonts are indexed starting at 0xf000, */ + /* not at 0. */ + {"wingding", {18540, 1, pitch_1,0, style_word(0, 0, 0), 0, + face_val(2730, agfa)}, cc_dingbats}, + {"symbol", {621, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(302, agfa)}, cc_symbol}, + {"timesbi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(517, agfa)}, cc_alphabetic}, + {"timesi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(517, agfa)}, cc_alphabetic}, + {"timesbd", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(517, agfa)}, cc_alphabetic}, + {"times", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(517, agfa)}, cc_alphabetic}, + {"arialbi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(218, agfa)}, cc_alphabetic}, + {"ariali", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(218, agfa)}, cc_alphabetic}, + {"arialbd", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(218, agfa)}, cc_alphabetic}, + {"arial", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(218, agfa)}, cc_alphabetic}, + {"albrmdi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(266, agfa)}, cc_alphabetic}, + {"albrxb", {0, 1, pitch_1, 0, style_word(0, 0, 0), 4, + face_val(266, agfa)}, cc_alphabetic}, + {"albrmd", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(266, agfa)}, cc_alphabetic}, + {"mari", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(201, agfa)}, cc_alphabetic}, + {"garrkh", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(101, agfa)}, cc_alphabetic}, + {"garak", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(101, agfa)}, cc_alphabetic}, + {"garrah", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(101, agfa)}, cc_alphabetic}, + {"garaa", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(101, agfa)}, cc_alphabetic}, + {"antoi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(72, agfa)}, cc_alphabetic}, + {"antob", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(72, agfa)}, cc_alphabetic}, + {"anto", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(72, agfa)}, cc_alphabetic }, + {"univcbi", {0, 1, pitch_1, 0, style_word(1, 1, 0), 3, + face_val(52, agfa)}, cc_alphabetic}, + {"univmci", {0, 1, pitch_1, 0, style_word(1, 1, 0), 0, + face_val(52, agfa)}, cc_alphabetic}, + {"univcb", {0, 1, pitch_1, 0, style_word(0, 1, 0), 3, + face_val(52, agfa)}, cc_alphabetic}, + {"univmc", {0, 1, pitch_1, 0, style_word(0, 1, 0), 0, + face_val(52, agfa)}, cc_alphabetic}, + {"univbi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(52, agfa)}, cc_alphabetic}, + {"univmi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(52, agfa)}, cc_alphabetic}, + {"univb", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(52, agfa)}, cc_alphabetic}, + {"univm", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(52, agfa)}, cc_alphabetic }, + {"clarbc", {0, 1, pitch_1, 0, style_word(0, 1, 0), 3, + face_val(44, agfa)}, cc_alphabetic}, + {"coro", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(20, agfa)}, cc_alphabetic}, + {"cgombi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(17, agfa)}, cc_alphabetic}, + {"cgomi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(17, agfa)}, cc_alphabetic}, + {"cgomb", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(17, agfa)}, cc_alphabetic}, + {"cgom", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(17, agfa)}, cc_alphabetic}, + {"cgtibi", {0, 1, pitch_1, 0, style_word(1, 0, 0), 3, + face_val(5, agfa)}, cc_alphabetic}, + {"cgtii", {0, 1, pitch_1, 0, style_word(1, 0, 0), 0, + face_val(5, agfa)}, cc_alphabetic}, + {"cgtib", {0, 1, pitch_1, 0, style_word(0, 0, 0), 3, + face_val(5, agfa)}, cc_alphabetic}, + {"cgti", {0, 1, pitch_1, 0, style_word(0, 0, 0), 0, + face_val(5, agfa)}, cc_alphabetic}, + {NULL, {0, 0, pitch_1, 0, 0, 0, 0} } #undef C #undef cc_alphabetic #undef cc_symbol #undef cc_dingbats +#undef pitch_1 +#undef agfa_value +#undef face_val }; - const font_hack_t *hackp; - pl_font_t *font_found[countof(hack_table)]; + const font_resident_t *residentp; + pl_font_t *font_found[countof(resident_table)]; bool found_some = false; byte key[3]; - int i; /* This initialization was moved from the do_reset procedures to * this point to localize the font initialization in the state @@ -96,14 +185,13 @@ pcl_load_built_in_fonts(pcl_state_t *pcls, const char *prefixes[]) /* IDs that could conflict with user-defined ones. */ key[0] = key[1] = key[2] = 0; for ( pprefix = prefixes; *pprefix != 0; ++pprefix ) - for ( hackp = hack_table; hackp->ext_name != 0; ++hackp ) - if ( !font_found[hackp - hack_table] ) + for ( residentp = resident_table; residentp->ext_name != 0; ++residentp ) + if ( !font_found[residentp - resident_table] ) { char fname[150]; FILE *fnp; pl_font_t *plfont; - strcpy(fname, *pprefix); - strcat(fname, hackp->ext_name); + strcat(fname, residentp->ext_name); strcat(fname, ".ttf"); if ( (fnp=fopen(fname, gp_fmode_rb)) == NULL ) continue; @@ -119,7 +207,7 @@ pcl_load_built_in_fonts(pcl_state_t *pcls, const char *prefixes[]) dprintf1("Loaded %s\n", fname); #endif plfont->storage = pcds_internal; - if ( hackp->params.symbol_set != 0 ) + if ( residentp->params.symbol_set != 0 ) plfont->font_type = plft_8bit; /* * Don't smash the pitch, which was obtained @@ -127,50 +215,24 @@ pcl_load_built_in_fonts(pcl_state_t *pcls, const char *prefixes[]) */ { pl_font_pitch_t save_pitch; save_pitch = plfont->params.pitch; - plfont->params = hackp->params; + plfont->params = residentp->params; plfont->params.pitch = save_pitch; } memcpy(plfont->character_complement, - hackp->character_complement, 8); + residentp->character_complement, 8); pl_dict_put(&pcls->built_in_fonts, key, sizeof(key), plfont); key[sizeof(key) - 1]++; - font_found[hackp - hack_table] = plfont; + font_found[residentp - resident_table] = plfont; found_some = true; } - - /* Create fake condensed versions of the Arial ("Univers") fonts. */ - - for ( i = 0; i < 4; ++i ) - if ( font_found[i] ) - { const pl_font_t *orig_font = font_found[i]; - gs_font_type42 *pfont = - gs_alloc_struct(pcls->memory, gs_font_type42, - &st_gs_font_type42, - "pl_tt_load_font(gs_font_type42)"); - pl_font_t *plfont = - pl_alloc_font(pcls->memory, "pl_tt_load_font(pl_font_t)"); - int code; - - if ( pfont == 0 || plfont == 0 ) - return_error(gs_error_VMerror); -#define factor 0.7 - /* Condense the Type 42 font. */ - *pfont = *(const gs_font_type42 *)orig_font->pfont; - pfont->FontMatrix.xx *= factor; - pfont->FontBBox.p.x *= factor; - pfont->FontBBox.q.x *= factor; - /* Condense our font data. */ - *plfont = *orig_font; - pl_fp_set_pitch_cp(&plfont->params, - pl_fp_pitch_cp(&plfont->params) * factor); - plfont->params.style |= 4; /* condensed */ - plfont->pfont = (gs_font *)pfont; -#undef factor - code = gs_definefont(pcls->font_dir, (gs_font *)pfont); - if ( code < 0 ) - return code; - pl_dict_put(&pcls->built_in_fonts, key, sizeof(key), plfont); - key[sizeof(key) - 1]++; - } +#ifdef DEBUG + /* check that we have loaded everything in the resident font table */ + { int i; + for (i=0; resident_table[i].ext_name != 0; i++) + if ( !font_found[i] ) + dprintf1( "Could not load resident font: %s\n", + resident_table[i].ext_name ); + } +#endif return found_some; } diff --git a/pcl/pcmain.c b/pcl/pcmain.c index aef0db539..fae0b8408 100644 --- a/pcl/pcmain.c +++ b/pcl/pcmain.c @@ -52,7 +52,7 @@ const pcl_init_t *pcl_init_table[] = { /* Interim font initialization procedure */ extern bool pcl_load_built_in_fonts(P2(pcl_state_t *, const char *[])); private const char *built_in_font_prefixes[] = { - "", "/windows/system/", "/windows/fonts/", "/win95/fonts/", 0 + "", "fonts/", "/windows/system/", "/windows/fonts/", "/win95/fonts/", 0 }; /* Built-in symbol set initialization procedure */ diff --git a/pcl/pcprint.c b/pcl/pcprint.c index 6a1de4c78..3e817b6a1 100644 --- a/pcl/pcprint.c +++ b/pcl/pcprint.c @@ -162,14 +162,6 @@ pcl_set_pattern_reference_point(pcl_args_t *pargs, pcl_state_t *pcls) if ( rotate > 1 ) return 0; pcls->shift_patterns = true; - { gs_point origin; - gs_transform(pcls->pgs, (float)pcls->cap.x, - (float)pcls->cap.y, &origin); - pcls->pattern_reference_point.x = (int)origin.x; - pcls->pattern_reference_point.y = (int)origin.y; - gs_sethalftonephase(pcls->pgs, pcls->pattern_reference_point.x, - pcls->pattern_reference_point.y); - } pcls->rotate_patterns = rotate == 0; return 0; } diff --git a/pcl/pcsfont.c b/pcl/pcsfont.c index e848a787f..29cc8533a 100644 --- a/pcl/pcsfont.c +++ b/pcl/pcsfont.c @@ -203,7 +203,8 @@ pcl_font_header(pcl_args_t *pargs, pcl_state_t *pcls) pl_fp_set_pitch_cp(&plfont->params, pitch_cp); } - plfont->params.height_4ths = pl_get_uint16(pfh->Height); + plfont->params.height_4ths = + pl_get_uint16(pfh->Height) * 72 / plfont->resolution.x; break; } case plfst_TrueType: diff --git a/pcl/pcsymbol.c b/pcl/pcsymbol.c index 5d02c7673..362ecb2e7 100644 --- a/pcl/pcsymbol.c +++ b/pcl/pcsymbol.c @@ -26,14 +26,15 @@ pcl_define_symbol_set(pcl_args_t *pargs, pcl_state_t *pcls) uint header_size; uint first_code, last_code; gs_memory_t *mem = pcls->memory; - byte *header; + pl_symbol_map_t *header; pcl_symbol_set_t *symsetp; pl_glyph_vocabulary_t gv; - if ( count < 18 ) +#define psm_header_size offset_of(pl_symbol_map_t, codes) + if ( count < psm_header_size ) return e_Range; header_size = pl_get_uint16(psm->header_size); - if ( header_size < 18 || + if ( header_size < psm_header_size || psm->id[0] != id_key(pcls->symbol_set_id)[0] || psm->id[1] != id_key(pcls->symbol_set_id)[1] || psm->type > 2 @@ -45,19 +46,33 @@ pcl_define_symbol_set(pcl_args_t *pargs, pcl_state_t *pcls) case 3: break; default: - return 0; + return e_Range; } first_code = pl_get_uint16(psm->first_code); last_code = pl_get_uint16(psm->last_code); gv = (psm->character_requirements[7] & 07)==1? plgv_Unicode: plgv_MSL; - if ( first_code > last_code || - count < 18 + (last_code - first_code + 1) * 2 - ) - return e_Range; - header = gs_alloc_bytes(mem, count, "pcl_font_header(header)"); - if ( header == 0 ) - return_error(e_Memory); - memcpy(header, (void *)psm, count); + { int num_codes = last_code - first_code + 1; + int i; + + if ( num_codes <= 0 || count < psm_header_size + num_codes * 2 ) + return e_Range; + header = + (pl_symbol_map_t *)gs_alloc_bytes(mem, + psm_header_size + + num_codes * sizeof(ushort), + "pcl_font_header(header)"); + if ( header == 0 ) + return_error(e_Memory); + memcpy((void *)header, (void *)psm, psm_header_size); + /* + * Byte swap the codes now, so that we don't have to byte swap + * them every time we access them. + */ + for ( i = num_codes; --i >= 0; ) + header->codes[i] = + pl_get_uint16((byte *)psm + psm_header_size + i * 2); + } +#undef psm_header_size /* Symbol set may already exist; if so, we may be replacing one of * its existing maps or adding one for a new glyph vocabulary. */ @@ -79,7 +94,7 @@ pcl_define_symbol_set(pcl_args_t *pargs, pcl_state_t *pcls) pl_dict_put(&pcls->soft_symbol_sets, id_key(pcls->symbol_set_id), 2, symsetp); } - symsetp->maps[gv] = (pl_symbol_map_t *)header; + symsetp->maps[gv] = header; return 0; } diff --git a/pcl/pctext.c b/pcl/pctext.c index d99f8ca5b..b226da656 100644 --- a/pcl/pctext.c +++ b/pcl/pctext.c @@ -147,7 +147,8 @@ pcl_show_chars(gs_show_enum *penum, pcl_state_t *pcls, const gs_point *pscale, bool source_transparent = gs_currentsourcetransparent(pgs); bool opaque = !source_transparent && rop3_know_S_0(effective_rop) != rop3_D; - bool wrap = pcls->end_of_line_wrap && pcls->check_right_margin; + bool wrap = pcls->end_of_line_wrap; + bool clip = pcls->check_right_margin; /* Compute any width adjustment. */ switch ( adjust ) @@ -188,12 +189,13 @@ pcl_show_chars(gs_show_enum *penum, pcl_state_t *pcls, const gs_point *pscale, * bounding box that is outside their actual shape), we have to * do quite a bit of extra work. This "feature" is a pain! */ - if ( opaque || wrap ) - { /* - * 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.) - */ + 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; @@ -225,12 +227,20 @@ pcl_show_chars(gs_show_enum *penum, pcl_state_t *pcls, const gs_point *pscale, * We should really handle this by scaling the font.... * We need a little fuzz to handle rounding inaccuracies. */ - if ( wrap && pt.x + width.x >= limit ) - { 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); + 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 + { + return 0; + } } if ( opaque ) { /* @@ -394,9 +404,6 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) pfp = &pcls->font_selection[pcls->font_selected]; /**** WE COULD CACHE MORE AND DO LESS SETUP HERE ****/ pcl_set_graphics_state(pcls, true); - /* Clip to the margins. */ - { gs_rect text_clip; - /* * TRM 5-13 describes text clipping very badly. Text is only * clipped if it crosses the right margin in the course of @@ -404,24 +411,12 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) * clipped to the right margin if it starts to the right of * the right margin. */ - if ( !pcls->within_text ) - { - /* Decide now whether to clip and wrap. */ - pcls->check_right_margin = pcls->cap.x < pcl_right_margin(pcls); - pcls->within_text = true; - } - gs_initclip(pgs); - gs_clippath(pgs); - gs_pathbbox(pgs, &text_clip); - gs_newpath(pgs); - text_clip.p.y = pcl_top_margin(pcls); - if ( pcls->check_right_margin ) - text_clip.q.x = pcl_right_margin(pcls); - text_clip.q.y = pcl_top_margin(pcls) + pcl_text_length(pcls); - code = gs_rectclip(pgs, &text_clip, 1); - if ( code < 0 ) - return code; - } + if ( !pcls->within_text ) + { + /* Decide now whether to clip and wrap. */ + pcls->check_right_margin = pcls->cap.x < pcl_right_margin(pcls); + pcls->within_text = true; + } code = pcl_set_drawing_color(pcls, pcls->pattern_type, &pcls->current_pattern_id); if ( code < 0 ) @@ -507,20 +502,19 @@ pcl_text(const byte *str, uint size, pcl_state_t *pcls) adjust = char_adjust_all; } else - { /* - * If the string has any spaces and the font doesn't define the - * space character, we have to do something special. - * ******HACK******: The built-in fonts must not define the - * space character (required by Genoa FTS 0010-054). + { /* + * 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 ( (pcls->font->storage & pcds_internal) || - !pl_font_includes_char(pcls->font, pcls->map, &font_ctm, ' ') - ) + { if ( (!pl_font_includes_char(pcls->font, pcls->map, &font_ctm, ' ')) || + (pcls->hmi_set == hmi_set_explicitly) ) adjust = char_adjust_space; break; } diff --git a/pcl/pcursor.c b/pcl/pcursor.c index e87ae207b..22004ab6b 100644 --- a/pcl/pcursor.c +++ b/pcl/pcursor.c @@ -37,7 +37,7 @@ pcl_do_FF(pcl_state_t *pcls) /* Move the cursor down, taking perforation skip into account if necessary. */ private int move_down(pcl_state_t *pcls, coord dy) -{ coord y = pcls->cap.y + pcls->vmi; +{ coord y = pcls->cap.y + dy; if ( pcls->perforation_skip && y > pcl_top_margin(pcls) + pcl_text_length(pcls) ) diff --git a/pcl/pgconfig.c b/pcl/pgconfig.c index 93708c1f5..07f15ad13 100644 --- a/pcl/pgconfig.c +++ b/pcl/pgconfig.c @@ -197,34 +197,34 @@ hpgl_IN(hpgl_args_t *pargs, hpgl_state_t *pgls) private int hpgl_picture_frame_coords(hpgl_state_t *pgls, gs_int_rect *gl2_win) { - gs_rect dev_win; /* device window */ - gs_rect pcl_win; /* pcl window -- upper left and lower right */ hpgl_real_t x1 = pgls->g.picture_frame.anchor_point.x; hpgl_real_t y1 = pgls->g.picture_frame.anchor_point.y; hpgl_real_t x2 = x1 + pgls->g.picture_frame_width; hpgl_real_t y2 = y1 + pgls->g.picture_frame_height; + pcl_set_ctm(pgls, false); hpgl_call(gs_transform(pgls->pgs, x1, y1, &dev_win.p)); hpgl_call(gs_transform(pgls->pgs, x2, y2, &dev_win.q)); hpgl_call(hpgl_set_plu_ctm(pgls)); - hpgl_call(gs_itransform(pgls->pgs, - dev_win.p.x, - dev_win.p.y, - &pcl_win.p)); - hpgl_call(gs_itransform(pgls->pgs, - dev_win.q.x, - dev_win.q.y, - &pcl_win.q)); - /* now win.p is the upper left and win.q the lower right, gl/2 - likes to use the lower left and upper right for boxes */ + /* + * gs_bbox_transform_inverse puts the resulting points in the + * correct order, with p < q. + */ + { gs_matrix mat; + gs_rect pcl_win; /* pcl window */ + + gs_currentmatrix(pgls->pgs, &mat); + hpgl_call(gs_bbox_transform_inverse(&dev_win, &mat, &pcl_win)); /* HAS have not checked if this is properly rounded or truncated */ -#define round(x) (((x) < 0.0) ? (ceil ((x) - 0.5)) : (floor ((x) + 0.5))) - gl2_win->p.x = round(pcl_win.p.x); - gl2_win->p.y = round(pcl_win.q.y); /* !! */ - gl2_win->q.x = round(pcl_win.q.x); - gl2_win->q.y = round(pcl_win.p.y); /* !! */ -#undef round +/* Round all coordinates to the nearest integer. */ +#define set_round(e) gl2_win->e = (int)floor(pcl_win.e + 0.5) + set_round(p.x); + set_round(p.y); + set_round(q.x); + set_round(q.y); +#undef set_round + } return 0; } @@ -493,6 +493,7 @@ pxy: scale_params.pmin.x = xy[0]; 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); } diff --git a/pcl/pgdraw.c b/pcl/pgdraw.c index 26bcc7893..1c793d192 100644 --- a/pcl/pgdraw.c +++ b/pcl/pgdraw.c @@ -24,6 +24,31 @@ #include "pgmisc.h" #include "pcdraw.h" /* included for setting pcl's ctm */ + + int +hpgl_set_picture_frame_scaling(hpgl_state_t *pgls) +{ + if ( (pgls->g.picture_frame_height == 0) || + (pgls->g.picture_frame_width == 0) || + (pgls->g.plot_width == 0) || + (pgls->g.plot_height == 0) ) + return 1; + { + hpgl_real_t vert_scale = (pgls->g.plot_size_vertical_specified) ? + ((hpgl_real_t)pgls->g.picture_frame_height / + (hpgl_real_t)pgls->g.plot_height) : + 1.0; + hpgl_real_t horz_scale = (pgls->g.plot_size_horizontal_specified) ? + ((hpgl_real_t)pgls->g.picture_frame_width / + (hpgl_real_t)pgls->g.plot_width) : + 1.0; + + hpgl_call(gs_scale(pgls->pgs, horz_scale, vert_scale)); + } + + return 0; +} + /* HAS: update ghostscript's gs and the current ctm to reflect hpgl's. embodied in hpgl_set_graphics_dash_state(), hpgl_set_graphics_line_attributes(), and hpgl_set_drawing_state() below. @@ -35,7 +60,7 @@ int hpgl_set_pcl_to_plu_ctm(hpgl_state_t *pgls) { - pcl_set_ctm(pgls, false); + hpgl_call(pcl_set_ctm(pgls, false)); hpgl_call(gs_translate(pgls->pgs, pgls->g.picture_frame.anchor_point.x, pgls->g.picture_frame.anchor_point.y)); @@ -64,20 +89,7 @@ hpgl_set_pcl_to_plu_ctm(hpgl_state_t *pgls) break; } } - /* set up scaling wrt plot size and picture frame size. HAS - we still have the line width issue when scaling is - assymetric !! */ - /* if any of these are zero something is wrong */ - if ( (pgls->g.picture_frame_height == 0) || - (pgls->g.picture_frame_width == 0) || - (pgls->g.plot_width == 0) || - (pgls->g.plot_height == 0) ) - return 1; - hpgl_call(gs_scale(pgls->pgs, - ((hpgl_real_t)pgls->g.picture_frame_height / - (hpgl_real_t)pgls->g.plot_height), - ((hpgl_real_t)pgls->g.picture_frame_width / - (hpgl_real_t)pgls->g.plot_width))); + hpgl_call(hpgl_set_picture_frame_scaling(pgls)); return 0; } @@ -101,11 +113,11 @@ hpgl_compute_user_units_to_plu_ctm(const hpgl_state_t *pgls, gs_matrix *pmat) gs_make_identity(pmat); break; case hpgl_scaling_point_factor: - gs_make_translation(origin_x, origin_y, pmat); - gs_matrix_scale(pmat, pgls->g.scaling_params.factor.x, - pgls->g.scaling_params.factor.y, pmat); - gs_matrix_translate(pmat, -pgls->g.scaling_params.pmin.x, - -pgls->g.scaling_params.pmin.y, pmat); + hpgl_call(gs_make_translation(origin_x, origin_y, pmat)); + hpgl_call(gs_matrix_scale(pmat, pgls->g.scaling_params.factor.x, + pgls->g.scaling_params.factor.y, pmat)); + hpgl_call(gs_matrix_translate(pmat, -pgls->g.scaling_params.pmin.x, + -pgls->g.scaling_params.pmin.y, pmat)); break; default: /*case hpgl_scaling_anisotropic:*/ @@ -134,17 +146,17 @@ hpgl_compute_user_units_to_plu_ctm(const hpgl_state_t *pgls, gs_matrix *pmat) scale_y = scale_x; } } - gs_make_translation(origin_x, origin_y, pmat); - gs_matrix_scale(pmat, scale_x, scale_y, pmat); - gs_matrix_translate(pmat, -pgls->g.scaling_params.pmin.x, - -pgls->g.scaling_params.pmin.y, pmat); + hpgl_call(gs_make_translation(origin_x, origin_y, pmat)); + hpgl_call(gs_matrix_scale(pmat, scale_x, scale_y, pmat)); + hpgl_call(gs_matrix_translate(pmat, -pgls->g.scaling_params.pmin.x, + -pgls->g.scaling_params.pmin.y, pmat)); break; } } return 0; } - private int + int hpgl_set_user_units_to_plu_ctm(hpgl_state_t *pgls) { if ( pgls->g.scaling_type != hpgl_scaling_none ) @@ -329,77 +341,20 @@ vector: hpgl_call(gs_setlinejoin(pgls->pgs, } /* A bounding box for the current polygon -- used for HPGL/2 vector - fills. We expand the bounding box by the current line width to + fills. We expand the bounding box by 1/2 the current line width to avoid overhanging lines. */ private int -hpgl_polyfill_anchored_bbox(hpgl_state_t *pgls, gs_rect *bbox, - hpgl_real_t spacing, hpgl_real_t direction) +hpgl_polyfill_bbox(hpgl_state_t *pgls, gs_rect *bbox) { - /* get the bounding box we only need this for the upper right - corner. The lower left is supplied by AC */ + hpgl_real_t half_width = pgls->g.pen.width[pgls->g.pen.selected] / 2.0; + /* get the bounding box for the current path / polygon */ hpgl_call(gs_pathbbox(pgls->pgs, bbox)); - /* expand the box */ - - { -#define sin_dir sincos.sin -#define cos_dir sincos.cos - gs_matrix mat, imat; - gs_sincos_t sincos; - gs_point anchor = pgls->g.anchor_corner; - /* calculate integer number of fill lines between the origin - of the bbox and the anchor corner in X and Y directions. - Then use the coordinates of the n'th fill line as the - anchor corner. Also make sure anchor corner is in front of bbox */ -#if 0 - gs_point fill_increment; - int fill_line_num; -#endif - hpgl_call(hpgl_compute_user_units_to_plu_ctm(pgls, &mat)); - hpgl_call(gs_matrix_invert(&mat, &imat)); - hpgl_call(gs_point_transform(pgls->g.anchor_corner.x, - pgls->g.anchor_corner.y, - &imat, - &anchor)); - gs_sincos_degrees(direction, &sincos); - /* HAS anchor in front of polygon origin is not documented */ - bbox->p.x = min(anchor.x, bbox->p.x); - bbox->p.y = min(anchor.y, bbox->p.y); - -#if 0 - if ( sin_dir != 0 ) - { - fill_increment.x = fabs(spacing / sin_dir); - /* move the anchor back if necessary. note that we - treat x and y exclusively */ - while ( bbox->p.x < anchor.x ) anchor.x -= fill_increment.x; - /* integer number of fill lines */ - - fill_line_num = - (int)fabs(bbox->p.x - anchor.x) / fill_increment.x; - /* new origin at last fill line below origin */ - bbox->p.x = fill_line_num * fill_increment.x; - } - /* same for y */ - if ( cos_dir != 0 ) - { - fill_increment.y = fabs(spacing / cos_dir); - while ( bbox->p.y < anchor.y ) anchor.y -= fill_increment.y; - fill_line_num = - (int)fabs(bbox->p.y - anchor.y) / fill_increment.y; - bbox->p.y = fill_line_num * fill_increment.y; - } - bbox->p = anchor; - - { - hpgl_real_t half_width = pgls->g.pen.width[pgls->g.pen.selected] / 2.0; - bbox->p.x -= half_width; - bbox->p.y -= half_width; - bbox->q.x += half_width; - bbox->q.y += half_width; - } -#endif - } + /* expand the box. */ + bbox->p.x -= half_width; + bbox->p.y -= half_width; + bbox->q.x += half_width; + bbox->q.y += half_width; return 0; } @@ -449,10 +404,10 @@ hpgl_set_clipping_region(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) 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); - dev_clip_box.p.y = max(dev_clip_box.p.y, dev_soft_window_box.p.y); - dev_clip_box.q.x = min(dev_clip_box.q.x, dev_soft_window_box.q.x); - dev_clip_box.q.y = min(dev_clip_box.q.y, dev_soft_window_box.q.y); + dev_clip_box.p.x = max(dev_clip_box.p.x, dev_soft_window_box.p.x); + dev_clip_box.p.y = max(dev_clip_box.p.y, dev_soft_window_box.p.y); + dev_clip_box.q.x = min(dev_clip_box.q.x, dev_soft_window_box.q.x); + dev_clip_box.q.y = min(dev_clip_box.q.y, dev_soft_window_box.q.y); } /* convert intersection box to fixed point and clip */ @@ -476,7 +431,6 @@ hpgl_draw_vector_absolute(hpgl_state_t *pgls, hpgl_real_t x0, hpgl_real_t y0, hpgl_plot_move_absolute, set_ctm)); hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, hpgl_plot_draw_absolute, set_ctm)); - hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector_fill)); return 0; } @@ -493,6 +447,7 @@ hpgl_polyfill(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) #define cos_dir sincos.cos gs_rect bbox; hpgl_pen_state_t saved_pen_state; + hpgl_real_t x_fill_increment, y_fill_increment; bool cross = (pgls->g.fill.type == hpgl_fill_crosshatch); const hpgl_hatch_params_t *params = (cross ? &pgls->g.fill.param.crosshatch : &pgls->g.fill.param.hatch); @@ -504,7 +459,7 @@ hpgl_polyfill(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) { /* Per TRM 22-12, use 1% of the P1/P2 distance. */ gs_matrix mat; - hpgl_compute_user_units_to_plu_ctm(pgls, &mat); + hpgl_call(hpgl_compute_user_units_to_plu_ctm(pgls, &mat)); spacing = 0.01 * hpgl_compute_distance(pgls->g.P1.x, pgls->g.P1.y, pgls->g.P2.x, pgls->g.P2.y); @@ -512,16 +467,9 @@ hpgl_polyfill(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) spacing /= min(fabs(mat.xx), fabs(mat.yy)); } /* get the bounding box */ - hpgl_call(hpgl_polyfill_anchored_bbox(pgls, &bbox, spacing, direction)); + hpgl_call(hpgl_polyfill_bbox(pgls, &bbox)); /* HAS calculate the offset for dashing - we do not need this for solid lines */ - /* HAS 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(bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); - /* if the line width exceeds the spacing we use the line width to avoid overlapping of the fill lines. HAS this can be integrated with the logic above for spacing as not to @@ -544,33 +492,43 @@ 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 = bbox.p.x; starty = bbox.p.y; + 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; + /* 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, endx, endy, render_mode)); /* Travel along +x using current spacing. */ - if ( sin_dir != 0 ) - { hpgl_real_t x_fill_increment = fabs(spacing / sin_dir); - + if ( x_fill_increment != 0 ) while ( endx += x_fill_increment, (startx += x_fill_increment) <= bbox.q.x ) hpgl_call(hpgl_draw_vector_absolute(pgls, startx, starty, endx, endy, render_mode)); - } /* Travel along +Y similarly. */ - if ( cos_dir != 0 ) - { hpgl_real_t y_fill_increment = fabs(spacing / cos_dir); - + if ( y_fill_increment != 0 ) + { /* * If the slope is negative, we have to travel along the right * edge of the box rather than the left edge. Fortuitously, * the X loop left everything set up exactly right for this case. */ if ( cos_dir >= 0 ) - { startx = bbox.p.x; starty = bbox.p.y; + { startx = pgls->g.anchor_corner.x; starty = pgls->g.anchor_corner.y; endx = (diag_mag * cos_dir) + startx; endy = (diag_mag * sin_dir) + starty; } @@ -589,6 +547,7 @@ start: gs_sincos_degrees(direction, &sincos); direction += 90; goto start; } + hpgl_call(hpgl_draw_current_path(pgls, hpgl_rm_vector_fill)); hpgl_restore_pen_state(pgls, &saved_pen_state, hpgl_pen_pos); return 0; #undef sin_dir @@ -613,18 +572,28 @@ hpgl_polyfill_using_current_line_type(hpgl_state_t *pgls, } private int +hpgl_set_pcl_pattern_origin(hpgl_state_t *pgls, gs_point *point) +{ + gs_point pattern_origin; + hpgl_call(gs_transform(pgls->pgs, point->x, point->y, &pattern_origin)); + hpgl_call(gs_sethalftonephase(pgls->pgs, pattern_origin.x, pattern_origin.y)); + return 0; +} + private int hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) { pcl_id_t pcl_id; + gs_point pattern_origin; /* default to pcl pattern dictionary. Only user defined types use a private hpgl/2 dictionary. */ pl_dict_t *pattern_dictp = &pgls->patterns; pcl_pattern_type_t pat; - + /* HAS - this is tooooo complicated. */ if ( (render_mode == hpgl_rm_clip_and_fill_polygon) || + ((pgls->g.fill.type == hpgl_fill_hatch || pgls->g.fill.type == hpgl_fill_crosshatch) && ((render_mode == hpgl_rm_character) && ((pgls->g.character.fill_mode == hpgl_char_fill) || - (pgls->g.character.fill_mode == hpgl_char_fill_edge))) ) + (pgls->g.character.fill_mode == hpgl_char_fill_edge)))) ) { hpgl_call(hpgl_polyfill_using_current_line_type(pgls, render_mode)); @@ -639,13 +608,17 @@ hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) case hpgl_char_edge: pat = pcpt_solid_black; break; + case hpgl_char_fill: + case hpgl_char_fill_edge: + goto fill; default: dprintf("hpgl_set_drawing_color: internal error illegal fill\n"); - break; + return 0; } + break; /* fill like a polygon */ case hpgl_rm_polygon: - switch ( pgls->g.fill.type ) +fill: switch ( pgls->g.fill.type ) { case hpgl_fill_solid: case hpgl_fill_solid2: /* fall through */ @@ -659,12 +632,16 @@ hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) 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, + &pgls->g.anchor_corner)); break; case hpgl_fill_shaded: id_set_value(pcl_id, pgls->g.fill.param.shading); pat = pcpt_shading; break; case hpgl_fill_pcl_user_defined: + 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; break; @@ -714,6 +691,8 @@ hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) } break; case hpgl_screen_pcl_user_defined: + 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; @@ -727,13 +706,14 @@ hpgl_set_drawing_color(hpgl_state_t *pgls, hpgl_rendering_mode_t render_mode) break; } + gs_setrasterop(pgls->pgs, pgls->logical_op); gs_setsourcetransparent(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, + pgls->g.anchor_corner.y, &pattern_origin)); hpgl_call(pcl_set_drawing_color_rotation(pgls, - pat, - &pcl_id, - pattern_dictp, - (pgls->g.rotation / 90) & 3)); + pat, &pcl_id, pattern_dictp, -((pgls->g.rotation / 90) & 3), + &pattern_origin)); return 0; } @@ -807,7 +787,7 @@ hpgl_add_point_to_path(hpgl_state_t *pgls, floatp x, floatp y, hpgl_set_lost_mode(pgls, hpgl_lost_mode_cleared); /* update hpgl's state position */ - gs_currentpoint(pgls->pgs, &point); + hpgl_call(gs_currentpoint(pgls->pgs, &point)); hpgl_call(hpgl_set_current_position(pgls, &point)); } } @@ -850,26 +830,27 @@ 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, floatp radius, floatp start_angle, floatp sweep_angle, - floatp chord_angle, bool start_moveto, bool draw) + floatp chord_angle, bool start_moveto, hpgl_plot_function_t draw, + bool set_ctm) { floatp start_angle_radians = start_angle * degrees_to_radians; /* * Ensure that the sweep angle is an integral multiple of the * chord angle, by decreasing the chord angle if necessary. */ - int num_chords = ceil(sweep_angle / chord_angle); + int num_chords = (int)ceil(sweep_angle / chord_angle); floatp chord_angle_radians = sweep_angle / num_chords * degrees_to_radians; int i; floatp arccoord_x, arccoord_y; - hpgl_compute_arc_coords(radius, center_x, center_y, - start_angle_radians, - &arccoord_x, &arccoord_y); + (void)hpgl_compute_arc_coords(radius, center_x, center_y, + start_angle_radians, + &arccoord_x, &arccoord_y); hpgl_call(hpgl_add_point_to_path(pgls, arccoord_x, arccoord_y, (draw && !start_moveto ? hpgl_plot_draw_absolute : - hpgl_plot_move_absolute), true)); + hpgl_plot_move_absolute), set_ctm)); /* HAS - pen up/down is invariant in the loop */ for ( i = 0; i < num_chords; i++ ) @@ -880,7 +861,7 @@ hpgl_add_arc_to_path(hpgl_state_t *pgls, floatp center_x, floatp center_y, &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), true)); + hpgl_plot_move_absolute), set_ctm)); } return 0; } @@ -890,7 +871,7 @@ hpgl_add_arc_to_path(hpgl_state_t *pgls, floatp center_x, floatp center_y, hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp start_y, floatp inter_x, floatp inter_y, floatp end_x, floatp end_y, floatp chord_angle, - bool draw) + hpgl_plot_function_t draw) { /* handle unusual cases as per pcltrm */ if ( hpgl_3_same_points(start_x, start_y, @@ -917,7 +898,7 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp (hypot((inter_x - start_x), (inter_y - start_y)) / 2.0), 0.0, 360.0, chord_angle, false, - draw)); + draw, true)); return 0; } @@ -989,7 +970,7 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp radius, start_angle, sweep_angle, (sweep_angle < 0.0 ) ? -chord_angle : chord_angle, false, - draw)); + draw, true)); return 0; } } @@ -1001,7 +982,7 @@ hpgl_add_arc_3point_to_path(hpgl_state_t *pgls, floatp start_x, floatp int hpgl_add_bezier_to_path(hpgl_state_t *pgls, floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3, - floatp x4, floatp y4, bool draw) + floatp x4, floatp y4, hpgl_plot_function_t draw) { hpgl_call(hpgl_add_point_to_path(pgls, x1, y1, hpgl_plot_move_absolute, true)); diff --git a/pcl/pgdraw.h b/pcl/pgdraw.h index c53764003..568860be3 100644 --- a/pcl/pgdraw.h +++ b/pcl/pgdraw.h @@ -15,6 +15,12 @@ int hpgl_set_plu_ctm(P1(hpgl_state_t *pgls)); int hpgl_compute_user_units_to_plu_ctm(P2(const hpgl_state_t *pgls, gs_matrix *pmat)); +/* The following 2 functions can be used together to calculate a ctm + without picture frame scaling. */ +int hpgl_set_pcl_to_plu_ctm(P1(const hpgl_state_t *pgls)); + +int hpgl_set_user_units_to_plu_ctm(P1(const hpgl_state_t *pgls)); + /* set (user units) ctm */ int hpgl_set_ctm(P1(hpgl_state_t *pgls)); @@ -27,11 +33,11 @@ int hpgl_add_point_to_path(P5(hpgl_state_t *pgls, floatp x, floatp y, /* 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(P9(hpgl_state_t *pgls, floatp center_x, - floatp center_y, floatp radius, - floatp start_angle, floatp sweep_angle, - floatp chord_angle, bool start_moveto, - bool draw)); +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)); /* puts a 3 point arc into the current path. Note that the decomposition is a bit different for 3 point arcs since the polygon @@ -40,13 +46,13 @@ int hpgl_add_arc_to_path(P9(hpgl_state_t *pgls, floatp center_x, int hpgl_add_arc_3point_to_path(P9(hpgl_state_t *pgls, floatp start_x, floatp start_y, floatp inter_x, floatp inter_y, floatp end_x, floatp end_y, floatp chord_angle, - bool draw)); + 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, - floatp y4, bool draw)); + 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, diff --git a/pcl/pgframe.c b/pcl/pgframe.c index 17ffe9e3c..39b26fc70 100644 --- a/pcl/pgframe.c +++ b/pcl/pgframe.c @@ -121,9 +121,16 @@ pcl_hpgl_plot_horiz_size(pcl_args_t *pargs, pcl_state_t *pcls) float size = float_arg(pargs) * 7200.0; if ( (coord)size == 0 ) - pcls->g.plot_width = pcls->g.picture_frame_width; + { + pcls->g.plot_width = pcls->g.picture_frame_width; + pcls->g.plot_size_horizontal_specified = false; + } else - pcls->g.plot_width = (coord)size; + { + pcls->g.plot_width = (coord)size; + pcls->g.plot_size_horizontal_specified = true; + } + return 0; } @@ -133,9 +140,15 @@ pcl_hpgl_plot_vert_size(pcl_args_t *pargs, pcl_state_t *pcls) /* convert to centipoints as to match the picture frame */ float size = float_arg(pargs) * 7200.0; if ( (coord)size == 0 ) - pcls->g.plot_height = pcls->g.picture_frame_height; + { + pcls->g.plot_height = pcls->g.picture_frame_height; + pcls->g.plot_size_vertical_specified = false; + } else - pcls->g.plot_height = (coord)size; + { + pcls->g.plot_height = (coord)size; + pcls->g.plot_size_vertical_specified = true; + } return 0; } diff --git a/pcl/pglabel.c b/pcl/pglabel.c index a2313a705..17cbf3074 100644 --- a/pcl/pglabel.c +++ b/pcl/pglabel.c @@ -761,12 +761,12 @@ hpgl_can_concat_labels(const hpgl_state_t *pgls) /* return relative coordinates to compensate for origin placement -- LO */ private int -hpgl_get_character_origin_offset(int origin, hpgl_real_t width, - hpgl_real_t height, gs_point *offset) +hpgl_get_character_origin_offset(hpgl_state_t *pgls, int origin, + hpgl_real_t width, hpgl_real_t height, + gs_point *offset) { double pos_x = 0.0, pos_y = 0.0; double off_x, off_y; - /* stickfonts are offset by 16 grid units or .33 times the point size. HAS need to support other font types. */ if ( origin > 10 ) @@ -827,7 +827,20 @@ hpgl_get_character_origin_offset(int origin, hpgl_real_t width, pos_y += height; break; case 21: - dprintf("no label 21 support yet, LO offsets are 0\n"); + { + gs_matrix save_ctm; + gs_point pcl_pos_dev, label_origin; + + gs_currentmatrix(pgls->pgs, &save_ctm); + pcl_set_ctm(pgls, false); + hpgl_call(gs_transform(pgls->pgs, (floatp)pgls->cap.x, + (floatp)pgls->cap.y, &pcl_pos_dev)); + gs_setmatrix(pgls->pgs, &save_ctm); + 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); + } break; default: dprintf("unknown label parameter"); @@ -931,7 +944,7 @@ acc_ht: hpgl_call(hpgl_get_current_cell_height(pgls, &height, vertical, ve } hpgl_select_font(pgls, save_index); } - hpgl_call(hpgl_get_character_origin_offset(pgls->g.label.origin, + hpgl_call(hpgl_get_character_origin_offset(pgls, pgls->g.label.origin, label_length, label_height, &offset)); switch ( pgls->g.character.text_path ) @@ -945,8 +958,17 @@ acc_ht: hpgl_call(hpgl_get_current_cell_height(pgls, &height, vertical, ve default: DO_NOTHING; } - hpgl_call(hpgl_add_point_to_path(pgls, -offset.x, -offset.y, + + /* these units should be strictly plu */ + { 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, hpgl_plot_move_relative, true)); + } { int i; diff --git a/pcl/pglfill.c b/pcl/pglfill.c index f86123231..5c81c0dd4 100644 --- a/pcl/pglfill.c +++ b/pcl/pglfill.c @@ -278,10 +278,10 @@ 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 : 255); - if ( hpgl_arg_c_int(pargs, &opcode) && (opcode & ~255) ) - return e_Range; + if ( mode != 0 && hpgl_arg_c_int(pargs, &opcode) ) + if (opcode < 0 || opcode > 255 ) + return e_Range; pgls->logical_op = opcode; - gs_setrasterop(pgls->pgs, opcode); return 0; } @@ -289,16 +289,16 @@ hpgl_MC(hpgl_args_t *pargs, hpgl_state_t *pgls) int hpgl_PW(hpgl_args_t *pargs, hpgl_state_t *pgls) { - hpgl_real_t width = - ((pgls->g.pen.width_relative) ? - (0.01 * hpgl_compute_distance(pgls->g.P1.x, pgls->g.P1.y, - pgls->g.P2.x, pgls->g.P2.y)): - (0.35)); + /* we initialize the parameter to be parsed to either .1 which + is a % of the magnitude of P1 P2 or .35 MM WU sets up how + it get interpreted. */ + hpgl_real_t param = pgls->g.pen.width_relative ? .1 : .35; + hpgl_real_t width_plu; int pmin = 0, pmax = pgls->g.number_of_pens - 1; /* we maintain the line widths in plotter units, irrespective - of current units (WU) */ - if ( hpgl_arg_c_real(pargs, &width) ) + 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 ) @@ -306,25 +306,25 @@ hpgl_PW(hpgl_args_t *pargs, hpgl_state_t *pgls) else pmax = pmin; } - + /* width is maintained in plu only */ + width_plu = ((pgls->g.pen.width_relative) ? + ((param/100.0) * hpgl_compute_distance(pgls->g.P1.x, pgls->g.P1.y, + pgls->g.P2.x, pgls->g.P2.y)) : + mm_2_plu(param)); /* PCLTRM 22-38 metric widths scaled scaled by the ratio of the picture frame to plot size. Note that we always store the line width in PU not MM. */ - if ( !pgls->g.pen.width_relative ) - { - width = width * (min((hpgl_real_t)pgls->g.picture_frame_height / - (hpgl_real_t)pgls->g.plot_height, - ((hpgl_real_t)pgls->g.picture_frame_width / - (hpgl_real_t)pgls->g.plot_width))); - width = mm_2_plu(width); - } - + if ( pgls->g.pen.width_relative ) + width_plu *= (min((hpgl_real_t)pgls->g.picture_frame_height / + (hpgl_real_t)pgls->g.plot_height, + ((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 ) - pgls->g.pen.width[i] = width; + pgls->g.pen.width[i] = width_plu; } return 0; } @@ -537,7 +537,7 @@ hpgl_UL(hpgl_args_t *pargs, hpgl_state_t *pgls) if ( hpgl_arg_c_int(pargs, &index) ) { hpgl_real_t gap[20]; double total = 0; - int i; + int i, k; if ( index < -8 || index > 8 || index == 0 ) return e_Range; @@ -548,15 +548,18 @@ hpgl_UL(hpgl_args_t *pargs, hpgl_state_t *pgls) } if ( total == 0 ) return e_Range; - { - hpgl_line_type_t *fixed_plt = + + for ( k = 0; k < i; k++ ) + gap[k] /= total; + + { hpgl_line_type_t *fixed_plt = &pgls->g.fixed_line_type[(index < 0 ? -index : index) - 1]; hpgl_line_type_t *adaptive_plt = &pgls->g.adaptive_line_type[(index < 0 ? -index : index) - 1]; fixed_plt->count = adaptive_plt->count = i; memcpy(fixed_plt->gap, gap, i * sizeof(hpgl_real_t)); memcpy(adaptive_plt->gap, gap, i * sizeof(hpgl_real_t)); - } + } } else { @@ -573,8 +576,9 @@ int hpgl_WU(hpgl_args_t *pargs, hpgl_state_t *pgls) { int mode = 0; - if ( hpgl_arg_c_int(pargs, &mode) && (mode & ~1) ) - return e_Range; + if ( hpgl_arg_c_int(pargs, &mode) ) + if ( mode != 0 && mode != 1 ) + return e_Range; pgls->g.pen.width_relative = mode; hpgl_args_setup(pargs); hpgl_PW(pargs, pgls); diff --git a/pcl/pgstate.h b/pcl/pgstate.h index e1c364eb4..2fd274246 100644 --- a/pcl/pgstate.h +++ b/pcl/pgstate.h @@ -137,7 +137,8 @@ typedef struct pcl_hpgl_state_s { #define plot_width plot_size.x #define plot_height plot_size.y - + bool plot_size_vertical_specified; + bool plot_size_horizontal_specified; /* Chapter 19 (pgconfig.c) */ enum { diff --git a/pcl/pgvector.c b/pcl/pgvector.c index b3d9f47a7..87a650883 100644 --- a/pcl/pgvector.c +++ b/pcl/pgvector.c @@ -51,7 +51,7 @@ hpgl_arc(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) radius, start_angle, sweep, (sweep < 0.0 ) ? -chord_angle : chord_angle, false, - pgls->g.move_or_draw != 0)); + pgls->g.move_or_draw, true)); pgls->g.carriage_return_pos = pgls->g.pos; return 0; @@ -76,7 +76,7 @@ hpgl_arc_3_point(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) hpgl_arg_c_real(pargs, &chord_angle); - if ( relative ) + if ( relative ) { x_inter += x_start; y_inter += y_start; @@ -84,11 +84,11 @@ hpgl_arc_3_point(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) y_end += y_start; } - hpgl_call(hpgl_add_arc_3point_to_path(pgls, - x_start, y_start, + hpgl_call(hpgl_add_arc_3point_to_path(pgls, + x_start, y_start, x_inter, y_inter, x_end, y_end, chord_angle, - pgls->g.move_or_draw != 0)); + pgls->g.move_or_draw)); pgls->g.carriage_return_pos = pgls->g.pos; return 0; } @@ -134,13 +134,13 @@ hpgl_bezier(hpgl_args_t *pargs, hpgl_state_t *pgls, bool relative) y_start + coords[3], x_start + coords[4], y_start + coords[5], - pgls->g.move_or_draw != 0)); + pgls->g.move_or_draw)); else hpgl_call(hpgl_add_bezier_to_path(pgls, x_start, y_start, coords[0], coords[1], coords[2], coords[3], coords[4], coords[5], - pgls->g.move_or_draw != 0)); + pgls->g.move_or_draw)); /* Prepare for the next set of points. */ @@ -244,15 +244,16 @@ 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; + 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, 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 ) @@ -268,6 +269,8 @@ hpgl_CI(hpgl_args_t *pargs, hpgl_state_t *pgls) hpgl_call(hpgl_draw_arc(pgls)); hpgl_restore_pen_state(pgls, &saved_pen_state, hpgl_pen_pos); } + /* restore the ctm - i.e. the ctm with picture frame scaling */ + hpgl_set_ctm(pgls); return 0; } |