From e5a5511bec4711ad70aee2b3dcc294140951969b Mon Sep 17 00:00:00 2001 From: wlemb Date: Mon, 10 Mar 2003 21:51:48 +0000 Subject: * tmac/an-old.tmac: Use register `HY' to control hyphenation. * NEWS, tmac/groff_man.man, doc/groff.texinfo: Document it. Added support to access more than 256 glyphs in Type 1 fonts. * src/devices/grops/ps.cc (subencoding): New structure. (style): Add `sub' field. Updated all users. (ps_printer): Add `subencodings' and `next_subencoding_index' fields. Add `set_subencoding', `get_subfont' and `encode_subfont' member functions. Updated all users. (ps_printer::set_char): Use `set_subencoding'. (make_subencoding_name): New function. (ps_printer::set_style): Handle case where `sty.sub' is not zero. (ps_printer::~ps_printer): Emit subencoding definitions. * src/devices/grops/psrm.cc (valid_input_table): New array to properly support EBCDIC. (white_space): Add `\f'. (ps_get_line): Change first argument to be of type `string &'. Updated all callers. This allows to get lines of arbitrary length. Use `valid_input_table'. Remove warning about non-conforming PS line length. This seems not to be of great importance -- for example, dvips don't emit a warning either. (PS_LINE_MAX): Removed. (matches_comment): Change first argument to be of type `string &'. * src/devices/grops/grops.man, src/devices/grops/TODO: Updated. * src/utils/afmtodit/afmtodit.pl (%unicode_decomposed, %AGL_to_unicode, %default_ligatures): New hash tables. Read all map entries. Add unencoded characters. Check for default ligatures if there are no `L' entries. Print all kern entries. Print all characters in charset. * src/utils/afmtodit/afmtodit.man: Updated. * font/devps/*: Regerated all fonts. * tmac/latin[129].tmac, tmac/cp1047.tmac: Don't test for existence of characters, just use `.trin'. Otherwise the mapping is depending on the font encoding. * tmac/ps.tmac: Add `fi' and `fl'. Improve `Fi' and `Fl'. * tmac/X.tmac, tmac/lbp.tmac, tmac/tty.tmac: Improve `Fi' and `Fl'. * tmac/Xps.tmac: Fix `em'. * NEWS: Updated. --- src/devices/grops/TODO | 2 - src/devices/grops/grops.man | 165 ++++++++++++++++++++++++++------------------ src/devices/grops/ps.cc | 155 ++++++++++++++++++++++++++++++++++------- src/devices/grops/psrm.cc | 107 ++++++++++++++++++---------- 4 files changed, 296 insertions(+), 133 deletions(-) (limited to 'src/devices/grops') diff --git a/src/devices/grops/TODO b/src/devices/grops/TODO index 7ab3b698..eab8f833 100644 --- a/src/devices/grops/TODO +++ b/src/devices/grops/TODO @@ -1,7 +1,5 @@ Read PFB files directly. -Generate %%DocumentMedia comment. - Generate %%For comment. Generate %%Title comment. diff --git a/src/devices/grops/grops.man b/src/devices/grops/grops.man index e7e40fd3..25acfb27 100644 --- a/src/devices/grops/grops.man +++ b/src/devices/grops/grops.man @@ -23,8 +23,18 @@ the original English. .\" Like TP, but if specified indent is more than half .\" the current line-length - indent, use the default indent. .de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" +. ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP +. el .TP "\\$1" +.. +. +.de TQ +. br +. ns +. TP \$1 +.. +. +.de FT +. if '\\*(.T'ps' .ft \\$1 .. . . @@ -125,13 +135,13 @@ A value of\~0 will cause grops not to employ any workarounds. . .IP Add\~1 if no -.B %%BeginDocumentSetup +.B %%Begin\%Document\%Setup and -.B %%EndDocumentSetup +.B %%End\%Document\%Setup comments should be generated; this is needed for early versions of TranScript that get confused by anything between the -.B %%EndProlog +.B %%End\%Prolog comment and the first .B %%Page comment. @@ -146,13 +156,13 @@ Add\~4 if .BR %%Page , .BR %%Trailer and -.B %%EndProlog +.B %%End\%Prolog comments should be stripped out of included files; this is needed for spoolers that don't understand the -.B %%BeginDocument +.B %%Begin\%Document and -.B %%EndDocument +.B %%End\%Document comments. . .IP @@ -166,7 +176,7 @@ page reversal. .IP Add\~16 if no media size information should be included in the document (this is, neither use -.B %%DocumentMedia +.B %%Document\%Media nor the .B setpagedevice PostScript command). @@ -274,15 +284,11 @@ The fonts are grouped into families .BR H , .BR HN , .BR N , -.B P +.BR P , and\~\c .B T having members in each of these styles: . -.de FT -.if '\\*(.T'ps' .ft \\$1 -.. -. .RS .TP .B AR @@ -290,187 +296,187 @@ having members in each of these styles: AvantGarde-Book .FT . -.TP +.TQ .B AI .FT AI AvantGarde-BookOblique .FT . -.TP +.TQ .B AB .FT AB AvantGarde-Demi .FT . -.TP +.TQ .B ABI .FT ABI AvantGarde-DemiOblique .FT . -.TP +.TQ .B BMR .FT BMR Bookman-Light .FT . -.TP +.TQ .B BMI .FT BMI Bookman-LightItalic .FT . -.TP +.TQ .B BMB .FT BMB Bookman-Demi .FT . -.TP +.TQ .B BMBI .FT BMBI Bookman-DemiItalic .FT . -.TP +.TQ .B CR .FT CR Courier .FT . -.TP +.TQ .B CI .FT CI Courier-Oblique .FT . -.TP +.TQ .B CB .FT CB Courier-Bold .FT . -.TP +.TQ .B CBI .FT CBI Courier-BoldOblique .FT . -.TP +.TQ .B HR .FT HR Helvetica .FT . -.TP +.TQ .B HI .FT HI Helvetica-Oblique .FT . -.TP +.TQ .B HB .FT HB Helvetica-Bold .FT . -.TP +.TQ .B HBI .FT HBI Helvetica-BoldOblique .FT . -.TP +.TQ .B HNR .FT HNR Helvetica-Narrow .FT . -.TP +.TQ .B HNI .FT HNI Helvetica-Narrow-Oblique .FT . -.TP +.TQ .B HNB .FT HNB Helvetica-Narrow-Bold .FT . -.TP +.TQ .B HNBI .FT HNBI Helvetica-Narrow-BoldOblique .FT . -.TP +.TQ .B NR .FT NR NewCenturySchlbk-Roman .FT . -.TP +.TQ .B NI .FT NI NewCenturySchlbk-Italic .FT . -.TP +.TQ .B NB .FT NB NewCenturySchlbk-Bold .FT . -.TP +.TQ .B NBI .FT NBI NewCenturySchlbk-BoldItalic .FT . -.TP +.TQ .B PR .FT PR Palatino-Roman .FT . -.TP +.TQ .B PI .FT PI Palatino-Italic .FT . -.TP +.TQ .B PB .FT PB Palatino-Bold .FT . -.TP +.TQ .B PBI .FT PBI Palatino-BoldItalic .FT . -.TP +.TQ .B TR .FT TR Times-Roman .FT . -.TP +.TQ .B TI .FT TI Times-Italic .FT . -.TP +.TQ .B TB .FT TB Times-Bold .FT . -.TP +.TQ .B TBI .FT TBI Times-BoldItalic @@ -490,9 +496,10 @@ ZapfChancery-MediumItalic . .LP There are also some special fonts called -.B SS -and\~\c -.BR S . +.B S +for the PS Symbol font, and +.BR SS , +containing slanted lowercase Greek letters taken from PS Symbol. . Zapf Dingbats is available as .BR ZD @@ -513,6 +520,10 @@ is used, for `cmy' and `cmyk' .BR setcmykcolor , and for `gray' .BR setgray . +Note that +.B setcmykcolor +is a PostScript LanguageLevel\~2 command and thus not available on some +older printers. . .LP .B grops @@ -702,7 +713,7 @@ arguments are not allowed to have attached scaling indicators. . If the PostScript file complies with the Adobe Document Structuring Conventions and contains a -.B %%BoundingBox +.B %%Bounding\%Box comment, then the bounding box can be automatically extracted from within groff by using the .B psbb @@ -763,9 +774,7 @@ option causes the graphic to be indented by\~\c . .TP .B \[rs]X'ps:\ invis' -.br -.ns -.TP +.TQ .B \[rs]X'ps:\ endinvis' No output will be generated for text and drawing commands that are bracketed with these @@ -812,7 +821,12 @@ whereas will print the .B \[rs](em character -and ignore the line. +and ignore the line (this code is already in file +.B Xps.tmac +which will be loaded if a documented intended for +.B grops +is previewed with +.BR gxditview ). .RE . .LP @@ -884,7 +898,8 @@ where is the PostScript name of the character, and .I code -is its position in the encoding expressed as a decimal integer. +is its position in the encoding expressed as a decimal integer; valid +values are in the range 0 to\~255. . Lines starting with .B # @@ -913,10 +928,24 @@ it can make use of such a character to generate more efficient and compact PostScript output. . .LP +Note that +.B grops +is able to display all glyphs in a PostScript font, not only 256. +.I enc_file +(or the default encoding if no encoding file specified) just defines the +order of glyphs for the first 256 characters; all other glyphs are +accessed with additional encoding vectors which +.B grops +produces on the fly. +. +.LP .B grops can automatically include the downloadable fonts necessary to print the document. -. +Such fonts must be in PFA format. +Use +.BR pfbtops (@MAN1EXT@) +to convert a Type\~1 font in PFB format. Any downloadable fonts which should, when required, be included by .B grops must be listed in the file @@ -997,30 +1026,30 @@ in the file. . A downloadable font should not include its own name in a -.B %%DocumentSuppliedResources +.B %%Document\%Supplied\%Resources comment. . .LP .B grops will not interpret -.B %%DocumentFonts +.B %%Document\%Fonts comments. . The -.BR %%DocumentNeededResources , -.BR %%DocumentSuppliedResources , -.BR %%IncludeResource , -.BR %%BeginResource +.BR %%Document\%Needed\%Resources , +.BR %%Document\%Supplied\%Resources , +.BR %%Include\%Resource , +.BR %%Begin\%Resource , and -.BR %%EndResource +.BR %%End\%Resource comments (or possibly the old -.BR %%DocumentNeededFonts , -.BR %%DocumentSuppliedFonts , -.BR %%IncludeFont , -.BR %%BeginFont +.BR %%Document\%Needed\%Fonts , +.BR %%Document\%Supplied\%Fonts , +.BR %%Include\%Font , +.BR %%Begin\%Font , and -.BR %%EndFont +.BR %%End\%Font comments) should be used. . @@ -1120,7 +1149,7 @@ Temporary file. .BR afmtodit (@MAN1EXT@), .BR groff (@MAN1EXT@), .BR @g@troff (@MAN1EXT@), -.BR psbb (@MAN1EXT@), +.BR pfbtops (@MAN1EXT@), .BR groff_out (@MAN5EXT@), .BR groff_font (@MAN5EXT@), .BR groff_char (@MAN7EXT@) diff --git a/src/devices/grops/ps.cc b/src/devices/grops/ps.cc index 3cea8631..129f1bf3 100644 --- a/src/devices/grops/ps.cc +++ b/src/devices/grops/ps.cc @@ -451,13 +451,38 @@ static void handle_unknown_desc_command(const char *command, const char *arg, } } +struct subencoding { + font *p; + unsigned int num; + int idx; + char *subfont; + const char *glyphs[256]; + subencoding *next; + + subencoding(font *, unsigned int, int, subencoding *); + ~subencoding(); +}; + +subencoding::subencoding(font *f, unsigned int n, int ix, subencoding *s) +: p(f), num(n), idx(ix), subfont(0), next(s) +{ + for (int i = 0; i < 256; i++) + glyphs[i] = 0; +} + +subencoding::~subencoding() +{ + a_delete subfont; +} + struct style { font *f; + subencoding *sub; int point_size; int height; int slant; style(); - style(font *, int, int, int); + style(font *, subencoding *, int, int, int); int operator==(const style &) const; int operator!=(const style &) const; }; @@ -466,15 +491,18 @@ style::style() : f(0) { } -style::style(font *p, int sz, int h, int sl) -: f(p), point_size(sz), height(h), slant(sl) +style::style(font *p, subencoding *s, int sz, int h, int sl) +: f(p), sub(s), point_size(sz), height(h), slant(sl) { } int style::operator==(const style &s) const { - return (f == s.f && point_size == s.point_size - && height == s.height && slant == s.slant); + return (f == s.f + && sub == s.sub + && point_size == s.point_size + && height == s.height + && slant == s.slant); } int style::operator!=(const style &s) const @@ -504,6 +532,7 @@ class ps_printer : public printer { style sbuf_style; color sbuf_color; // the current PS color style output_style; + subencoding *subencodings; int output_hpos; int output_vpos; int output_draw_point_size; @@ -514,6 +543,7 @@ class ps_printer : public printer { style defined_styles[MAX_DEFINED_STYLES]; int ndefined_styles; int next_encoding_index; + int next_subencoding_index; string defs; int ndefs; resource_manager rm; @@ -523,6 +553,8 @@ class ps_printer : public printer { void set_style(const style &); void set_space_code(unsigned char c); int set_encoding_index(ps_font *); + subencoding *set_subencoding(font *, int, unsigned char *); + char *get_subfont(subencoding *, const char *); void do_exec(char *, const environment *); void do_import(char *, const environment *); void do_def(char *, const environment *); @@ -533,6 +565,7 @@ class ps_printer : public printer { void set_line_thickness_and_color(const environment *); void fill_path(const environment *); void encode_fonts(); + void encode_subfont(subencoding *); void define_encoding(const char *, int); void reencode_font(ps_font *); void set_color(color *c, int fill = 0); @@ -545,7 +578,8 @@ class ps_printer : public printer { public: ps_printer(double); ~ps_printer(); - void set_char(int i, font *f, const environment *env, int w, const char *name); + void set_char(int i, font *f, const environment *env, int w, + const char *name); void draw(int code, int *p, int np, const environment *env); void begin_page(int); void end_page(int); @@ -559,11 +593,13 @@ ps_printer::ps_printer(double pl) : out(0, MAX_LINE_LENGTH), pages_output(0), sbuf_len(0), + subencodings(0), output_hpos(-1), output_vpos(-1), line_thickness(-1), ndefined_styles(0), next_encoding_index(0), + next_subencoding_index(0), ndefs(0), invis_count(0) { @@ -611,13 +647,43 @@ int ps_printer::set_encoding_index(ps_font *f) return f->encoding_index = next_encoding_index++; } +subencoding *ps_printer::set_subencoding(font *f, int i, unsigned char *codep) +{ + unsigned int idx = f->get_code(i); + *codep = idx % 256; + unsigned int num = idx >> 8; + if (num == 0) + return 0; + subencoding *p = 0; + for (p = subencodings; p; p = p->next) + if (p->p == f && p->num == num) + break; + if (p == 0) + p = subencodings = new subencoding(f, num, next_subencoding_index++, + subencodings); + p->glyphs[*codep] = f->get_special_device_encoding(i); + return p; +} + +char *ps_printer::get_subfont(subencoding *sub, const char *stem) +{ + assert(sub != 0); + if (!sub->subfont) { + char *tem = new char[strlen(stem) + 2 + INT_DIGITS + 1]; + sprintf(tem, "%s@@%d", stem, next_subencoding_index); + sub->subfont = tem; + } + return sub->subfont; +} + void ps_printer::set_char(int i, font *f, const environment *env, int w, const char *) { if (i == space_char_index || invis_count > 0) return; - unsigned char code = f->get_code(i); - style sty(f, env->size, env->height, env->slant); + unsigned char code; + subencoding *sub = set_subencoding(f, i, &code); + style sty(f, sub, env->size, env->height, env->slant); if (sty.slant != 0) { if (sty.slant > 80 || sty.slant < -80) { error("silly slant `%1' degrees", sty.slant); @@ -694,6 +760,13 @@ static char *make_encoding_name(int encoding_index) return buf; } +static char *make_subencoding_name(int subencoding_index) +{ + static char buf[6 + INT_DIGITS + 1]; + sprintf(buf, "SUBENC%d", subencoding_index); + return buf; +} + const char *const WS = " \t\n\r"; void ps_printer::define_encoding(const char *encoding, int encoding_index) @@ -724,8 +797,8 @@ void ps_printer::define_encoding(const char *encoding, int encoding_index) lineno++; } a_delete path; - out.put_literal_symbol(make_encoding_name(encoding_index)); - out.put_delimiter('['); + out.put_literal_symbol(make_encoding_name(encoding_index)) + .put_delimiter('['); for (i = 0; i < 256; i++) { if (vec[i] == 0) out.put_literal_symbol(".notdef"); @@ -768,6 +841,22 @@ void ps_printer::encode_fonts() a_delete done_encoding; } +void ps_printer::encode_subfont(subencoding *sub) +{ + assert(sub->glyphs != 0); + out.put_literal_symbol(make_subencoding_name(sub->idx)) + .put_delimiter('['); + for (int i = 0; i < 256; i++) + { + if (sub->glyphs[i]) + out.put_literal_symbol(sub->glyphs[i]); + else + out.put_literal_symbol(".notdef"); + } + out.put_delimiter(']') + .put_symbol("def"); +} + void ps_printer::set_style(const style &sty) { char buf[1 + INT_DIGITS + 1]; @@ -785,18 +874,22 @@ void ps_printer::set_style(const style &sty) if (psname == 0) fatal("no internalname specified for font `%1'", sty.f->get_name()); char *encoding = ((ps_font *)sty.f)->encoding; - if (encoding != 0) { - char *s = ((ps_font *)sty.f)->reencoded_name; - if (s == 0) { - int ei = set_encoding_index((ps_font *)sty.f); - char *tem = new char[strlen(psname) + 1 + INT_DIGITS + 1]; - sprintf(tem, "%s@%d", psname, ei); - psname = tem; - ((ps_font *)sty.f)->reencoded_name = tem; + if (sty.sub == 0) { + if (encoding != 0) { + char *s = ((ps_font *)sty.f)->reencoded_name; + if (s == 0) { + int ei = set_encoding_index((ps_font *)sty.f); + char *tem = new char[strlen(psname) + 1 + INT_DIGITS + 1]; + sprintf(tem, "%s@%d", psname, ei); + psname = tem; + ((ps_font *)sty.f)->reencoded_name = tem; + } + else + psname = s; } - else - psname = s; } + else + psname = get_subfont(sty.sub, psname); out.put_fix_number((font::res/(72*font::sizescale))*sty.point_size); if (sty.height != 0 || sty.slant != 0) { int h = sty.height == 0 ? sty.point_size : sty.height; @@ -1302,12 +1395,12 @@ ps_printer::~ps_printer() if (!(broken_flags & NO_PAPERSIZE)) { fprintf(out.get_file(), "%%%%DocumentMedia: %s %d %d %d %s %s\n", - media_name(), /* tag name of media */ - media_width(), /* media width */ - media_height(), /* media height */ - 0, /* weight in g/m2 */ - "()", /* paper color, e.g. white */ - "()" /* preprinted form type */ + media_name(), // tag name of media + media_width(), // media width + media_height(), // media height + 0, // weight in g/m2 + "()", // paper color, e.g. white + "()" // preprinted form type ); } @@ -1388,6 +1481,16 @@ ps_printer::~ps_printer() .simple_comment("EndFeature"); } encode_fonts(); + while (subencodings) { + subencoding *tem = subencodings; + subencodings = subencodings->next; + encode_subfont(tem); + out.put_literal_symbol(tem->subfont) + .put_symbol(make_subencoding_name(tem->idx)) + .put_literal_symbol(tem->p->get_internal_name()) + .put_symbol("RE"); + delete tem; + } out.simple_comment((broken_flags & NO_SETUP_SECTION) ? "EndProlog" : "EndSetup"); diff --git a/src/devices/grops/psrm.cc b/src/devices/grops/psrm.cc index d3ece2de..87fcc4d9 100644 --- a/src/devices/grops/psrm.cc +++ b/src/devices/grops/psrm.cc @@ -35,9 +35,51 @@ extern "C" { static void print_ps_string(const string &s, FILE *outfp); -cset white_space("\n\r \t"); +cset white_space("\n\r \t\f"); string an_empty_string; +char valid_input_table[256]= { +#ifndef IS_EBCDIC_HOST + // ASCII + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#else + // CP 1047 + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, +#endif +}; + const char *extension_table[] = { "DPS", "CMYK", @@ -373,34 +415,23 @@ void resource_manager::supply_resource(resource *r, int rank, FILE *outfp, r->flags &= ~resource::BUSY; } - -#define PS_LINE_MAX 255 #define PS_MAGIC "%!PS-Adobe-" -static int ps_get_line(char *buf, FILE *fp) +static int ps_get_line(string &buf, FILE *fp) { + buf.clear(); int c = getc(fp); - if (c == EOF) { - buf[0] = '\0'; + if (c == EOF) return 0; - } current_lineno++; - int i = 0; - int err = 0; while (c != '\r' && c != '\n' && c != EOF) { - if ((c < 0x1b && !white_space(c)) || c == 0x7f) + if (!valid_input_table[c]) error("invalid input character code %1", int(c)); - else if (i < PS_LINE_MAX) - buf[i++] = c; - else if (!err) { - err = 1; - error("PostScript file non-conforming " - "because length of line exceeds 255"); - } + buf += c; c = getc(fp); } - buf[i++] = '\n'; - buf[i] = '\0'; + buf += '\n'; + buf += '\0'; if (c == '\r') { c = getc(fp); if (c != EOF && c != '\n') @@ -551,17 +582,20 @@ resource *resource_manager::read_resource_arg(const char **ptr) return lookup_resource(resource_type(ri), arg); } -static const char *matches_comment(const char *buf, const char *comment) +static const char *matches_comment(string &buf, const char *comment) { + if ((size_t)buf.length() < strlen(comment) + 3) + return 0; if (buf[0] != '%' || buf[1] != '%') return 0; - for (buf += 2; *comment; comment++, buf++) - if (*buf != *comment) + const char *bufp = buf.contents() + 2; + for (; *comment; comment++, bufp++) + if (*bufp != *comment) return 0; if (comment[-1] == ':') - return buf; - if (*buf == '\0' || white_space(*buf)) - return buf; + return bufp; + if (*bufp == '\0' || white_space(*bufp)) + return bufp; return 0; } @@ -697,7 +731,7 @@ int resource_manager::change_to_end_resource(const char *, int, FILE *, int resource_manager::do_begin_preview(const char *, int, FILE *fp, FILE *) { - char buf[PS_LINE_MAX + 2]; + string buf; do { if (!ps_get_line(buf, fp)) { error("end of file in preview section"); @@ -817,7 +851,7 @@ int resource_manager::do_begin_data(const char *ptr, int, FILE *fp, } while ((unit == Bytes ? bytecount : linecount) < numberof); } skip_possible_newline(fp, outfp); - char buf[PS_LINE_MAX + 2]; + string buf; if (!ps_get_line(buf, fp)) { error("missing %%%%EndData line"); return 0; @@ -825,7 +859,7 @@ int resource_manager::do_begin_data(const char *ptr, int, FILE *fp, if (!matches_comment(buf, "EndData")) error("bad %%%%EndData line"); if (outfp) - fputs(buf, outfp); + fputs(buf.contents(), outfp); return 0; } @@ -859,7 +893,7 @@ int resource_manager::do_begin_binary(const char *ptr, int, FILE *fp, current_lineno++; } skip_possible_newline(fp, outfp); - char buf[PS_LINE_MAX + 2]; + string buf; if (!ps_get_line(buf, fp)) { error("missing %%%%EndBinary line"); return 0; @@ -867,7 +901,7 @@ int resource_manager::do_begin_binary(const char *ptr, int, FILE *fp, if (!matches_comment(buf, "EndBinary")) { error("bad %%%%EndBinary line"); if (outfp) - fputs(buf, outfp); + fputs(buf.contents(), outfp); } else if (outfp) fputs("%%EndData\n", outfp); @@ -952,7 +986,7 @@ void resource_manager::process_file(int rank, FILE *fp, const char *filename, }; const int NCOMMENTS = sizeof(comment_table)/sizeof(comment_table[0]); - char buf[PS_LINE_MAX + 2]; + string buf; int saved_lineno = current_lineno; const char *saved_filename = current_filename; current_filename = filename; @@ -962,19 +996,19 @@ void resource_manager::process_file(int rank, FILE *fp, const char *filename, current_lineno = saved_lineno; return; } - if (strlen(buf) < sizeof(PS_MAGIC) - 1 - || memcmp(buf, PS_MAGIC, sizeof(PS_MAGIC) - 1) != 0) { + if ((size_t)buf.length() < sizeof(PS_MAGIC) + || memcmp(buf.contents(), PS_MAGIC, sizeof(PS_MAGIC) - 1) != 0) { if (outfp) { do { if (!(broken_flags & STRIP_PERCENT_BANG) || buf[0] != '%' || buf[1] != '!') - fputs(buf, outfp); + fputs(buf.contents(), outfp); } while (ps_get_line(buf, fp)); } } else { if (!(broken_flags & STRIP_PERCENT_BANG) && outfp) - fputs(buf, outfp); + fputs(buf.contents(), outfp); int in_header = 1; int interesting = 0; int had_extensions_comment = 0; @@ -1033,7 +1067,7 @@ void resource_manager::process_file(int rank, FILE *fp, const char *filename, if (!outfp && !in_header && !interesting) break; if (copy_this_line && outfp) - fputs(buf, outfp); + fputs(buf.contents(), outfp); } } current_filename = saved_filename; @@ -1144,4 +1178,3 @@ void resource_manager::print_language_level_comment(FILE *outfp) if (language_level) fprintf(outfp, "%%%%LanguageLevel: %u\n", language_level); } - -- cgit v1.2.1