📄 ps.cc
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING. If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "driver.h"#include "stringclass.h"#include "cset.h"#include "ps.h"static int landscape_flag = 0;static int ncopies = 1;static int linewidth = -1;// Non-zero means generate PostScript code that guesses the paper// length using the imageable area.static int guess_flag = 0;// Non-zero if -b was specified on the command line.static int bflag = 0;unsigned broken_flags = 0;#define DEFAULT_LINEWIDTH 40 /* in ems/1000 */#define FILL_MAX 1000const char *const dict_name = "grops";const char *const defs_dict_name = "DEFS";const int DEFS_DICT_SPARE = 50;double degrees(double r){ return r*180.0/M_PI;}double radians(double d){ return d*M_PI/180.0;}inline double transform_fill(int fill){ return 1 - fill/double(FILL_MAX);}ps_output::ps_output(FILE *f, int n): fp(f), max_line_length(n), col(0), need_space(0), fixed_point(0){}ps_output &ps_output::set_file(FILE *f){ fp = f; col = 0; return *this;}ps_output &ps_output::copy_file(FILE *infp){ int c; while ((c = getc(infp)) != EOF) putc(c, fp); return *this;}ps_output &ps_output::end_line(){ if (col != 0) { putc('\n', fp); col = 0; need_space = 0; } return *this;}ps_output &ps_output::special(const char *s){ if (s == 0 || *s == '\0') return *this; if (col != 0) { putc('\n', fp); col = 0; } fputs(s, fp); if (strchr(s, '\0')[-1] != '\n') putc('\n', fp); need_space = 0; return *this;}ps_output &ps_output::simple_comment(const char *s){ if (col != 0) putc('\n', fp); putc('%', fp); putc('%', fp); fputs(s, fp); putc('\n', fp); col = 0; need_space = 0; return *this;}ps_output &ps_output::begin_comment(const char *s){ if (col != 0) putc('\n', fp); putc('%', fp); putc('%', fp); fputs(s, fp); col = 2 + strlen(s); return *this;}ps_output &ps_output::end_comment(){ if (col != 0) { putc('\n', fp); col = 0; } need_space = 0; return *this;}ps_output &ps_output::comment_arg(const char *s){ int len = strlen(s); if (col + len + 1 > max_line_length) { putc('\n', fp); fputs("%%+", fp); col = 3; } putc(' ', fp); fputs(s, fp); col += len + 1; return *this;}ps_output &ps_output::set_fixed_point(int n){ assert(n >= 0 && n <= 10); fixed_point = n; return *this;}ps_output &ps_output::put_delimiter(char c){ if (col + 1 > max_line_length) { putc('\n', fp); col = 0; } putc(c, fp); col++; need_space = 0; return *this;}ps_output &ps_output::put_string(const char *s, int n){ int len = 0; for (int i = 0; i < n; i++) { char c = s[i]; if (isascii(c) && isprint(c)) { if (c == '(' || c == ')' || c == '\\') len += 2; else len += 1; } else len += 4; } if (len > n*2) { if (col + n*2 + 2 > max_line_length && n*2 + 2 <= max_line_length) { putc('\n', fp); col = 0; } if (col + 1 > max_line_length) { putc('\n', fp); col = 0; } putc('<', fp); col++; for (i = 0; i < n; i++) { if (col + 2 > max_line_length) { putc('\n', fp); col = 0; } fprintf(fp, "%02x", s[i] & 0377); col += 2; } putc('>', fp); col++; } else { if (col + len + 2 > max_line_length && len + 2 <= max_line_length) { putc('\n', fp); col = 0; } if (col + 2 > max_line_length) { putc('\n', fp); col = 0; } putc('(', fp); col++; for (i = 0; i < n; i++) { char c = s[i]; if (isascii(c) && isprint(c)) { if (c == '(' || c == ')' || c == '\\') len = 2; else len = 1; } else len = 4; if (col + len + 1 > max_line_length) { putc('\\', fp); putc('\n', fp); col = 0; } switch (len) { case 1: putc(c, fp); break; case 2: putc('\\', fp); putc(c, fp); break; case 4: fprintf(fp, "\\%03o", c & 0377); break; default: assert(0); } col += len; } putc(')', fp); col++; } need_space = 0; return *this;}ps_output &ps_output::put_number(int n){ char buf[1 + INT_DIGITS + 1]; sprintf(buf, "%d", n); int len = strlen(buf); if (col > 0 && col + len + need_space > max_line_length) { putc('\n', fp); col = 0; need_space = 0; } if (need_space) { putc(' ', fp); col++; } fputs(buf, fp); col += len; need_space = 1; return *this;}ps_output &ps_output::put_fix_number(int i){ const char *p = iftoa(i, fixed_point); int len = strlen(p); if (col > 0 && col + len + need_space > max_line_length) { putc('\n', fp); col = 0; need_space = 0; } if (need_space) { putc(' ', fp); col++; } fputs(p, fp); col += len; need_space = 1; return *this;}ps_output &ps_output::put_float(double d){ char buf[128]; sprintf(buf, "%.4f", d); int len = strlen(buf); if (col > 0 && col + len + need_space > max_line_length) { putc('\n', fp); col = 0; need_space = 0; } if (need_space) { putc(' ', fp); col++; } fputs(buf, fp); col += len; need_space = 1; return *this;}ps_output &ps_output::put_symbol(const char *s){ int len = strlen(s); if (col > 0 && col + len + need_space > max_line_length) { putc('\n', fp); col = 0; need_space = 0; } if (need_space) { putc(' ', fp); col++; } fputs(s, fp); col += len; need_space = 1; return *this;}ps_output &ps_output::put_literal_symbol(const char *s){ int len = strlen(s); if (col > 0 && col + len + 1 > max_line_length) { putc('\n', fp); col = 0; } putc('/', fp); fputs(s, fp); col += len + 1; need_space = 1; return *this;}class ps_font : public font { ps_font(const char *);public: int encoding_index; char *encoding; char *reencoded_name; ~ps_font(); void handle_unknown_font_command(const char *command, const char *arg, const char *filename, int lineno); static ps_font *load_ps_font(const char *);};ps_font *ps_font::load_ps_font(const char *s){ ps_font *f = new ps_font(s); if (!f->load()) { delete f; return 0; } return f;}ps_font::ps_font(const char *nm): font(nm), encoding(0), reencoded_name(0), encoding_index(-1){}ps_font::~ps_font(){ a_delete encoding; a_delete reencoded_name;}void ps_font::handle_unknown_font_command(const char *command, const char *arg, const char *filename, int lineno){ if (strcmp(command, "encoding") == 0) { if (arg == 0) error_with_file_and_line(filename, lineno, "`encoding' command requires an argument"); else encoding = strsave(arg); }}static void handle_unknown_desc_command(const char *command, const char *arg, const char *filename, int lineno){ if (strcmp(command, "broken") == 0) { if (arg == 0) error_with_file_and_line(filename, lineno, "`broken' command requires an argument"); else if (!bflag) broken_flags = atoi(arg); }}struct style { font *f; int point_size; int height; int slant; style(); style(font *, int, int, int); int operator==(const style &) const; int operator!=(const style &) const;};style::style() : f(0){}style::style(font *p, int sz, int h, int sl): f(p), 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);}int style::operator!=(const style &s) const{ return !(*this == s);}class ps_printer : public printer { FILE *tempfp; ps_output out; int res; int space_char_index; int pages_output; int paper_length; int equalise_spaces; enum { SBUF_SIZE = 256 }; char sbuf[SBUF_SIZE]; int sbuf_len; int sbuf_start_hpos; int sbuf_vpos; int sbuf_end_hpos; int sbuf_space_width; int sbuf_space_count; int sbuf_space_diff_count; int sbuf_space_code; int sbuf_kern; style sbuf_style; style output_style; int output_hpos; int output_vpos; int output_draw_point_size; int line_thickness; int output_line_thickness; int fill; unsigned char output_space_code; enum { MAX_DEFINED_STYLES = 50 }; style defined_styles[MAX_DEFINED_STYLES]; int ndefined_styles; int next_encoding_index; string defs; int ndefs; resource_manager rm; int invis_count; void flush_sbuf(); void set_style(const style &); void set_space_code(unsigned char c); int set_encoding_index(ps_font *); void do_exec(char *, const environment *); void do_import(char *, const environment *); void do_def(char *, const environment *); void do_mdef(char *, const environment *); void do_file(char *, const environment *); void do_invis(char *, const environment *); void do_endinvis(char *, const environment *); void set_line_thickness(const environment *); void fill_path(); void encode_fonts(); void define_encoding(const char *, int); void reencode_font(ps_font *);public: ps_printer(); ~ps_printer(); void set_char(int i, font *f, const environment *env, int w); void draw(int code, int *p, int np, const environment *env); void begin_page(int); void end_page(int); void special(char *arg, const environment *env); font *make_font(const char *); void end_of_line();};ps_printer::ps_printer(): pages_output(0), sbuf_len(0),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -