diff options
Diffstat (limited to 'contrib/groff/grolbp/lbp.cc')
-rw-r--r-- | contrib/groff/grolbp/lbp.cc | 772 |
1 files changed, 0 insertions, 772 deletions
diff --git a/contrib/groff/grolbp/lbp.cc b/contrib/groff/grolbp/lbp.cc deleted file mode 100644 index fe06e1c41cf4b..0000000000000 --- a/contrib/groff/grolbp/lbp.cc +++ /dev/null @@ -1,772 +0,0 @@ -// -*- C++ -*- -/* Copyright (C) 1994 Free Software Foundation, Inc. - Written by Francisco Andrés Verdú <pandres@dragonet.es> with many ideas - taken from the other groff drivers. - - -This file is part of groff. - -groff is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* -TODO - - - Add X command to include bitmaps -*/ -#define _GNU_SOURCE - -#include "driver.h" -#include "lbp.h" -#include "charset.h" - -#include "nonposix.h" - -#ifdef HAVE_STRNCASECMP -#ifdef NEED_DECLARATION_STRNCASECMP -extern "C" { - // SunOS's string.h fails to declare this. - int strncasecmp(const char *, const char *, int); -} -#endif /* NEED_DECLARATION_STRNCASECMP */ -#endif /* HAVE_STRNCASECMP */ - -static short int papersize = -1, // papersize - orientation = -1 , // orientation - paperlength = 0, // Custom Paper size - paperwidth = 0, - ncopies = 1; // Number of copies - -class lbp_font : public font { -public: - ~lbp_font(); - void handle_unknown_font_command(const char *command, const char *arg, - const char *filename, int lineno); - static lbp_font *load_lbp_font(const char *); - char *lbpname; - char is_scalable; -private: - lbp_font(const char *); -}; - -class lbp_printer : public printer { -public: - lbp_printer(); - ~lbp_printer(); - void set_char(int, font *, const environment *, int, const char *name); - void draw(int code, int *p, int np, const environment *env); - void begin_page(int); - void end_page(int page_length); - font *make_font(const char *); - void end_of_line(); -private: - void set_line_thickness(int size, int dot = 0); - void vdmstart(); - void vdmflush(); // the name vdmend was already used in lbp.h - void setfillmode(int mode); - void polygon( int hpos,int vpos,int np,int *p); - char *font_name(const lbp_font *f, const int siz); - - int fill_pattern; - int fill_mode; - int cur_hpos; - int cur_vpos; - lbp_font *cur_font; - int cur_size; - unsigned short cur_symbol_set; - int line_thickness; -}; - -// Compatibility section. -// -// Here we define some functions not present in some of the targets -// platforms -#ifndef HAVE_STRSEP -// Solaris 8 doesn't have the strsep function -static char *strsep(char **pcadena, const char *delim) -{ - char *p; - - p = strtok(*pcadena,delim); - *pcadena = strtok(NULL,delim); - return p; - -}; -#endif - -#ifndef HAVE_STRDUP -// Ditto with OS/390 and strdup -static char *strdup(const char *s) -{ - char *result; - - result = (char *)malloc(strlen(s)+1); - if (result != NULL) strcpy(result,s); - return result; - -}; // strdup - -#endif -lbp_font::lbp_font(const char *nm) -: font(nm) -{ -} - -lbp_font::~lbp_font() -{ -} - -lbp_font *lbp_font::load_lbp_font(const char *s) -{ - lbp_font *f = new lbp_font(s); - f->lbpname = NULL; - f->is_scalable = 1; // Default is that fonts are scalable - if (!f->load()) { - delete f; - return 0; - } - return f; -} - - -void lbp_font::handle_unknown_font_command(const char *command, - const char *arg, - const char *filename, int lineno) -{ - if (strcmp(command, "lbpname") == 0) { - if (arg == 0) - fatal_with_file_and_line(filename, lineno, - "`%1' command requires an argument", - command); - this->lbpname = new char[strlen(arg)+1]; - strcpy(this->lbpname,arg); - // We Recongnize bitmaped fonts by the first character of it's name - if (arg[0] == 'N') this->is_scalable = 0; - // fprintf(stderr,"Loading font \"%s\" \n",arg); - }; // if (strcmp(command, "lbpname") - // fprintf(stderr,"Loading font %s \"%s\" in %s at %d\n",command,arg,filename,lineno); -}; - -static void wp54charset() -{ - int i; - - lbpputs("\033[714;100;29;0;32;120.}"); - for (i = 0; i < sizeof(symset) ; i++) lbpputc(symset[i]); - lbpputs("\033[100;0 D"); - return ; -}; - -lbp_printer::lbp_printer() -: fill_pattern(1), - fill_mode(0), - cur_hpos(-1), - cur_font(0), - cur_size(0), - cur_symbol_set(0), - line_thickness(-1) -{ -#ifdef SET_BINARY - SET_BINARY(fileno(stdout)); -#endif - lbpinit(stdout); - lbpputs("\033c\033;\033[2&z\033[7 I\033[?32h\033[?33h\033[11h"); - wp54charset(); // Define the new symbol set - lbpputs("\033[7 I\033[?32h\033[?33h\033[11h"); - // Paper size handling - if (orientation < 0) orientation = 0;// Default orientation is portrait - if (papersize < 0) papersize = 14; // Default paper size is A4 - if (papersize < 80) // standard paper - lbpprintf("\033[%dp",(papersize | orientation)); - else // Custom paper - lbpprintf("\033[%d;%d;%dp",(papersize | orientation),\ - paperlength,paperwidth); - - // Number of copies - lbpprintf("\033[%dv\n",ncopies); - - lbpputs("\033[0u\033[1u\033P1y Grolbp\033\\"); - lbpmoveabs(0,0); - lbpputs("\033[0t\033[2t"); - lbpputs("\033('$2\033)' 1"); // Primary symbol set IBML - // Secondary symbol set IBMR1 - cur_symbol_set = 0; -}; - -lbp_printer::~lbp_printer() -{ - lbpputs("\033P1y\033\\"); - lbpputs("\033c\033<"); -} - -void lbp_printer::begin_page(int) -{ -} - -void lbp_printer::end_page(int) -{ - if (vdminited()) vdmflush(); - lbpputc('\f'); - cur_hpos = -1; -} - -void lbp_printer::end_of_line() -{ - cur_hpos = -1; // force absolute motion -} - -char *lbp_printer::font_name(const lbp_font *f, const int siz) -{ - static char bfont_name[255] ; // The resulting font name - char type, // Italic, Roman, Bold - ori, // Normal or Rotated - *nam; // The font name without other data. -// nam[strlen(f->lbpname)-2]; // The font name without other data. - int cpi; // The font size in characters per inch - // (Bitmaped fonts are monospaced). - - - /* Bitmap font selection is ugly in this printer, so don't expect - this function to be elegant. */ - - bfont_name[0] = 0x00; - if (orientation) // Landscape - ori = 'R'; - else // Portrait - ori = 'N'; - type = f->lbpname[strlen(f->lbpname)-1]; - nam = new char[strlen(f->lbpname)-2]; - strncpy(nam,&(f->lbpname[1]),strlen(f->lbpname)-2); - nam[strlen(f->lbpname)-2] = 0x00; - // fprintf(stderr,"Bitmap font '%s' %d %c %c \n",nam,siz,type,ori); - /* Since these fonts are avaiable only at certain sizes, - 10 and 17 cpi for courier, 12 and 17 cpi for elite, - we adjust the resulting size. */ - cpi = 17; - // Fortunately there were only two bitmaped fonts shiped with the printer. - if (!strcasecmp(nam,"courier")) - { // Courier font - if (siz >= 12) cpi = 10; - else cpi = 17; - }; - if (!strcasecmp(nam,"elite")) - { // Elite font - if (siz >= 10) cpi = 12; - else cpi = 17; - }; - - // Now that we have all the data, let's generate the font name. - if ((type != 'B') && (type != 'I')) // Roman font - sprintf(bfont_name,"%c%s%d",ori,nam,cpi); - else - sprintf(bfont_name,"%c%s%d%c",ori,nam,cpi,type); - - return bfont_name; - -}; // lbp_printer::font_name - -void lbp_printer::set_char(int index, font *f, const environment *env, int w, const char *name) -{ - int code = f->get_code(index); - - unsigned char ch = code & 0xff; - unsigned short symbol_set = code >> 8; - if (f != cur_font) { - lbp_font *psf = (lbp_font *)f; - // fprintf(stderr,"Loading font %s \"%d\" \n",psf->lbpname,env->size); - if (psf->is_scalable) - { // Scalable font selection is different from bitmaped - lbpprintf("\033Pz%s.IBML\033\\\033[%d C",psf->lbpname,\ - (int)((env->size*300)/72)); - } else - { // Bitmaped font - lbpprintf("\033Pz%s.IBML\033\\\n",font_name(psf,env->size)); - }; - lbpputs("\033)' 1"); // Select IBML and IBMR1 symbol set - cur_size = env->size; - cur_font = psf; - cur_symbol_set = 0; - } - if (symbol_set != cur_symbol_set) { - if ( cur_symbol_set == 3 ) { - // if current symbol set is Symbol we must restore the font - lbpprintf("\033Pz%s.IBML\033\\\033[%d C",cur_font->lbpname,\ - (int)((env->size*300)/72)); - }; // if ( cur_symbol_set == 3 ) - switch (symbol_set) { - case 0: lbpputs("\033('$2\033)' 1"); // Select IBML and IBMR1 symbol sets - break; - case 1: lbpputs("\033(d\033)' 1"); // Select wp54 symbol set - break; - case 2: lbpputs("\033('$2\033)'!0"); // Select IBMP symbol set - break; - case 3: lbpprintf("\033PzSymbol.SYML\033\\\033[%d C",\ - (int)((env->size*300)/72)); - lbpputs("\033(\"!!0\033)\"!!1"); // Select symbol font - break; - case 4: lbpputs("\033)\"! 1\033(\"!$2"); // Select PS symbol set - break; - }; // switch (symbol_set) - -// if (symbol_set == 1) lbpputs("\033(d"); // Select wp54 symbol set -// else lbpputs("\033('$2\033)' 1"); // Select IBML and IBMR1 symbol sets - cur_symbol_set = symbol_set; - } - if (env->size != cur_size) { - - if (!cur_font->is_scalable) - lbpprintf("\033Pz%s.IBML\033\\\n",font_name(cur_font,env->size)); - else - lbpprintf("\033[%d C",(int)((env->size*300)/72)); - cur_size = env->size; - } - if ((env->hpos != cur_hpos) || (env->vpos != cur_vpos)) - { - // lbpmoveabs(env->hpos - ((5*300)/16),env->vpos ); - lbpmoveabs(env->hpos - 64,env->vpos - 64 ); - cur_vpos = env->vpos; - cur_hpos = env->hpos; - }; - if ((ch & 0x7F) < 32) lbpputs("\033[1.v"); - lbpputc(ch); - cur_hpos += w; -}; - -void -lbp_printer::vdmstart() -{ - FILE *f; - static int changed_origin = 0; - - errno = 0; - f = tmpfile(); - // f = fopen("/tmp/gtmp","w+"); - if (f == NULL) perror("Openinig temp file"); - vdminit(f); - if (!changed_origin) { // we should change the origin only one time - changed_origin = 1; - vdmorigin(-63,0); - }; - vdmlinewidth(line_thickness); - -}; - -void -lbp_printer::vdmflush() -{ - char buffer[1024]; - int bytes_read = 1; - - vdmend(); - fflush(lbpoutput); - /* lets copy the vdm code to the output */ - rewind(vdmoutput); - do - { - bytes_read = fread(buffer,1,sizeof(buffer),vdmoutput); - bytes_read = fwrite(buffer,1,bytes_read,lbpoutput); - } while ( bytes_read == sizeof(buffer)); - - fclose(vdmoutput); // This will also delete the file, - // since it is created by tmpfile() - vdmoutput = NULL; - -}; // lbp_printer::vdmflush - -inline void -lbp_printer::setfillmode(int mode) -{ - if (mode != fill_mode) { - if (mode != 1) vdmsetfillmode(mode,1,0); - else vdmsetfillmode(mode,1,1); // To get black we must use white - // inverted - fill_mode = mode; - }; -}; // setfillmode - -inline void -lbp_printer::polygon( int hpos,int vpos,int np,int *p) -{ - //int points[np+2],i; - int *points,i; - - points = new int[np+2]; - points[0] = hpos; - points[1] = vpos; -/* fprintf(stderr,"Poligon (%d,%d) ", points[0],points[1]);*/ - for (i = 0; i < np; i++) points[i+2] = p[i]; -/* for (i = 0; i < np; i++) fprintf(stderr," %d ",p[i]); - fprintf(stderr,"\n"); */ - vdmpolygon((np /2) + 1,points); -}; - -void lbp_printer::draw(int code, int *p, int np, const environment *env) -{ - switch (code) { - case 't': - if (np == 0) line_thickness = 1; - else { // troff gratuitously adds an extra 0 - if (np != 1 && np != 2) { - error("0 or 1 argument required for thickness"); - break; - } // if (np != ... - if (p[0] == 0) line_thickness = 1; - if (p[0] < 0) // Default = 1 point - line_thickness = (int)(env->size*30/72); - line_thickness = (int)((abs(p[0])*env->size)/10); - if ((line_thickness > 16 ) && (!vdminited())) - { /* for greater thickness we must use VDM */ - vdmstart(); - /* vdmlinewidth(line_thickness); already done in - * vdmstart() */ - }; - if (vdminited()) vdmlinewidth(line_thickness); - // fprintf(stderr,"\nthickness: %d == %d, size %d\n", - // p[0],line_thickness,env->size ); - } // else - break; - - case 'l': // Line - if (np != 2) { - error("2 arguments required for line"); - break; - }; - if (!vdminited()) vdmstart(); - vdmline(env->hpos,env->vpos,p[0],p[1]); - /*fprintf(stderr,"\nline: %d,%d - %d,%d thickness %d == %d\n",\ - env->hpos - 64,env->vpos -64, env->hpos - 64 + p[0],\ - env->vpos -64 + p[1],env->size, line_thickness);*/ - break; - case 'R': // Rule - if (np != 2) { - error("2 arguments required for Rule"); - break; - } - if (vdminited()) { - setfillmode(fill_pattern); // Solid Rule - vdmrectangle(env->hpos,env->vpos,p[0],p[1]); - } - else { - lbpruleabs(env->hpos - 64,env->vpos -64 , p[0], p[1]); - cur_vpos = p[1]; - cur_hpos = p[0]; - }; - fprintf(stderr,"\nrule: thickness %d == %d\n", env->size, line_thickness); - break; - case 'P': // Filled Polygon - if (!vdminited()) vdmstart(); - setfillmode(fill_pattern); - polygon(env->hpos,env->vpos,np,p); - break; - case 'p': // Empty Polygon - if (!vdminited()) vdmstart(); - setfillmode(0); - polygon(env->hpos,env->vpos,np,p); - break; - case 'C': // Filled Circle - if (!vdminited()) vdmstart(); - // fprintf(stderr,"Circle (%d,%d) Fill %d\n",env->hpos,env->vpos,fill_pattern); - setfillmode(fill_pattern); - vdmcircle(env->hpos + (p[0]/2),env->vpos,p[0]/2); - break; - case 'c': // Empty Circle - if (!vdminited()) vdmstart(); - setfillmode(0); - vdmcircle(env->hpos + (p[0]/2),env->vpos,p[0]/2); - break; - case 'E': // Filled Ellipse - if (!vdminited()) vdmstart(); - setfillmode(fill_pattern); - vdmellipse(env->hpos + (p[0]/2),env->vpos,p[0]/2,p[1]/2,0); - break; - case 'e': // Empty Ellipse - if (!vdminited()) vdmstart(); - setfillmode(0); - vdmellipse(env->hpos + (p[0]/2),env->vpos,p[0]/2,p[1]/2,0); - break; - case 'a': // Arc - if (!vdminited()) vdmstart(); - setfillmode(0); - // VDM draws arcs clockwise and pic counterclockwise - // We must compensate for that, exchanging the starting and - // ending points - vdmvarc(env->hpos + p[0],env->vpos+p[1],\ - int(sqrt( double((p[0]*p[0])+(p[1]*p[1])))),\ - p[2],p[3],\ - (-p[0]),(-p[1]),1,2); - break; - case '~': // Spline - if (!vdminited()) vdmstart(); - setfillmode(0); - vdmspline(np/2,env->hpos,env->vpos,p); - break; - case 'f': - if (np != 1 && np != 2) { - error("1 argument required for fill"); - break; - }; - // fprintf(stderr,"Fill %d\n",p[0]); - if ((p[0] == 1) || (p[0] >= 1000)) { // Black - fill_pattern = 1; - break; - }; // if (p[0] == 1) - if (p[0] == 0) { // White - fill_pattern = 0; - break; - }; - if ((p[0] > 1) && (p[0] < 1000)) - { - if (p[0] >= 990) fill_pattern = -23; - else if (p[0] >= 700) fill_pattern = -28; - else if (p[0] >= 500) fill_pattern = -27; - else if (p[0] >= 400) fill_pattern = -26; - else if (p[0] >= 300) fill_pattern = -25; - else if (p[0] >= 200) fill_pattern = -22; - else if (p[0] >= 100) fill_pattern = -24; - else fill_pattern = -21; - }; // if (p[0] >= 0 && p[0] <= 1000) - break; - default: - error("unrecognised drawing command `%1'", char(code)); - break; - }; // switch (code) - return ; -}; - -font *lbp_printer::make_font(const char *nm) -{ - return lbp_font::load_lbp_font(nm); -} - - - -printer *make_printer() -{ - return new lbp_printer; -} - -static struct -{ - const char *name; - int code; -} papersizes[] = -{{ "A4", 14 }, -{ "letter", 30 }, -{ "legal", 32 }, -{ "executive", 40 }, -}; - - -static int set_papersize(const char *papersize) -{ - int i; - - // First test for a standard (i.e. supported directly by the printer) - // papersize - for (i = 0 ; i < sizeof(papersizes)/sizeof(papersizes[0]); i++) - { - if (strcasecmp(papersizes[i].name,papersize) == 0) - return papersizes[i].code; - }; - - // Now test for a custom papersize - if (strncasecmp("cust",papersize,4) == 0) - { - char *p , - *p1, - *papsize; - - p = papsize = strdup(&papersize[4]); - if (papsize == NULL) return -1; - p1 = strsep(&p,"x"); - if (p == NULL) - { // let's test for an uppercase x - p = papsize ; - p1 = strsep(&p,"X"); - if (p == NULL) { free(papsize); return -1;}; - }; // if (p1 == NULL) - paperlength = atoi(p1); - if (paperlength == 0) { free(papsize); return -1;}; - paperwidth = atoi(p); - if (paperwidth == 0) { free(papsize); return -1;}; - free(papsize); - return 82; - }; // if (strcnasecmp("cust",papersize,4) == 0) - - return -1; -}; - -static int handle_papersize_command(const char *arg) -{ - int n = set_papersize(arg); - - if (n < 0) - { // If is not a standard nor custom paper size - // let's see if it's a file (i.e /etc/papersize ) - FILE *f = fopen(arg,"r"); - if (f != NULL) - { // the file exists and is readable - char psize[255],*p; - fgets(psize,254,f); - fclose(f); - // set_papersize doesn't like the trailing \n - p = psize; while (*p) p++; - if (*(--p) == '\n') *p = 0x00; - - n = set_papersize(psize); - }; // if (f != NULL) - }; // if (n < 0) - - return n; -}; // handle_papersize_command - - -static void handle_unknown_desc_command(const char *command, const char *arg, - const char *filename, int lineno) -{ - // papersize command - if (strcasecmp(command, "papersize") == 0) { - // We give priority to command line options - if (papersize > 0) return; - if (arg == 0) - error_with_file_and_line(filename, lineno, - "`papersize' command requires an argument"); - else - { - int n = handle_papersize_command(arg); - if (n < 0) - error_with_file_and_line(filename, lineno, - "unknown paper size `%1'", arg); - else - papersize = n; - - }; // if (arg == 0) ... else ... - }; // if (strcasecmp(command, "papersize") - - // orientation command - if (strcasecmp(command, "orientation") == 0) { - // We give priority to command line options - if (orientation > 0) return; - if (arg == 0) - error_with_file_and_line(filename, lineno, - "`papersize' command requires an argument"); - else { - if (strcasecmp(arg,"portrait") == 0) orientation = 0; - else { if (strcasecmp(arg,"landscape") == 0) orientation = 1; - else error_with_file_and_line(filename, lineno, - "`orientation' command requires an argument"); - }; - }; // if (arg == 0) ... else ... - }; // if (strcasecmp(command, "orientation") == 0) -}; - -static struct option long_options[] = { - {"orientation",1,NULL,'o'}, - {"version",0,NULL,'v'}, - {"copies",1,NULL,'c'}, - {"landscape",0,NULL,'l'}, - {"papersize",1,NULL,'p'}, - {"fontdir",1,NULL,'F'}, - {"help",0,NULL,'h'}, - {0, 0, 0, 0} - }; - -static void usage() -{ - fprintf(stderr, - "usage: %s [-lvh] [-c n] [-p paper_size] [-F dir] [-o or] "\ - " [files ...]\n"\ - " -o --orientation=[portrait|landscape]\n"\ - " -v --version\n"\ - " -c --copies=numcopies\n"\ - " -l --landscape\n"\ - " -p --papersize=paper_size\n"\ - " -F --fontdir=dir\n"\ - " -h --help\n", - program_name); - exit(1); -}; // usage - -int main(int argc, char **argv) -{ - if (program_name == NULL) program_name = strdup(argv[0]); - - font::set_unknown_desc_command_handler(handle_unknown_desc_command); - // command line parsing - int c = 0; - int option_index = 0; - - while (c >= 0 ) - { - c = getopt_long (argc, argv, "F:p:lvo:c:h",\ - long_options, &option_index); - switch (c) { - case 'F' : font::command_line_font_dir(optarg); - break; - case 'p' : { - int n = handle_papersize_command(optarg); - if (n < 0) - error("unknown paper size `%1'", optarg); - else - papersize = n; - break; - }; - case 'l' : orientation = 1; - break; - case 'v' : { - extern const char *version_string; - fprintf(stderr, "grolbp version %s\n",\ - version_string); - fflush(stderr); - break; - }; - case 'o' : { - if (strcasecmp(optarg,"portrait") == 0) - orientation = 0; - else { - if (strcasecmp(optarg,"landscape") == 0) - orientation = 1; - else - error("unknown orientation '%1'", optarg); - }; - break; - }; - case 'c' : { - char *ptr; - long n = strtol(optarg, &ptr, 10); - if ((n <= 0) && (ptr == optarg)) - error("argument for -c must be a positive integer"); - else if (n <= 0 || n > 32767) - error("out of range argument for -c"); - else - ncopies = unsigned(n); - break; - } - case 'h' : usage(); - break; - - - }; // switch (c) - }; // while (c > 0 ) - - if (optind >= argc) - do_file("-"); - - while (optind < argc) { - do_file(argv[optind++]); - }; - - lbpputs("\033c\033<"); - return 0; -}; |