version 1.1, 2005/02/28 19:08:11
|
version 1.2, 2006/03/24 23:08:33
|
Line 1
|
Line 1
|
/**************************************************************************** |
/**************************************************************************** |
* |
* |
* Copyright(c) 2002-2005, John Forkosh Associates, Inc. All rights reserved. |
* Copyright(c) 2002-2006, John Forkosh Associates, Inc. All rights reserved. |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* This file is part of mimeTeX, which is free software. You may redistribute |
* This file is part of mimeTeX, which is free software. You may redistribute |
* and/or modify it under the terms of the GNU General Public License, |
* and/or modify it under the terms of the GNU General Public License, |
Line 58
|
Line 58
|
* rastcat(sp1,sp2,isfree) concatanate sp1||sp2 |
* rastcat(sp1,sp2,isfree) concatanate sp1||sp2 |
* rastack(sp1,sp2,base,space,iscenter,isfree)stack sp2 atop sp1 |
* rastack(sp1,sp2,base,space,iscenter,isfree)stack sp2 atop sp1 |
* rastile(tiles,ntiles) create composite raster from tiles |
* rastile(tiles,ntiles) create composite raster from tiles |
* rastsquash(sp1,sp2,xmin,ymin) calc #squash pixels sp1||sp2 |
* rastsmash(sp1,sp2,xmin,ymin) calc #smash pixels sp1||sp2 |
* --- raster "drawing" functions --- |
* --- raster "drawing" functions --- |
* accent_subraster(accent,width,height) draw \hat\vec\etc |
* accent_subraster(accent,width,height) draw \hat\vec\etc |
* arrow_subraster(width,height,drctn,isBig) left/right arrow |
* arrow_subraster(width,height,drctn,isBig) left/right arrow |
Line 74
|
Line 74
|
* type_raster(rp,fp) emit ascii dump of rp on file ptr fp |
* type_raster(rp,fp) emit ascii dump of rp on file ptr fp |
* type_bytemap(bp,grayscale,width,height,fp) dump bytemap on fp |
* type_bytemap(bp,grayscale,width,height,fp) dump bytemap on fp |
* xbitmap_raster(rp,fp) emit mime xbitmap of rp on fp |
* xbitmap_raster(rp,fp) emit mime xbitmap of rp on fp |
|
* type_pbmpgm(rp,ptype,file) pbm or pgm image of rp to file |
* cstruct_chardef(cp,fp,col1) emit C struct of cp on fp |
* cstruct_chardef(cp,fp,col1) emit C struct of cp on fp |
* cstruct_raster(rp,fp,col1) emit C struct of rp on fp |
* cstruct_raster(rp,fp,col1) emit C struct of rp on fp |
* hex_bitmap(rp,fp,col1,isstr)emit hex dump of rp->pixmap on fp |
* hex_bitmap(rp,fp,col1,isstr)emit hex dump of rp->pixmap on fp |
* --- ancillary output functions --- |
* --- ancillary output functions --- |
* emit_string(fp,col1,string,comment) emit string and C comment |
* emit_string(fp,col1,string,comment) emit string and C comment |
|
* gftobitmap(rp) convert .gf-like pixmap to bitmap image |
* ====================== Font Functions ======================= |
* ====================== Font Functions ======================= |
* --- font lookup functions --- |
* --- font lookup functions --- |
* get_symdef(symbol) returns mathchardef for symbol |
* get_symdef(symbol) returns mathchardef for symbol |
* get_chardef(symdef,size) returns chardef for symdef,size |
* get_chardef(symdef,size) returns chardef for symdef,size |
* get_charsubraster(symdef,size) wrap subraster around chardef |
* get_charsubraster(symdef,size) wrap subraster around chardef |
|
* get_symsubraster(symbol,size) returns subraster for symbol |
* --- ancillary font functions --- |
* --- ancillary font functions --- |
* get_baseline(gfdata) determine baseline (in our coords) |
* get_baseline(gfdata) determine baseline (in our coords) |
* get_delim(symbol,height,family) delim just larger than height |
* get_delim(symbol,height,family) delim just larger than height |
Line 91
|
Line 94
|
* ================= Tokenize/Parse Functions ================== |
* ================= Tokenize/Parse Functions ================== |
* texchar(expression,chartoken) retruns next char or \sequence |
* texchar(expression,chartoken) retruns next char or \sequence |
* texsubexpr(expr,subexpr,maxsubsz,left,right,isescape,isdelim) |
* texsubexpr(expr,subexpr,maxsubsz,left,right,isescape,isdelim) |
|
* texleft(expr,subexpr,maxsubsz,ldelim,rdelim) \left...\right |
* texscripts(expression,subscript,superscript,which)get scripts |
* texscripts(expression,subscript,superscript,which)get scripts |
* --- ancillary parse functions --- |
* --- ancillary parse functions --- |
* isbrace(expression,braces,isescape) check for leading brace |
* isbrace(expression,braces,isescape) check for leading brace |
Line 110
|
Line 114
|
* rastdispmath(expression,size,sp) scripts for displaymath |
* rastdispmath(expression,size,sp) scripts for displaymath |
* --- table-driven handlers that rasterize... --- |
* --- table-driven handlers that rasterize... --- |
* rastleft(expression,size,basesp,ildelim,arg2,arg3)\left\right |
* rastleft(expression,size,basesp,ildelim,arg2,arg3)\left\right |
|
* rastright(expression,size,basesp,ildelim,arg2,arg3) ...\right |
|
* rastmiddle(expression,size,basesp,arg1,arg2,arg3) \middle |
* rastflags(expression,size,basesp,flag,value,arg3) set flag |
* rastflags(expression,size,basesp,flag,value,arg3) set flag |
* rastspace(expression,size,basesp,width,isfill,isheight)\,\:\; |
* rastspace(expression,size,basesp,width,isfill,isheight)\,\:\; |
* rastnewline(expression,size,basesp,arg1,arg2,arg3) \\ |
* rastnewline(expression,size,basesp,arg1,arg2,arg3) \\ |
Line 133
|
Line 139
|
* rastfbox(expression,size,basesp,arg1,arg2,arg3) \fbox |
* rastfbox(expression,size,basesp,arg1,arg2,arg3) \fbox |
* rastinput(expression,size,basesp,arg1,arg2,arg3) \input |
* rastinput(expression,size,basesp,arg1,arg2,arg3) \input |
* rastcounter(expression,size,basesp,arg1,arg2,arg3) \counter |
* rastcounter(expression,size,basesp,arg1,arg2,arg3) \counter |
|
* rasttoday(expression,size,basesp,arg1,arg2,arg3) \today |
|
* rastcalendar(expression,size,basesp,arg1,arg2,arg3) \calendar |
* rastnoop(expression,size,basesp,arg1,arg2,arg3) flush \escape |
* rastnoop(expression,size,basesp,arg1,arg2,arg3) flush \escape |
* --- helper functions for handlers --- |
* --- helper functions for handlers --- |
* rastopenfile(filename,mode) opens filename[.tex] in mode |
* rastopenfile(filename,mode) opens filename[.tex] in mode |
* rastreadfile(filename,tag,value) read between <tag>...</tag> |
* rasteditfilename(filename) edit filename (for security) |
|
* rastreadfile(filename,islock,tag,value) read <tag>...</tag> |
* rastwritefile(filename,tag,value,isstrict)write<tag>...</tag> |
* rastwritefile(filename,tag,value,isstrict)write<tag>...</tag> |
* timestamp( ) formats timestamp string (used by rastcounter) |
* calendar(year,month,day) formats one-month calendar string |
* dtoa(d,npts) double to comma-separated ascii |
* timestamp(tzdelta,ifmt) formats timestamp string |
|
* tzadjust(tzdelta,year,month,day,hour) adjust date/time |
|
* daynumber(year,month,day) #days since Monday, Jan 1, 1973 |
|
* dbltoa(d,npts) double to comma-separated ascii |
* === Anti-alias completed raster (lowpass) or symbols (ss) === |
* === Anti-alias completed raster (lowpass) or symbols (ss) === |
* aalowpass(rp,bytemap,grayscale) lowpass grayscale bytemap |
* aalowpass(rp,bytemap,grayscale) lowpass grayscale bytemap |
* aapnm(rp,bytemap,grayscale) lowpass based on pnmalias.c |
* aapnm(rp,bytemap,grayscale) lowpass based on pnmalias.c |
Line 149
|
Line 161
|
* aawtpixel(image,ipixel,weights,rotate) weight image at ipixel |
* aawtpixel(image,ipixel,weights,rotate) weight image at ipixel |
* PART1 ========================== Driver =========================== |
* PART1 ========================== Driver =========================== |
* main(argc,argv) parses math expression and emits mime xbitmap |
* main(argc,argv) parses math expression and emits mime xbitmap |
|
* CreateGifFromEq(expression,gifFileName) entry pt for win dll |
* isstrstr(string,snippets,iscase) are any snippets in string? |
* isstrstr(string,snippets,iscase) are any snippets in string? |
* ismonth(month) is month current month ("jan"-"dec")? |
* ismonth(month) is month current month ("jan"-"dec")? |
* unescape_url(url,isescape), x2c(what) xlate %xx url-encoded |
* unescape_url(url,isescape), x2c(what) xlate %xx url-encoded |
* logger(fp,msglevel,logvars) logs environment variables |
* logger(fp,msglevel,logvars) logs environment variables |
* emitcache(cachefile) read cachefile and emit bytes to stdout |
* emitcache(cachefile,maxage,isbuffer) emit cachefile to stdout |
|
* readcachefile(cachefile,buffer) read cachefile into buffer |
* md5str(instr) md5 hash library functions |
* md5str(instr) md5 hash library functions |
* GetPixel(x,y) callback function for gifsave library |
* GetPixel(x,y) callback function for gifsave library |
* |
* |
Line 311 header files and macros
|
Line 325 header files and macros
|
|
|
/* --- windows-specific header info --- */ |
/* --- windows-specific header info --- */ |
#ifndef WINDOWS /* -DWINDOWS not supplied by user */ |
#ifndef WINDOWS /* -DWINDOWS not supplied by user */ |
#if defined(_WIN32) || defined(WIN32) \ |
#if defined(_WINDOWS) || defined(_WIN32) || defined(WIN32) \ |
|| defined(DJGPP) /* try to recognize windows */ |
|| defined(DJGPP) /* try to recognize windows compilers */ \ |
|
|| defined(_USRDLL) /* must be WINDOWS if compiling for DLL */ |
#define WINDOWS /* signal windows */ |
#define WINDOWS /* signal windows */ |
#endif |
#endif |
#endif |
#endif |
Line 328 header files and macros
|
Line 343 header files and macros
|
#if defined(_O_BINARY) || defined(O_BINARY) /* setmode() now available */ |
#if defined(_O_BINARY) || defined(O_BINARY) /* setmode() now available */ |
#define HAVE_SETMODE /* so we'll use setmode() */ |
#define HAVE_SETMODE /* so we'll use setmode() */ |
#endif |
#endif |
|
#if defined(_MSC_VER) && defined(_DEBUG) /* MS VC++ in debug mode */ |
|
/* to show source file and line numbers where memory leaks occur... */ |
|
#define _CRTDBG_MAP_ALLOC /* ...include this debug macro */ |
|
#include <crtdbg.h> /* and this debug library */ |
|
#endif |
#define ISWINDOWS 1 |
#define ISWINDOWS 1 |
#else |
#else |
#define ISWINDOWS 0 |
#define ISWINDOWS 0 |
Line 396 header files and macros
|
Line 416 header files and macros
|
#define TEXFONTS /* to include texfonts.h */ |
#define TEXFONTS /* to include texfonts.h */ |
#endif |
#endif |
#include "mimetex.h" |
#include "mimetex.h" |
|
/* --- info needed when gif image returned in memory buffer --- */ |
|
#ifdef GIF /* compiling along with gifsave.c */ |
|
extern int gifSize; |
|
extern int maxgifSize; |
|
#else /* or just set dummy values */ |
|
static int gifSize=0, maxgifSize=0; |
|
#endif |
|
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
adjustable default values |
adjustable default values |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- anti-aliasing parameters --- */ |
/* --- anti-aliasing parameters --- */ |
#ifndef CENTERWT |
#ifndef CENTERWT |
|
/*#define CENTERWT 32*/ /* anti-aliasing centerwt default */ |
/*#define CENTERWT 10*/ /* anti-aliasing centerwt default */ |
/*#define CENTERWT 10*/ /* anti-aliasing centerwt default */ |
/*#define CENTERWT 6*/ /* anti-aliasing centerwt default */ |
#define CENTERWT 8 /* anti-aliasing centerwt default */ |
#define CENTERWT 32 /* anti-aliasing centerwt default */ |
|
#endif |
#endif |
#ifndef ADJACENTWT |
#ifndef ADJACENTWT |
/*#define ADJACENTWT 3*/ /* anti-aliasing adjacentwt default*/ |
/*#define ADJACENTWT 3*/ /* anti-aliasing adjacentwt default*/ |
/*#define ADJACENTWT 2*/ /* anti-aliasing adjacentwt default*/ |
#define ADJACENTWT 2 /* anti-aliasing adjacentwt default*/ |
#define ADJACENTWT 3 /* anti-aliasing adjacentwt default*/ |
|
#endif |
#endif |
#ifndef CORNERWT |
#ifndef CORNERWT |
#define CORNERWT 1 /* anti-aliasing cornerwt default*/ |
#define CORNERWT 1 /* anti-aliasing cornerwt default*/ |
Line 473 other variables
|
Line 499 other variables
|
#ifndef FGBLUE |
#ifndef FGBLUE |
#define FGBLUE (ISBLACKONWHITE?0:255) |
#define FGBLUE (ISBLACKONWHITE?0:255) |
#endif |
#endif |
/* --- "squash" margin (0 means no squashing) --- */ |
/* --- "smash" margin (0 means no smashing) --- */ |
#ifndef SQUASHMARGIN |
#ifndef SMASHMARGIN |
#ifdef NOSQUASH |
#ifdef NOSMASH |
#define SQUASHMARGIN 0 |
#define SMASHMARGIN 0 |
#else |
#else |
#define SQUASHMARGIN 3 |
#define SMASHMARGIN 3 |
#endif |
#endif |
#endif |
#endif |
/* --- textwidth --- */ |
/* --- textwidth --- */ |
Line 486 other variables
|
Line 512 other variables
|
#define TEXTWIDTH (400) |
#define TEXTWIDTH (400) |
#endif |
#endif |
/* --- font "combinations" --- */ |
/* --- font "combinations" --- */ |
#define CMSYEX (107) /* select CMSY10 _or_ CMEX10 */ |
#define CMSYEX (109) /*select CMSY10, CMEX10 or STMARY10*/ |
/* --- prefix prepended to all expressions --- */ |
/* --- prefix prepended to all expressions --- */ |
#ifndef PREFIX |
#ifndef PREFIX |
#define PREFIX "\000" /* default no prepended prefix */ |
#define PREFIX "\000" /* default no prepended prefix */ |
Line 522 other variables
|
Line 548 other variables
|
#ifndef PATHPREFIX |
#ifndef PATHPREFIX |
#define PATHPREFIX "\000" /* paths relative mimetex.cgi */ |
#define PATHPREFIX "\000" /* paths relative mimetex.cgi */ |
#endif |
#endif |
|
/* --- time zone delta t (in hours) --- */ |
|
#ifndef TZDELTA |
|
#define TZDELTA 0 |
|
#endif |
|
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
debugging and logging / error reporting |
debugging and logging / error reporting |
Line 555 control flags and values
|
Line 585 control flags and values
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
GLOBAL(int,recurlevel,0); /* inc/decremented in rasterize() */ |
GLOBAL(int,recurlevel,0); /* inc/decremented in rasterize() */ |
GLOBAL(int,scriptlevel,0); /* inc/decremented in rastlimits() */ |
GLOBAL(int,scriptlevel,0); /* inc/decremented in rastlimits() */ |
GLOBAL(int,istext,0); /* textmode if true,italics=2,bb=3 */ |
GLOBAL(int,isstring,0); /*pixmap is ascii string, not raster*/ |
GLOBAL(int,isstring ,0); /*pixmap is ascii string, not raster*/ |
/*SHARED(int,imageformat,1);*/ /* image is 1=bitmap, 2=.gf-like */ |
GLOBAL(int,isdisplaystyle,1); /* displaystyle mode (forced if 2) */ |
GLOBAL(int,isdisplaystyle,1); /* displaystyle mode (forced if 2) */ |
GLOBAL(int,ispreambledollars,0); /* displaystyle mode set by $$...$$ */ |
GLOBAL(int,ispreambledollars,0); /* displaystyle mode set by $$...$$ */ |
|
GLOBAL(int,fontnum,0); /* cal=1,scr=2,rm=3,it=4,bb=5,bf=6 */ |
GLOBAL(int,fontsize,NORMALSIZE); /* current size */ |
GLOBAL(int,fontsize,NORMALSIZE); /* current size */ |
GLOBAL(int,displaysize,DISPLAYSIZE); /* use \displaystyle when fontsize>=*/ |
GLOBAL(int,displaysize,DISPLAYSIZE); /* use \displaystyle when fontsize>=*/ |
GLOBAL(int,shrinkfactor,3); /* shrinkfactors[fontsize] */ |
GLOBAL(int,shrinkfactor,3); /* shrinkfactors[fontsize] */ |
GLOBAL(double,unitlength,1.0); /* #pixels per unit (may be <1.0) */ |
GLOBAL(double,unitlength,1.0); /* #pixels per unit (may be <1.0) */ |
/*GLOBAL(int,textwidth,TEXTWIDTH);*/ /* #pixels across line */ |
/*GLOBAL(int,textwidth,TEXTWIDTH);*/ /* #pixels across line */ |
GLOBAL(int,squashmargin,SQUASHMARGIN); /* minimum "squash" margin */ |
GLOBAL(int,iscatspace,1); /* true to add space in rastcat() */ |
GLOBAL(int,issquashdelta,1); /* true if squashmargin is a delta */ |
GLOBAL(int,smashmargin,SMASHMARGIN); /* minimum "smash" margin */ |
|
GLOBAL(int,issmashdelta,1); /* true if smashmargin is a delta */ |
|
GLOBAL(int,blanksignal,(-991234)); /*rastsmash signal right-hand blank*/ |
GLOBAL(int,istransparent,1); /*true to set background transparent*/ |
GLOBAL(int,istransparent,1); /*true to set background transparent*/ |
GLOBAL(int,fgred,FGRED); |
GLOBAL(int,fgred,FGRED); |
GLOBAL(int,fggreen,FGGREEN); |
GLOBAL(int,fggreen,FGGREEN); |
Line 655 if ( rp == (raster *)NULL ) /* malloc f
|
Line 688 if ( rp == (raster *)NULL ) /* malloc f
|
goto end_of_job; /* return error to caller */ |
goto end_of_job; /* return error to caller */ |
rp->width = width; /* store width in raster struct */ |
rp->width = width; /* store width in raster struct */ |
rp->height = height; /* and store height */ |
rp->height = height; /* and store height */ |
|
rp->format = 1; /* initialize as bitmap format */ |
rp->pixsz = pixsz; /* store #bits per pixel */ |
rp->pixsz = pixsz; /* store #bits per pixel */ |
rp->pixmap = (pixbyte *)NULL; /* init bitmap as null ptr */ |
rp->pixmap = (pixbyte *)NULL; /* init bitmap as null ptr */ |
/* --- allocate and initialize bitmap array --- */ |
/* --- allocate and initialize bitmap array --- */ |
Line 775 cp->charnum = cp->location = 0; /* init
|
Line 809 cp->charnum = cp->location = 0; /* init
|
cp->toprow = cp->topleftcol = 0; /* init upper-left corner */ |
cp->toprow = cp->topleftcol = 0; /* init upper-left corner */ |
cp->botrow = cp->botleftcol = 0; /* init lower-left corner */ |
cp->botrow = cp->botleftcol = 0; /* init lower-left corner */ |
cp->image.width = cp->image.height = 0; /* init raster dimensions */ |
cp->image.width = cp->image.height = 0; /* init raster dimensions */ |
|
cp->image.format = 0; /* init raster format */ |
cp->image.pixsz = 0; /* and #bits per pixel */ |
cp->image.pixsz = 0; /* and #bits per pixel */ |
cp->image.pixmap = NULL; /* init raster pixmap as null */ |
cp->image.pixmap = NULL; /* init raster pixmap as null */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 1190 int base1 = sp1->baseline, /*baseline
|
Line 1225 int base1 = sp1->baseline, /*baseline
|
pixsz2 = (sp2->image)->pixsz, /* pixsz for right-hand subraster */ |
pixsz2 = (sp2->image)->pixsz, /* pixsz for right-hand subraster */ |
type2 = sp2->type; /* image type for right-hand */ |
type2 = sp2->type; /* image type for right-hand */ |
int height=0, width=0, pixsz=0, base=0; /*concatted sp1||sp2 composite*/ |
int height=0, width=0, pixsz=0, base=0; /*concatted sp1||sp2 composite*/ |
int issquash = (squashmargin!=0?1:0), /* true to "squash" sp1||sp2 */ |
int issmash = (smashmargin!=0?1:0), /* true to "squash" sp1||sp2 */ |
isopaque = (issquash?0:1), /* not oppaque if squashing */ |
isopaque = (issmash?0:1), /* not oppaque if smashing */ |
rastsquash(), isblank=0, nsquash=0, /* #cols to squash */ |
rastsmash(), isblank=0, nsmash=0, /* #cols to smash */ |
oldsquashmargin = squashmargin; /* save original squashmargin */ |
oldsmashmargin = smashmargin; /* save original smashmargin */ |
int blanksignal = (-991234); /*rastsquash signal right-hand blank*/ |
|
mathchardef *symdef1 = sp1->symdef, /*mathchardef of last left-hand char*/ |
mathchardef *symdef1 = sp1->symdef, /*mathchardef of last left-hand char*/ |
*symdef2 = sp2->symdef; /* mathchardef of right-hand char */ |
*symdef2 = sp2->symdef; /* mathchardef of right-hand char */ |
int class1 = (symdef1==NULL?ORDINARY:symdef1->class), /* symdef->class */ |
int class1 = (symdef1==NULL?ORDINARY:symdef1->class), /* symdef->class */ |
Line 1211 Initialization
|
Line 1245 Initialization
|
if ( !isstring ) |
if ( !isstring ) |
space = max2(2,(symspace[class1][class2] + fontsize-3)); /* space */ |
space = max2(2,(symspace[class1][class2] + fontsize-3)); /* space */ |
else space = 1; /* space for ascii string */ |
else space = 1; /* space for ascii string */ |
/* --- determine squash --- */ |
if ( !iscatspace ) space=0; /* spacing explicitly turned off */ |
if ( !isstring ) /* don't squash strings */ |
/* --- determine smash --- */ |
if ( issquash ) { /* raster squash wanted */ |
if ( !isstring ) /* don't smash strings */ |
int maxsquash = rastsquash(sp1,sp2), /* calculate max squash space */ |
if ( issmash ) { /* raster smash wanted */ |
margin = squashmargin; /* init margin without delta */ |
int maxsmash = rastsmash(sp1,sp2), /* calculate max smash space */ |
|
margin = smashmargin; /* init margin without delta */ |
if ( (1 && smash1 && smash2) /* concatanating two chars */ |
if ( (1 && smash1 && smash2) /* concatanating two chars */ |
|| (1 && type1!=IMAGERASTER && type2!=IMAGERASTER) ) |
|| (1 && type1!=IMAGERASTER && type2!=IMAGERASTER) ) |
/*maxsquash = 0;*/ /* turn off squash */ |
/*maxsmash = 0;*/ /* turn off smash */ |
margin = max2(space-1,0); /* force small squashmargin */ |
margin = max2(space-1,0); /* force small smashmargin */ |
else /* adjust for delta if images */ |
else /* adjust for delta if images */ |
if ( issquashdelta ) /* squashmargin is a delta value */ |
if ( issmashdelta ) /* smashmargin is a delta value */ |
margin += fontsize; /* add displaystyle base to margin */ |
margin += fontsize; /* add displaystyle base to margin */ |
if ( maxsquash == blanksignal ) /* sp2 is intentional blank */ |
if ( maxsmash == blanksignal ) /* sp2 is intentional blank */ |
isblank = 1; /* set blank flag signal */ |
isblank = 1; /* set blank flag signal */ |
else /* see how much extra space we have*/ |
else /* see how much extra space we have*/ |
if ( maxsquash > margin ) /* enough space for adjustment */ |
if ( maxsmash > margin ) /* enough space for adjustment */ |
nsquash = maxsquash-margin; /* make adjustment */ |
nsmash = maxsmash-margin; /* make adjustment */ |
if ( msgfp!=NULL && msglevel>=99 ) /* display squash results */ |
if ( msgfp!=NULL && msglevel>=99 ) /* display smash results */ |
{ fprintf(msgfp,"rastcat> maxsquash=%d, margin=%d, nsquash=%d\n", |
{ fprintf(msgfp,"rastcat> maxsmash=%d, margin=%d, nsmash=%d\n", |
maxsquash,margin,nsquash); |
maxsmash,margin,nsmash); |
fprintf(msgfp,"rastcat> type1=%d,2=%d, class1=%d,2=%d\n", type1,type2, |
fprintf(msgfp,"rastcat> type1=%d,2=%d, class1=%d,2=%d\n", type1,type2, |
(symdef1==NULL?-999:class1),(symdef2==NULL?-999:class2)); |
(symdef1==NULL?-999:class1),(symdef2==NULL?-999:class2)); |
fflush(msgfp); } |
fflush(msgfp); } |
} /* --- end-of-if(issquash) --- */ |
} /* --- end-of-if(issmash) --- */ |
/* --- determine height, width and baseline of composite raster --- */ |
/* --- determine height, width and baseline of composite raster --- */ |
if ( !isstring ) |
if ( !isstring ) |
{ height = max2(base1+1,base2+1) /* max height above baseline */ |
{ height = max2(base1+1,base2+1) /* max height above baseline */ |
+ max2(height1-base1-1,height2-base2-1); /*+ max descending below*/ |
+ max2(height1-base1-1,height2-base2-1); /*+ max descending below*/ |
width = width1+width2 + space-nsquash; /*add widths and space-squash*/ |
width = width1+width2 + space-nsmash; /*add widths and space-smash*/ |
width = max3(width,width1,width2); } /* don't "over-squash" composite */ |
width = max3(width,width1,width2); } /* don't "over-smash" composite */ |
else /* ascii string */ |
else /* ascii string */ |
{ height = 1; /* default */ |
{ height = 1; /* default */ |
width = width1 + width2 + space - 1; } /* no need for two nulls */ |
width = width1 + width2 + space - 1; } /* no need for two nulls */ |
Line 1254 if ( msgfp!=NULL && msglevel>=9999 ) /*
|
Line 1289 if ( msgfp!=NULL && msglevel>=9999 ) /*
|
height2,width2,pixsz2,base2); |
height2,width2,pixsz2,base2); |
type_raster(sp2->image,msgfp); /* display right-hand raster */ |
type_raster(sp2->image,msgfp); /* display right-hand raster */ |
fprintf(msgfp, |
fprintf(msgfp, |
"rastcat> Composite ht,width,squash,pixsz,base = %d,%d,%d,%d,%d\n", |
"rastcat> Composite ht,width,smash,pixsz,base = %d,%d,%d,%d,%d\n", |
height,width,nsquash,pixsz,base); |
height,width,nsmash,pixsz,base); |
fflush(msgfp); } /* flush msgfp buffer */ |
fflush(msgfp); } /* flush msgfp buffer */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
allocate concatted composite subraster |
allocate concatted composite subraster |
Line 1273 if ( (sp=new_subraster(width,height,pixs
|
Line 1308 if ( (sp=new_subraster(width,height,pixs
|
/* --- initialize subraster parameters --- */ |
/* --- initialize subraster parameters --- */ |
/* sp->type = (!isstring?STRINGRASTER:ASCIISTRING); */ /*concatted string*/ |
/* sp->type = (!isstring?STRINGRASTER:ASCIISTRING); */ /*concatted string*/ |
if ( !isstring ) |
if ( !isstring ) |
sp->type = type2;/*(type1==type2?type2:IMAGERASTER);*/ /*string or image*/ |
sp->type = /*type2;*//*(type1==type2?type2:IMAGERASTER);*/ |
|
(type2!=CHARASTER? type2 : (type1!=CHARASTER?type1:STRINGRASTER)); |
else |
else |
sp->type = ASCIISTRING; /* concatted ascii string */ |
sp->type = ASCIISTRING; /* concatted ascii string */ |
sp->symdef = symdef2; /* rightmost char is sp2 */ |
sp->symdef = symdef2; /* rightmost char is sp2 */ |
Line 1291 if ( msgfp!=NULL && msglevel>=9999 )
|
Line 1327 if ( msgfp!=NULL && msglevel>=9999 )
|
fflush(msgfp); } /* flush msgfp buffer */ |
fflush(msgfp); } /* flush msgfp buffer */ |
if ( !isstring ) |
if ( !isstring ) |
rastput (rp, sp1->image, base-base1, /* overlay left-hand */ |
rastput (rp, sp1->image, base-base1, /* overlay left-hand */ |
max2(0,nsquash-width1), 1); /* plus any residual squash space */ |
max2(0,nsmash-width1), 1); /* plus any residual smash space */ |
else |
else |
memcpy(rp->pixmap,(sp1->image)->pixmap,width1-1); /*init left string*/ |
memcpy(rp->pixmap,(sp1->image)->pixmap,width1-1); /*init left string*/ |
if ( msgfp!=NULL && msglevel>=9999 ) |
if ( msgfp!=NULL && msglevel>=9999 ) |
Line 1299 if ( msgfp!=NULL && msglevel>=9999 )
|
Line 1335 if ( msgfp!=NULL && msglevel>=9999 )
|
fflush(msgfp); } /* flush msgfp buffer */ |
fflush(msgfp); } /* flush msgfp buffer */ |
if ( !isstring ) |
if ( !isstring ) |
rastput (rp, sp2->image, base-base2, /* overlay right-hand */ |
rastput (rp, sp2->image, base-base2, /* overlay right-hand */ |
max2(0,width1+space-nsquash), isopaque); /* minus any squashed space */ |
max2(0,width1+space-nsmash), isopaque); /* minus any smashed space */ |
else |
else |
{ strcpy((char *)(rp->pixmap)+width1-1+space,(char *)((sp2->image)->pixmap)); |
{ strcpy((char *)(rp->pixmap)+width1-1+space,(char *)((sp2->image)->pixmap)); |
((char *)(rp->pixmap))[width1+width2+space-2] = '\000'; } /*null-term*/ |
((char *)(rp->pixmap))[width1+width2+space-2] = '\000'; } /*null-term*/ |
Line 1316 if ( isfree > 0 ) /* caller wants inpu
|
Line 1352 if ( isfree > 0 ) /* caller wants inpu
|
Back to caller with pointer to concatted subraster or with null for error |
Back to caller with pointer to concatted subraster or with null for error |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
end_of_job: |
end_of_job: |
squashmargin = oldsquashmargin; /* reset original squashmargin */ |
smashmargin = oldsmashmargin; /* reset original smashmargin */ |
return ( sp ); /* back with subraster or null ptr */ |
return ( sp ); /* back with subraster or null ptr */ |
} /* --- end-of-function rastcat() --- */ |
} /* --- end-of-function rastcat() --- */ |
|
|
Line 1487 end_of_job:
|
Line 1523 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: rastsquash ( sp1, sp2 ) |
* Function: rastsmash ( sp1, sp2 ) |
* Purpose: When concatanating sp1||sp2, calculate #pixels |
* Purpose: When concatanating sp1||sp2, calculate #pixels |
* we can "squash sp2 left" |
* we can "smash sp2 left" |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: sp1 (I) subraster * to left-hand raster |
* Arguments: sp1 (I) subraster * to left-hand raster |
* sp2 (I) subraster * to right-hand raster |
* sp2 (I) subraster * to right-hand raster |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Returns: ( int ) max #pixels we can squash sp1||sp2, |
* Returns: ( int ) max #pixels we can smash sp1||sp2, |
* or "blanksignal" if sp2 intentionally blank, |
* or "blanksignal" if sp2 intentionally blank, |
* or 0 for any error. |
* or 0 for any error. |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Notes: o |
* Notes: o |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
int rastsquash ( subraster *sp1, subraster *sp2 ) |
int rastsmash ( subraster *sp1, subraster *sp2 ) |
{ |
{ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
int nsquash = 0; /* #pixels to squash sp1||sp2 */ |
int nsmash = 0; /* #pixels to smash sp1||sp2 */ |
int base1 = sp1->baseline, /*baseline for left-hand subraster*/ |
int base1 = sp1->baseline, /*baseline for left-hand subraster*/ |
height1 = (sp1->image)->height, /* height for left-hand subraster */ |
height1 = (sp1->image)->height, /* height for left-hand subraster */ |
width1 = (sp1->image)->width, /* width for left-hand subraster */ |
width1 = (sp1->image)->width, /* width for left-hand subraster */ |
Line 1520 int base = max2(base1,base2), /* max asc
|
Line 1556 int base = max2(base1,base2), /* max asc
|
int irow1=0,irow2=0, icol=0; /* row,col indexes */ |
int irow1=0,irow2=0, icol=0; /* row,col indexes */ |
int firstcol1[1025], nfirst1=0, /* 1st sp1 col containing set pixel*/ |
int firstcol1[1025], nfirst1=0, /* 1st sp1 col containing set pixel*/ |
firstcol2[1025], nfirst2=0; /* 1st sp2 col containing set pixel*/ |
firstcol2[1025], nfirst2=0; /* 1st sp2 col containing set pixel*/ |
int blanksignal = (-991234); /*rastsquash signal right-hand blank*/ |
|
int smin=9999, xmin=9999,ymin=9999; /* min separation (s=x+y) */ |
int smin=9999, xmin=9999,ymin=9999; /* min separation (s=x+y) */ |
int type_raster(); /* display debugging output */ |
int type_raster(); /* display debugging output */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 1528 find right edge of sp1 and left edge of
|
Line 1563 find right edge of sp1 and left edge of
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- check args --- */ |
/* --- check args --- */ |
if ( isstring ) goto end_of_job; /* ignore string rasters */ |
if ( isstring ) goto end_of_job; /* ignore string rasters */ |
if ( height > 1023 ) goto end_of_job; /* don't try to squash huge image */ |
if ( 0 && istextmode ) goto end_of_job; /* don't smash in text mode */ |
|
if ( height > 1023 ) goto end_of_job; /* don't try to smash huge image */ |
if ( sp2->type == blanksignal ) /*blanksignal was propagated to us*/ |
if ( sp2->type == blanksignal ) /*blanksignal was propagated to us*/ |
goto end_of_job; /* don't squash intentional blank */ |
goto end_of_job; /* don't smash intentional blank */ |
/* --- init firstcol1[], firstcol2[] --- */ |
/* --- init firstcol1[], firstcol2[] --- */ |
for ( irow1=0; irow1<height; irow1++ ) /* for each row */ |
for ( irow1=0; irow1<height; irow1++ ) /* for each row */ |
firstcol1[irow1] = firstcol2[irow1] = blanksignal; /* signal empty rows */ |
firstcol1[irow1] = firstcol2[irow1] = blanksignal; /* signal empty rows */ |
Line 1542 for ( irow2=top2; irow2<=bot2; irow2++ )
|
Line 1578 for ( irow2=top2; irow2<=bot2; irow2++ )
|
nfirst2++; /* bump #rows containing set pixels*/ |
nfirst2++; /* bump #rows containing set pixels*/ |
break; } /* and go on to next row */ |
break; } /* and go on to next row */ |
if ( nfirst2 < 1 ) /*right-hand sp2 is completely blank*/ |
if ( nfirst2 < 1 ) /*right-hand sp2 is completely blank*/ |
{ nsquash = blanksignal; /* signal intentional blanks */ |
{ nsmash = blanksignal; /* signal intentional blanks */ |
goto end_of_job; } /* don't squash intentional blanks */ |
goto end_of_job; } /* don't smash intentional blanks */ |
/* --- now check if preceding image in sp1 was an intentional blank --- */ |
/* --- now check if preceding image in sp1 was an intentional blank --- */ |
if ( sp1->type == blanksignal ) /*blanksignal was propagated to us*/ |
if ( sp1->type == blanksignal ) /*blanksignal was propagated to us*/ |
goto end_of_job; /* don't squash intentional blank */ |
goto end_of_job; /* don't smash intentional blank */ |
/* --- set firstcol1[] indicating right edge of sp1 --- */ |
/* --- set firstcol1[] indicating right edge of sp1 --- */ |
for ( irow1=top1; irow1<=bot1; irow1++ ) /* for each row inside sp1 */ |
for ( irow1=top1; irow1<=bot1; irow1++ ) /* for each row inside sp1 */ |
for ( icol=width1-1; icol>=0; icol-- ) /* find last non-empty col in row */ |
for ( icol=width1-1; icol>=0; icol-- ) /* find last non-empty col in row */ |
Line 1555 for ( irow1=top1; irow1<=bot1; irow1++ )
|
Line 1591 for ( irow1=top1; irow1<=bot1; irow1++ )
|
nfirst1++; /* bump #rows containing set pixels*/ |
nfirst1++; /* bump #rows containing set pixels*/ |
break; } /* and go on to next row */ |
break; } /* and go on to next row */ |
if ( nfirst1 < 1 ) /*left-hand sp1 is completely blank*/ |
if ( nfirst1 < 1 ) /*left-hand sp1 is completely blank*/ |
goto end_of_job; /* don't squash intentional blanks */ |
goto end_of_job; /* don't smash intentional blanks */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
find minimum separation |
find minimum separation |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 1568 for ( irow2=top2; irow2<=bot2; irow2++ )
|
Line 1604 for ( irow2=top2; irow2<=bot2; irow2++ )
|
if ( (margin1=firstcol1[irow1]) != blanksignal ) { /*have non-blank row*/ |
if ( (margin1=firstcol1[irow1]) != blanksignal ) { /*have non-blank row*/ |
int dx=(margin1+margin2), dy=absval(irow2-irow1), ds=dx+dy; /* deltas */ |
int dx=(margin1+margin2), dy=absval(irow2-irow1), ds=dx+dy; /* deltas */ |
if ( ds >= smin ) continue; /* min unchanged */ |
if ( ds >= smin ) continue; /* min unchanged */ |
if ( dy>squashmargin && dx<xmin && smin<9999 ) continue; /* dy alone */ |
if ( dy>smashmargin && dx<xmin && smin<9999 ) continue; /* dy alone */ |
smin=ds; xmin=dx; ymin=dy; /* set new min */ |
smin=ds; xmin=dx; ymin=dy; /* set new min */ |
} /* --- end-of-if(margin1!=blanksignal) --- */ |
} /* --- end-of-if(margin1!=blanksignal) --- */ |
if ( smin<2 ) goto end_of_job; /* can't squash */ |
if ( smin<2 ) goto end_of_job; /* can't smash */ |
} /* --- end-of-for(irow2) --- */ |
} /* --- end-of-for(irow2) --- */ |
/*nsquash = min2(xmin,width2);*/ /* permissible squash */ |
/*nsmash = min2(xmin,width2);*/ /* permissible smash */ |
nsquash = xmin; /* permissible squash */ |
nsmash = xmin; /* permissible smash */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Back to caller with #pixels to squash sp1||sp2 |
Back to caller with #pixels to smash sp1||sp2 |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
end_of_job: |
end_of_job: |
/* --- debugging output --- */ |
/* --- debugging output --- */ |
if ( msgfp!=NULL && msglevel >= 99 ) /* display for debugging */ |
if ( msgfp!=NULL && msglevel >= 99 ) /* display for debugging */ |
{ fprintf(msgfp,"rastsquash> nsquash=%d, squashmargin=%d\n", |
{ fprintf(msgfp,"rastsmash> nsmash=%d, smashmargin=%d\n", |
nsquash,squashmargin); |
nsmash,smashmargin); |
if ( msglevel >= 999 ) /* also display rasters */ |
if ( msglevel >= 999 ) /* also display rasters */ |
{ fprintf(msgfp,"rastsquash>left-hand image...\n"); |
{ fprintf(msgfp,"rastsmash>left-hand image...\n"); |
if(sp1!=NULL) type_raster(sp1->image,msgfp); /* left image */ |
if(sp1!=NULL) type_raster(sp1->image,msgfp); /* left image */ |
fprintf(msgfp,"rastsquash>right-hand image...\n"); |
fprintf(msgfp,"rastsmash>right-hand image...\n"); |
if(sp2!=NULL) type_raster(sp2->image,msgfp); } /* right image */ |
if(sp2!=NULL) type_raster(sp2->image,msgfp); } /* right image */ |
fflush(msgfp); } |
fflush(msgfp); } |
return ( nsquash ); /* back with #squash pixels */ |
return ( nsmash ); /* back with #smash pixels */ |
} /* --- end-of-function rastsquash() --- */ |
} /* --- end-of-function rastsmash() --- */ |
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
Line 1622 raster *new_raster(), *rp=NULL; /*raster
|
Line 1658 raster *new_raster(), *rp=NULL; /*raster
|
subraster *new_subraster(), *sp=NULL; /* subraster returning accent */ |
subraster *new_subraster(), *sp=NULL; /* subraster returning accent */ |
int delete_raster(), delete_subraster(); /*free allocated raster on err*/ |
int delete_raster(), delete_subraster(); /*free allocated raster on err*/ |
int line_raster(), /* draws lines */ |
int line_raster(), /* draws lines */ |
|
rule_raster(), /* draw solid boxes */ |
thickness = 1; /* line thickness */ |
thickness = 1; /* line thickness */ |
/*int pixval = (pixsz==1? 1 : (pixsz==8?255:(-1)));*/ /*black pixel value*/ |
/*int pixval = (pixsz==1? 1 : (pixsz==8?255:(-1)));*/ /*black pixel value*/ |
/* --- other working info --- */ |
/* --- other working info --- */ |
Line 1653 switch ( accent )
|
Line 1690 switch ( accent )
|
/* --- bar request --- */ |
/* --- bar request --- */ |
case UNDERBARACCENT: |
case UNDERBARACCENT: |
case BARACCENT: |
case BARACCENT: |
thickness = height-1; /* adjust thickness */ |
thickness = 1; /*height-1;*/ /* adjust thickness */ |
if ( accent == BARACCENT ) /* bar is above expression */ |
if ( accent == BARACCENT ) /* bar is above expression */ |
line_raster(rp,0,0,0,width-1,thickness); /*leave blank line at bot*/ |
{ row0 = row1 = max2(height-3,0); /* row numbers for overbar */ |
|
line_raster(rp,row0,0,row1,width-1,thickness); } /*blanks at bot*/ |
else /* underbar is below expression */ |
else /* underbar is below expression */ |
line_raster(rp,1,0,1,width-1,thickness); /*leave blank line at top*/ |
{ row0 = row1 = min2(2,height-1); /* row numbers for underbar */ |
|
line_raster(rp,row0,0,row1,width-1,thickness); } /*blanks at top*/ |
break; |
break; |
/* --- dot request --- */ |
/* --- dot request --- */ |
case DOTACCENT: |
case DOTACCENT: |
thickness = height-1; /* adjust thickness */ |
thickness = height-1; /* adjust thickness */ |
line_raster(rp,0,width/2,1,(width/2)+1,thickness); /* centered dot */ |
/*line_raster(rp,0,width/2,1,(width/2)+1,thickness);*//*centered dot*/ |
|
rule_raster(rp,0,(width+1-thickness)/2,thickness,thickness,3); /*box*/ |
break; |
break; |
/* --- ddot request --- */ |
/* --- ddot request --- */ |
case DDOTACCENT: |
case DDOTACCENT: |
thickness = height-1; /* adjust thickness */ |
thickness = height-1; /* adjust thickness */ |
col0 = max2(width/3-(thickness-1),0); /* one-third of width */ |
col0 = max2((width+1)/3-(thickness/2)-1,0); /* one-third of width */ |
col1 = min2((2*width)/3+(thickness-1),width-thickness); /*two thirds*/ |
col1 = min2((2*width+1)/3-(thickness/2)+1,width-thickness); /*2/3rds*/ |
line_raster(rp,0,col0,1,col0+1,thickness); /* set a dot at 1st third*/ |
if ( col0+thickness >= col1 ) /* dots overlap */ |
line_raster(rp,0,col1,1,col1+1,thickness); /* and another at 2nd */ |
{ col0 = max2(col0-1,0); /* try moving left dot more left */ |
|
col1 = min2(col1+1,width-thickness); } /* and right dot right */ |
|
if ( col0+thickness >= col1 ) /* dots _still_ overlap */ |
|
thickness = max2(thickness-1,1); /* so try reducing thickness */ |
|
/*line_raster(rp,0,col0,1,col0+1,thickness);*//*set dot at 1st third*/ |
|
/*line_raster(rp,0,col1,1,col1+1,thickness);*//*and another at 2nd*/ |
|
rule_raster(rp,0,col0,thickness,thickness,3); /*box at 1st third*/ |
|
rule_raster(rp,0,col1,thickness,thickness,3); /*box at 2nd third*/ |
break; |
break; |
/* --- hat request --- */ |
/* --- hat request --- */ |
case HATACCENT: |
case HATACCENT: |
thickness = (width<=12? 2 : 3); /* adjust thickness */ |
thickness = 1; /*(width<=12? 2 : 3);*/ /* adjust thickness */ |
line_raster(rp,height-1,0,0,width/2,thickness); /* / part of hat*/ |
line_raster(rp,height-1,0,0,width/2,thickness); /* / part of hat*/ |
line_raster(rp,0,(width-1)/2,height-1,width-1,thickness); /* \ part*/ |
line_raster(rp,0,(width-1)/2,height-1,width-1,thickness); /* \ part*/ |
break; |
break; |
Line 1724 switch ( accent )
|
Line 1771 switch ( accent )
|
if ( (sp=rastack(new_subraster(1,1,pixsz),accsp,1,0,1,3))/*space below*/ |
if ( (sp=rastack(new_subraster(1,1,pixsz),accsp,1,0,1,3))/*space below*/ |
!= NULL ) /* have tilde with space below it */ |
!= NULL ) /* have tilde with space below it */ |
{ rp = sp->image; /* "extract" raster with bitmap */ |
{ rp = sp->image; /* "extract" raster with bitmap */ |
free((void *)sp); } /* and free subraster "envelope" */ |
free((void *)sp); /* and free subraster "envelope" */ |
|
leftsymdef = NULL; } /* so \tilde{x}^2 works properly */ |
break; |
break; |
} /* --- end-of-outer-switch(accent) --- */ |
} /* --- end-of-outer-switch(accent) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 1774 Allocations and Declarations
|
Line 1822 Allocations and Declarations
|
subraster *new_subraster(), *arrowsp=NULL; /* allocate arrow subraster */ |
subraster *new_subraster(), *arrowsp=NULL; /* allocate arrow subraster */ |
int rule_raster(); /* draw arrow line */ |
int rule_raster(); /* draw arrow line */ |
int irow, midrow=height/2; /* index, midrow is arrowhead apex */ |
int irow, midrow=height/2; /* index, midrow is arrowhead apex */ |
int icol, thickness=(height>15?2:1); /* arrowhead thickness and index */ |
int icol, thickness=(height>15?2:2); /* arrowhead thickness and index */ |
int pixval = (pixsz==1? 1 : (pixsz==8?255:(-1))); /* black pixel value */ |
int pixval = (pixsz==1? 1 : (pixsz==8?255:(-1))); /* black pixel value */ |
int ipix, /* raster pixmap[] index */ |
int ipix, /* raster pixmap[] index */ |
npix = width*height; /* #pixels malloced in pixmap[] */ |
npix = width*height; /* #pixels malloced in pixmap[] */ |
Line 1850 Allocations and Declarations
|
Line 1898 Allocations and Declarations
|
subraster *new_subraster(), *arrowsp=NULL; /* allocate arrow subraster */ |
subraster *new_subraster(), *arrowsp=NULL; /* allocate arrow subraster */ |
int rule_raster(); /* draw arrow line */ |
int rule_raster(); /* draw arrow line */ |
int icol, midcol=width/2; /* index, midcol is arrowhead apex */ |
int icol, midcol=width/2; /* index, midcol is arrowhead apex */ |
int irow, thickness=(width>15?2:1); /* arrowhead thickness and index */ |
int irow, thickness=(width>15?2:2); /* arrowhead thickness and index */ |
int pixval = (pixsz==1? 1 : (pixsz==8?255:(-1))); /* black pixel value */ |
int pixval = (pixsz==1? 1 : (pixsz==8?255:(-1))); /* black pixel value */ |
int ipix, /* raster pixmap[] index */ |
int ipix, /* raster pixmap[] index */ |
npix = width*height; /* #pixels malloced in pixmap[] */ |
npix = width*height; /* #pixels malloced in pixmap[] */ |
Line 1892 for ( icol=0; icol<width; icol++ ) /* f
|
Line 1940 for ( icol=0; icol<width; icol++ ) /* f
|
else /* should have a bytemap */ |
else /* should have a bytemap */ |
if ( pixsz == 8 ) /* check pixsz for bytemap */ |
if ( pixsz == 8 ) /* check pixsz for bytemap */ |
((arrowsp->image)->pixmap)[ipix] = pixval; } /*set arrowhead byte*/ |
((arrowsp->image)->pixmap)[ipix] = pixval; } /*set arrowhead byte*/ |
} /* --- end-of-for(irow) --- */ |
} /* --- end-of-for(icol) --- */ |
end_of_job: |
end_of_job: |
return ( arrowsp ); /*back to caller with arrow or NULL*/ |
return ( arrowsp ); /*back to caller with arrow or NULL*/ |
} /* --- end-of-function uparrow_subraster() --- */ |
} /* --- end-of-function uparrow_subraster() --- */ |
Line 1913 end_of_job:
|
Line 1961 end_of_job:
|
* height (I) int containing number of rows for rule |
* height (I) int containing number of rows for rule |
* type (I) int containing 0 for solid rule, |
* type (I) int containing 0 for solid rule, |
* 1 for horizontal dashes, 2 for vertical |
* 1 for horizontal dashes, 2 for vertical |
|
* 3 for solid rule with corners removed |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Returns: ( int ) 1 if rule drawn okay, |
* Returns: ( int ) 1 if rule drawn okay, |
* or 0 for any error. |
* or 0 for any error. |
Line 1928 int rule_raster ( raster *rp, int top, i
|
Line 1977 int rule_raster ( raster *rp, int top, i
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
int irow, icol; /* indexes over rp raster */ |
int irow=0, icol=0; /* indexes over rp raster */ |
int ipix, /* raster pixmap[] index */ |
int ipix = 0, /* raster pixmap[] index */ |
npix = rp->width * rp->height; /* #pixels malloced in rp->pixmap[] */ |
npix = rp->width * rp->height; /* #pixels malloced in rp->pixmap[] */ |
int isfatal = 0; /* true to abend on out-of-bounds error */ |
int isfatal = 0; /* true to abend on out-of-bounds error */ |
int hdash=1, vdash=2; /* type for horizontal, vertical dashes */ |
int hdash=1, vdash=2; /* type for horizontal, vertical dashes */ |
Line 1942 if ( rp == (raster *)NULL ) /* no raster
|
Line 1991 if ( rp == (raster *)NULL ) /* no raster
|
if ( workingbox != (subraster *)NULL ) /* see if we have a workingbox */ |
if ( workingbox != (subraster *)NULL ) /* see if we have a workingbox */ |
rp = workingbox->image; /* use workingbox if possible */ |
rp = workingbox->image; /* use workingbox if possible */ |
else return ( 0 ); /* otherwise signal error to caller */ |
else return ( 0 ); /* otherwise signal error to caller */ |
|
if ( type == 3 ) /* remove corners of solid box */ |
|
if ( width<3 || height<3 ) type=0; /* too small to remove corners */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Fill line/box |
Fill line/box |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 1952 for ( irow=top; irow<top+height; irow++
|
Line 2003 for ( irow=top; irow<top+height; irow++
|
ipix = irow*rp->width + left - 1; /*first pixel preceding icol*/ |
ipix = irow*rp->width + left - 1; /*first pixel preceding icol*/ |
for ( icol=left; icol<left+width; icol++ ) /* each pixel in scan line */ |
for ( icol=left; icol<left+width; icol++ ) /* each pixel in scan line */ |
{ |
{ |
|
if ( type == 3 ) /* remove corners of box */ |
|
if ( (irow==top && icol==left) /* top-left corner */ |
|
|| (irow==top && icol>=left+width-1) /* top-right corner */ |
|
|| (irow>=top+height-1 && icol==left) /* bottom-left corner */ |
|
|| (irow>=top+height-1 && icol>=left+width-1) ) /* bottom-right */ |
|
isdraw = 0; else isdraw = 1; /*set isdraw to skip corner*/ |
if ( type == hdash ) /*set isdraw for horiz dash*/ |
if ( type == hdash ) /*set isdraw for horiz dash*/ |
isdraw = (((icol-left)%(dashlen+spacelen)) < dashlen); |
isdraw = (((icol-left)%(dashlen+spacelen)) < dashlen); |
if ( ++ipix >= npix ) /* bounds check failed */ |
if ( ++ipix >= npix ) /* bounds check failed */ |
Line 2008 int line_raster ( raster *rp, int row0,
|
Line 2065 int line_raster ( raster *rp, int row0,
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
int irow, icol, /* indexes over rp raster */ |
int irow=0, icol=0, /* indexes over rp raster */ |
locol=col0, hicol=col1, /* col limits at irow */ |
locol=col0, hicol=col1, /* col limits at irow */ |
lorow=row0, hirow=row1; /* row limits at icol */ |
lorow=row0, hirow=row1; /* row limits at icol */ |
int ipix, /* raster pixmap[] index */ |
int width=rp->width, height=rp->height; /* dimensions of input raster */ |
npix = rp->width * rp->height; /* #pixels malloced in rp->pixmap[] */ |
int ipix = 0, /* raster pixmap[] index */ |
|
npix = width*height; /* #pixels malloced in rp->pixmap[] */ |
int isfatal = 0; /* true to abend on out-of-bounds error */ |
int isfatal = 0; /* true to abend on out-of-bounds error */ |
int isline=(row1==row0), isbar=(col1==col0); /*true if slope a=0,\infty*/ |
int isline=(row1==row0), isbar=(col1==col0); /*true if slope a=0,\infty*/ |
double dy = row1-row0 /* + (row1>=row0? +1.0 : -1.0) */, /* delta-x */ |
double dy = row1-row0 /* + (row1>=row0? +1.0 : -1.0) */, /* delta-x */ |
dx = col1-col0 /* + (col1>=col0? +1.0 : -1.0) */, /* delta-y */ |
dx = col1-col0 /* + (col1>=col0? +1.0 : -1.0) */, /* delta-y */ |
a= (isbar||isline? 0.0 : dy/dx), /* slope = tan(theta) = dy/dx */ |
a= (isbar||isline? 0.0 : dy/dx), /* slope = tan(theta) = dy/dx */ |
xcol, xrow; /* calculated col at irow, or row at icol */ |
xcol=0, xrow=0; /* calculated col at irow, or row at icol */ |
double ar = ASPECTRATIO, /* aspect ratio width/height of one pixel */ |
double ar = ASPECTRATIO, /* aspect ratio width/height of one pixel */ |
xwidth= (isline? 0.0 : /*#pixels per row to get sloped line thcknss*/ |
xwidth= (isline? 0.0 : /*#pixels per row to get sloped line thcknss*/ |
((double)thickness)*sqrt((dx*dx)+(dy*dy*ar*ar))/fabs(dy*ar)), |
((double)thickness)*sqrt((dx*dx)+(dy*dy*ar*ar))/fabs(dy*ar)), |
Line 2039 if ( msgfp!=NULL && msglevel>=29 ) /* d
|
Line 2097 if ( msgfp!=NULL && msglevel>=29 ) /* d
|
"\t dy,dx=%3.1f,%3.1f, a=%4.3f, xwidth=%4.3f\n", |
"\t dy,dx=%3.1f,%3.1f, a=%4.3f, xwidth=%4.3f\n", |
row0,col0, row1,col1, thickness, dy,dx, a, xwidth); |
row0,col0, row1,col1, thickness, dy,dx, a, xwidth); |
/* --- check for recursive line drawing --- */ |
/* --- check for recursive line drawing --- */ |
if ( isrecurse ) /* drawing lines recursively */ |
if ( isrecurse ) { /* drawing lines recursively */ |
{ line_recurse(rp,(double)row0,(double)col0, |
for ( irow=0; irow<thickness; irow++ ) /* each line 1 pixel thick */ |
(double)row1,(double)col1,thickness); |
{ double xrow0=(double)row0, xcol0=(double)col0, |
return ( 1 ); } |
xrow1=(double)row1, xcol1=(double)col1; |
|
if ( isline ) xrow0 = xrow1 = (double)(row0+irow); |
|
else if ( isbar ) xcol0 = xcol1 = (double)(col0+irow); |
|
if( xrow0>(-0.001) && xcol0>(-0.001) /*check line inside raster*/ |
|
&& xrow1<((double)(height-1)+0.001) && xcol1<((double)(width-1)+0.001) ) |
|
line_recurse(rp,xrow0,xcol0,xrow1,xcol1,thickness); } |
|
return ( 1 ); } |
/* --- set params for horizontal line or vertical bar --- */ |
/* --- set params for horizontal line or vertical bar --- */ |
if ( isline ) /*interpret row as top row*/ |
if ( isline ) /*interpret row as top row*/ |
row1 = row0 + (thickness-1); /* set bottom row for line */ |
row1 = row0 + (thickness-1); /* set bottom row for line */ |
Line 2588 static char display_chars[16] = /* displ
|
Line 2652 static char display_chars[16] = /* displ
|
char scanline[133]; /* ascii image for one scan line */ |
char scanline[133]; /* ascii image for one scan line */ |
int scan_width; /* #chars in scan (<=display_width)*/ |
int scan_width; /* #chars in scan (<=display_width)*/ |
int irow, locol,hicol=(-1); /* height index, width indexes */ |
int irow, locol,hicol=(-1); /* height index, width indexes */ |
|
raster *gftobitmap(), *bitmaprp=rp; /* convert .gf to bitmap if needed */ |
|
int delete_raster(); /*free bitmap converted for display*/ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 2595 initialization
|
Line 2661 initialization
|
if ( fp == (FILE *)NULL ) fp = stdout; /* default fp to stdout if null */ |
if ( fp == (FILE *)NULL ) fp = stdout; /* default fp to stdout if null */ |
/* --- check for ascii string --- */ |
/* --- check for ascii string --- */ |
if ( isstring /* pixmap has string, not raster */ |
if ( isstring /* pixmap has string, not raster */ |
|| (1 && rp->height==1) ) /* infer input rp is a string */ |
|| (0 && rp->height==1) ) /* infer input rp is a string */ |
{ |
{ |
char *string = (char *)(rp->pixmap); /*interpret pixmap as ascii string*/ |
char *string = (char *)(rp->pixmap); /*interpret pixmap as ascii string*/ |
int width = strlen(string); /* #chars in ascii string */ |
int width = strlen(string); /* #chars in ascii string */ |
Line 2609 if ( isstring /* pixmap has string, n
|
Line 2675 if ( isstring /* pixmap has string, n
|
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
display ascii dump of bitmap image (in segments if display_width < rp->width) |
display ascii dump of bitmap image (in segments if display_width < rp->width) |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
while ( (locol=hicol+1) < rp->width ) /*start where prev segment left off*/ |
if ( rp->format == 2 /* input is .gf-formatted */ |
|
|| rp->format == 3 ) |
|
bitmaprp = gftobitmap(rp); /* so convert it for display */ |
|
if ( bitmaprp != NULL ) /* if we have image for display */ |
|
while ( (locol=hicol+1) < rp->width ) /*start where prev segment left off*/ |
{ |
{ |
/* --- set hicol for this pass (locol set above) --- */ |
/* --- set hicol for this pass (locol set above) --- */ |
hicol += display_width; /* show as much as display allows */ |
hicol += display_width; /* show as much as display allows */ |
Line 2626 while ( (locol=hicol+1) < rp->width ) /*
|
Line 2696 while ( (locol=hicol+1) < rp->width ) /*
|
lopix = irow*rp->width + locol; /*first pixmap[] pixel in this scan*/ |
lopix = irow*rp->width + locol; /*first pixmap[] pixel in this scan*/ |
/* --- set chars in scanline[] based on pixels in rp->pixmap[] --- */ |
/* --- set chars in scanline[] based on pixels in rp->pixmap[] --- */ |
for ( ipix=0; ipix<scan_width; ipix++ ) /* set each char */ |
for ( ipix=0; ipix<scan_width; ipix++ ) /* set each char */ |
if ( rp->pixsz == 1 ) /*' '=0 or '*'=1 to display bitmap*/ |
if ( bitmaprp->pixsz == 1 ) /*' '=0 or '*'=1 to display bitmap*/ |
scanline[ipix] = (getlongbit(rp->pixmap,lopix+ipix)==1? '*':'.'); |
scanline[ipix]=(getlongbit(bitmaprp->pixmap,lopix+ipix)==1? '*':'.'); |
else /* should have a bytemap */ |
else /* should have a bytemap */ |
if ( rp->pixsz == 8 ) /* double-check pixsz for bytemap */ |
if ( bitmaprp->pixsz == 8 ) /* double-check pixsz for bytemap */ |
{ int pixval = (int)((rp->pixmap)[lopix+ipix]), /*pixel's byte value*/ |
{ int pixval = (int)((bitmaprp->pixmap)[lopix+ipix]), /*byte value*/ |
ichar = min2(15,pixval/16); /* index for ' ', '1'...'e', '*' */ |
ichar = min2(15,pixval/16); /* index for ' ', '1'...'e', '*' */ |
scanline[ipix] = display_chars[ichar]; } /*set ' ' for 0-15, etc*/ |
scanline[ipix] = display_chars[ichar]; } /*set ' ' for 0-15, etc*/ |
/* --- display completed scan line --- */ |
/* --- display completed scan line --- */ |
Line 2640 while ( (locol=hicol+1) < rp->width ) /*
|
Line 2710 while ( (locol=hicol+1) < rp->width ) /*
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Back to caller with 1=okay, 0=failed. |
Back to caller with 1=okay, 0=failed. |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
|
if ( rp->format == 2 /* input was .gf-format */ |
|
|| rp->format == 3 ) |
|
if ( bitmaprp != NULL ) /* and we converted it for display */ |
|
delete_raster(bitmaprp); /* no longer needed, so free it */ |
return ( 1 ); |
return ( 1 ); |
} /* --- end-of-function type_raster() --- */ |
} /* --- end-of-function type_raster() --- */ |
|
|
Line 2782 return ( 1 );
|
Line 2856 return ( 1 );
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: type_pbmpgm ( rp, ptype, file ) |
|
* Purpose: Write pbm or pgm image of rp to file |
|
* -------------------------------------------------------------------------- |
|
* Arguments: rp (I) ptr to raster struct for which |
|
* a pbm/pgm file is to be written. |
|
* ptype (I) int containing 1 for pbm, 2 for pgm, or |
|
* 0 to determine ptype from values in rp |
|
* file (I) ptr to null-terminated char string |
|
* containing name of fuke to be written |
|
* (see notes below). |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) total #bytes written, |
|
* or 0 for any error. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o (a) If file==NULL, output is written to stdout; |
|
* (b) if *file=='\000' then file is taken as the |
|
* address of an output buffer to which output |
|
* is written (and is followed by a terminating |
|
* '\0' which is not counted in #bytes returned); |
|
* (c) otherwise file is the filename (opened and |
|
* closed internally) to which output is written, |
|
* except that any final .ext extension is replaced |
|
* by .pbm or .pgm depending on ptype. |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int type_pbmpgm ( raster *rp, int ptype, char *file ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int isokay=0, nbytes=0; /* completion flag, total #bytes written */ |
|
int irow=0, jcol=0; /*height(row), width(col) indexes in raster*/ |
|
int pixmin=9999, pixmax=(-9999), /* min, max pixel value in raster */ |
|
ngray = 0; /* #gray scale values */ |
|
FILE /* *fopen(), */ *fp=NULL; /* pointer to output file (or NULL) */ |
|
char outline[1024], outfield[256], /* output line, field */ |
|
cr[16] = "\n\000"; /* cr at end-of-line */ |
|
int maxlinelen = 70; /* maximum allowed line length */ |
|
int pixfrac=6; /* use (pixmax-pixmin)/pixfrac as step */ |
|
static char |
|
*suffix[] = { NULL, ".pbm", ".pgm" }, /* file.suffix[ptype] */ |
|
*magic[] = { NULL, "P1", "P2" }, /*identifying "magic number"*/ |
|
*mode[] = { NULL, "w", "w" }; /* fopen() mode[ptype] */ |
|
/* ------------------------------------------------------------------------- |
|
check input, determine grayscale, and set up output file if necessary |
|
-------------------------------------------------------------------------- */ |
|
/* --- check input args --- */ |
|
if ( rp == NULL ) goto end_of_job; /* no input raster provided */ |
|
if ( ptype != 0 ) /* we'll determine ptype below */ |
|
if ( ptype<1 || ptype>2 ) goto end_of_job; /*invalid output graphic format*/ |
|
/* --- determine largest (and smallest) value in pixmap --- */ |
|
for ( irow=0; irow<rp->height; irow++ ) /* for each row, top-to-bottom */ |
|
for ( jcol=0; jcol<rp->width; jcol++ ) /* for each col, left-to-right */ |
|
{ int pixval = getpixel(rp,irow,jcol); /* value of pixel at irow,jcol */ |
|
pixmin = min2(pixmin,pixval); /* new minimum */ |
|
pixmax = max2(pixmax,pixval); } /* new maximum */ |
|
ngray = 1 + (pixmax-pixmin); /* should be 2 for b/w bitmap */ |
|
if ( ptype == 0 ) /* caller wants us to set ptype */ |
|
ptype = (ngray>=3?2:1); /* use grayscale if >2 shades */ |
|
/* --- open output file if necessary --- */ |
|
if ( file == NULL ) fp = stdout; /*null ptr signals output to stdout*/ |
|
else if ( *file != '\000' ) { /* explicit filename provided, so...*/ |
|
char fname[512], *pdot=NULL; /* file.ext, ptr to last . in fname*/ |
|
strncpy(fname,file,255); /* local copy of file name */ |
|
fname[255] = '\000'; /* make sure it's null terminated */ |
|
if ( (pdot=strrchr(fname,'.')) == NULL ) /*no extension on original name*/ |
|
strcat(fname,suffix[ptype]); /* so add extension */ |
|
else /* we already have an extension */ |
|
strcpy(pdot,suffix[ptype]); /* so replace original extension */ |
|
if ( (fp = fopen(fname,mode[ptype])) /* open output file */ |
|
== (FILE *)NULL ) goto end_of_job; /* quit if failed to open */ |
|
} /* --- ens-of-if(*file!='\0') --- */ |
|
/* ------------------------------------------------------------------------- |
|
format and write header |
|
-------------------------------------------------------------------------- */ |
|
/* --- format header info --- */ |
|
*outline = '\000'; /* initialize line buffer */ |
|
strcat(outline,magic[ptype]); /* begin file with "magic number" */ |
|
strcat(outline,cr); /* followed by cr to end line */ |
|
sprintf(outfield,"%d %d",rp->width,rp->height); /* format width and height */ |
|
strcat(outline,outfield); /* add width and height to header */ |
|
strcat(outline,cr); /* followed by cr to end line */ |
|
if ( ptype == 2 ) /* need max grayscale value */ |
|
{ sprintf(outfield,"%d",pixmax); /* format maximum pixel value */ |
|
strcat(outline,outfield); /* add max value to header */ |
|
strcat(outline,cr); } /* followed by cr to end line */ |
|
/* --- write header to file or memory buffer --- */ |
|
if ( fp == NULL ) /* if we have no open file... */ |
|
strcat(file,outline); /* add header to caller's buffer */ |
|
else /* or if we have an open file... */ |
|
if ( fputs(outline,fp) /* try writing header to open file */ |
|
== EOF ) goto end_of_job; /* return with error if failed */ |
|
nbytes += strlen(outline); /* bump output byte count */ |
|
/* ------------------------------------------------------------------------- |
|
format and write pixels |
|
-------------------------------------------------------------------------- */ |
|
*outline = '\000'; /* initialize line buffer */ |
|
for ( irow=0; irow<=rp->height; irow++ ) /* for each row, top-to-bottom */ |
|
for ( jcol=0; jcol<rp->width; jcol++ ) { /* for each col, left-to-right */ |
|
/* --- format value at irow,jcol--- */ |
|
*outfield = '\000'; /* init empty field */ |
|
if ( irow < rp->height ) { /* check row index */ |
|
int pixval = getpixel(rp,irow,jcol); /* value of pixel at irow,jcol */ |
|
if ( ptype == 1 ) /* pixval must be 1 or 0 */ |
|
pixval = (pixval>pixmin+((pixmax-pixmin)/pixfrac)?1:0); |
|
sprintf(outfield,"%d ",pixval); } /* format pixel value */ |
|
/* --- write line if this value won't fit on it (or last line) --- */ |
|
if ( strlen(outline)+strlen(outfield)+strlen(cr) >= maxlinelen /*won't fit*/ |
|
|| irow >= rp->height ) { /* force writing last line */ |
|
strcat(outline,cr); /* add cr to end current line */ |
|
if ( fp == NULL ) /* if we have no open file... */ |
|
strcat(file,outline); /* add header to caller's buffer */ |
|
else /* or if we have an open file... */ |
|
if ( fputs(outline,fp) /* try writing header to open file */ |
|
== EOF ) goto end_of_job; /* return with error if failed */ |
|
nbytes += strlen(outline); /* bump output byte count */ |
|
*outline = '\000'; /* re-initialize line buffer */ |
|
} /* --- end-of-if(strlen>=maxlinelen) --- */ |
|
if ( irow >= rp->height ) break; /* done after writing last line */ |
|
/* --- concatanate value to line -- */ |
|
strcat(outline,outfield); /* concatanate value to line */ |
|
} /* --- end-of-for(jcol,irow) --- */ |
|
isokay = 1; /* signal successful completion */ |
|
/* ------------------------------------------------------------------------- |
|
Back to caller with total #bytes written, or 0=failed. |
|
-------------------------------------------------------------------------- */ |
|
end_of_job: |
|
if ( fp != NULL /* output written to an open file */ |
|
&& fp != stdout ) /* and it's not just stdout */ |
|
fclose(fp); /* so close file before returning */ |
|
return ( (isokay?nbytes:0) ); /*back to caller with #bytes written*/ |
|
} /* --- end-of-function type_pbmpgm() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: cstruct_chardef ( cp, fp, col1 ) |
* Function: cstruct_chardef ( cp, fp, col1 ) |
* Purpose: Emit a C struct of cp on fp, starting in col1. |
* Purpose: Emit a C struct of cp on fp, starting in col1. |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 2813 emit charnum, location, name / hirow
|
Line 3022 emit charnum, location, name / hirow
|
sprintf(field,"{ %3d,%5d,\n", cp->charnum,cp->location); /*char#,location*/ |
sprintf(field,"{ %3d,%5d,\n", cp->charnum,cp->location); /*char#,location*/ |
emit_string ( fp, col1, field, "character number, location"); |
emit_string ( fp, col1, field, "character number, location"); |
/* --- toprow, topleftcol, botrow, botleftcol --- */ |
/* --- toprow, topleftcol, botrow, botleftcol --- */ |
sprintf(field," %3d,%2d, %3d,%2d,\n", /* format... */ |
sprintf(field," %3d,%2d, %3d,%2d,\n", /* format... */ |
cp->toprow,cp->topleftcol, /* toprow, topleftcol, */ |
cp->toprow,cp->topleftcol, /* toprow, topleftcol, */ |
cp->botrow,cp->botleftcol); /* and botrow, botleftcol */ |
cp->botrow,cp->botleftcol); /* and botrow, botleftcol */ |
emit_string ( fp, col1, field, "topleft row,col, and botleft row,col"); |
emit_string ( fp, col1, field, "topleft row,col, and botleft row,col"); |
Line 2855 int emit_string(); /* emit a string and
|
Line 3064 int emit_string(); /* emit a string and
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
emit width and height |
emit width and height |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
sprintf(field,"{ %2d, %3d,%2d, %s\n", /* format width,height,pixsz */ |
sprintf(field,"{ %2d, %3d,%2d,%2d, %s\n", /* format width,height,pixsz */ |
rp->width,rp->height,rp->pixsz,typecast); |
rp->width,rp->height,rp->format,rp->pixsz,typecast); |
emit_string ( fp, col1, field, "widthxheight, pixsz,map..."); |
emit_string ( fp, col1, field, "width,ht, fmt,pixsz,map..."); |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
emit bitmap and closing brace, and return to caller |
emit bitmap and closing brace, and return to caller |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 2894 int hex_bitmap ( raster *rp, FILE *fp, i
|
Line 3103 int hex_bitmap ( raster *rp, FILE *fp, i
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
int ibyte, nbytes=pixmapsz(rp); /* #bytes in raster */ |
int ibyte, /* pixmap[ibyte] index */ |
|
nbytes = pixbytes(rp); /*#bytes in bitmap or .gf-formatted*/ |
char stub[64]=" ";/* col1 leading blanks */ |
char stub[64]=" ";/* col1 leading blanks */ |
int linewidth = 64, /* (roughly) rightmost column */ |
int linewidth = 64, /* (roughly) rightmost column */ |
colwidth = (isstr? 4:5); /* #cols required for each byte */ |
colwidth = (isstr? 4:5); /* #cols required for each byte */ |
Line 3000 return ( 1 );
|
Line 3210 return ( 1 );
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: gftobitmap ( gf ) |
|
* Purpose: convert .gf-like pixmap to bitmap image |
|
* -------------------------------------------------------------------------- |
|
* Arguments: gf (I) raster * to struct in .gf-format |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( raster * ) image-format raster * if successful, |
|
* or NULL for any error. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
raster *gftobitmap ( raster *gf ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
raster *new_raster(), *rp=NULL; /* image raster retuned to caller */ |
|
int width=0, height=0, totbits=0; /* gf->width, gf->height, #bits */ |
|
int format=0, icount=0, ncounts=0, /*.gf format, count index, #counts*/ |
|
ibit=0, bitval=0; /* bitmap index, bit value */ |
|
int isrepeat = 1, /* true to process repeat counts */ |
|
repeatcmds[2] = {255,15}, /*opcode for repeat/duplicate count*/ |
|
nrepeats=0, irepeat=0, /* scan line repeat count,index */ |
|
wbits = 0; /* count bits to width of scan line*/ |
|
/* ------------------------------------------------------------------------- |
|
initialization |
|
-------------------------------------------------------------------------- */ |
|
/* --- check args --- */ |
|
if ( gf == NULL ) goto end_of_job; /* input raster not provided */ |
|
format = gf->format; /* 2 or 3 */ |
|
if ( format!=2 && format!=3 ) goto end_of_job; /* invalid raster format */ |
|
ncounts = gf->pixsz; /*pixsz is really #counts in pixmap*/ |
|
/* --- allocate output raster with proper dimensions for bitmap --- */ |
|
width=gf->width; height=gf->height; /* dimensions of raster */ |
|
if ( (rp = new_raster(width,height,1)) /* allocate new raster and bitmap */ |
|
== NULL ) goto end_of_job; /* quit if failed to allocate */ |
|
totbits = width*height; /* total #bits in image */ |
|
/* ------------------------------------------------------------------------- |
|
fill bitmap |
|
-------------------------------------------------------------------------- */ |
|
for ( icount=0,bitval=0; icount<ncounts; icount++ ) |
|
{ |
|
int nbits = (int)(getbyfmt(format,gf->pixmap,icount)); /*#bits to set*/ |
|
if ( isrepeat /* we're proxessing repeat counts */ |
|
&& nbits == repeatcmds[format-2] ) /* and repeat opcode found */ |
|
if ( nrepeats == 0 ) /* recursive repeat is error */ |
|
{ nrepeats = (int)(getbyfmt(format,gf->pixmap,icount+1));/*repeat count*/ |
|
nbits = (int)(getbyfmt(format,gf->pixmap,icount+2)); /*#bits to set*/ |
|
icount += 2; } /* bump byte/nibble count */ |
|
else /* some internal error occurred */ |
|
if ( msgfp!=NULL && msglevel>=1 ) /* report error */ |
|
fprintf(msgfp,"gftobitmap> found embedded repeat command\n"); |
|
if ( 0 ) |
|
fprintf(stdout, |
|
"gftobitmap> icount=%d bitval=%d nbits=%d ibit=%d totbits=%d\n", |
|
icount,bitval,nbits,ibit,totbits); |
|
for ( ; nbits>0; nbits-- ) /* count down */ |
|
{ if ( ibit >= totbits ) goto end_of_job; /* overflow check */ |
|
for ( irepeat=0; irepeat<=nrepeats; irepeat++ ) |
|
if ( bitval == 1 ) /* set pixel */ |
|
{ setlongbit(rp->pixmap,(ibit+irepeat*width)); } |
|
else /* clear pixel */ |
|
{ unsetlongbit(rp->pixmap,(ibit+irepeat*width)); } |
|
if ( nrepeats > 0 ) wbits++; /* count another repeated bit */ |
|
ibit++; } /* bump bit index */ |
|
bitval = 1-bitval; /* flip bit value */ |
|
if ( wbits >= width ) { /* completed repeats */ |
|
ibit += nrepeats*width; /*bump bit count past repeated scans*/ |
|
if ( wbits > width ) /* out-of alignment error */ |
|
if ( msgfp!=NULL && msglevel>=1 ) /* report error */ |
|
fprintf(msgfp,"gftobitmap> width=%d wbits=%d\n",width,wbits); |
|
wbits = nrepeats = 0; } /* reset repeat counts */ |
|
} /* --- end-of-for(icount) --- */ |
|
end_of_job: |
|
return ( rp ); /* back to caller with image */ |
|
} /* --- end-of-function gftobitmap() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: get_symdef ( symbol ) |
* Function: get_symdef ( symbol ) |
* Purpose: returns mathchardef struct for symbol |
* Purpose: returns mathchardef struct for symbol |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 3030 int symlen = strlen(symbol), /* length o
|
Line 3319 int symlen = strlen(symbol), /* length o
|
deflen, minlen=9999; /*length of shortest matching symdef*/ |
deflen, minlen=9999; /*length of shortest matching symdef*/ |
int /*alnumsym = (symlen==1 && isalnum(*symbol)),*/ /*alphanumeric sym*/ |
int /*alnumsym = (symlen==1 && isalnum(*symbol)),*/ /*alphanumeric sym*/ |
alphasym = (symlen==1 && isalpha(*symbol)); /* or alpha symbol */ |
alphasym = (symlen==1 && isalpha(*symbol)); /* or alpha symbol */ |
|
int family = fontinfo[fontnum].family; /* current font family */ |
static char *displaysyms[][2] = { /*xlate to Big sym for \displaystyle*/ |
static char *displaysyms[][2] = { /*xlate to Big sym for \displaystyle*/ |
|
/* --- see table on page 536 in TLC2 --- */ |
{"\\int", "\\Bigint"}, |
{"\\int", "\\Bigint"}, |
{"\\oint", "\\Bigoint"}, |
{"\\oint", "\\Bigoint"}, |
{"\\sum", "\\Bigsum"}, |
{"\\sum", "\\Bigsum"}, |
{"\\prod", "\\Bigprod"}, |
{"\\prod", "\\Bigprod"}, |
{"\\coprod", "\\Bigcoprod"}, |
{"\\coprod", "\\Bigcoprod"}, |
{"\\cup", "\\Bigcup"}, |
/* --- must be 'big' when related to similar binary operators --- */ |
{"\\sqcup", "\\Bigsqcup"}, |
{"\\bigcup", "\\Bigcup"}, |
{"\\cap", "\\Bigcap"}, |
{"\\bigsqcup", "\\Bigsqcup"}, |
{"\\sqcap", "\\sqcap"}, /* don't have \Bigsqcap */ |
{"\\bigcap", "\\Bigcap"}, |
{"\\odot", "\\Bigodot"}, |
/*{"\\bigsqcap", "\\sqcap"},*/ /* don't have \Bigsqcap */ |
{"\\oplus", "\\Bigoplus"}, |
{"\\bigodot", "\\Bigodot"}, |
{"\\otimes", "\\Bigotimes"}, |
{"\\bigoplus", "\\Bigoplus"}, |
{"\\uplus", "\\Biguplus"}, |
{"\\bigominus", "\\ominus"}, |
{"\\wedge", "\\Bigwedge"}, |
{"\\bigotimes", "\\Bigotimes"}, |
{"\\vee", "\\Bigvee"}, |
{"\\bigoslash", "\\oslash"}, |
|
{"\\biguplus", "\\Biguplus"}, |
|
{"\\bigwedge", "\\Bigwedge"}, |
|
{"\\bigvee", "\\Bigvee"}, |
{NULL, NULL} }; |
{NULL, NULL} }; |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
If in \displaystyle mode, first xlate int to Bigint, etc. |
If in \displaystyle mode, first xlate int to Bigint, etc. |
Line 3070 for ( idef=0; ;idef++ ) /* until trail
|
Line 3364 for ( idef=0; ;idef++ ) /* until trail
|
if ( symdefs[idef].symbol == NULL ) break; /* reached end-of-table */ |
if ( symdefs[idef].symbol == NULL ) break; /* reached end-of-table */ |
else /* check against caller's symbol */ |
else /* check against caller's symbol */ |
if ( strncmp(symbol,symdefs[idef].symbol,symlen) == 0 ) /* found match */ |
if ( strncmp(symbol,symdefs[idef].symbol,symlen) == 0 ) /* found match */ |
if ( symdefs[idef].handler != NULL /* mode irrelevant for directives */ |
if (fontnum==0 /* mathmode, so check every match */ |
|| istext==0 /* mathmode, so use first match */ |
|| (0 && istextmode && (!alphasym /* text mode and not alpha symbol */ |
|| (istext==1 && symdefs[idef].family==CMR10) /*textmode && rm text*/ |
|| symdefs[idef].handler!=NULL)) /* or text mode and directive */ |
|| (istext==2 && symdefs[idef].family==CMMI10) /*textmode && it text*/ |
|| (symdefs[idef].family==family /* have correct family */ |
|| (istext==3 && symdefs[idef].family==BBOLD10) /*textmode && bb text*/ |
&& symdefs[idef].handler==NULL) ) /* and not a handler collision */ |
|| (istext!=3 && !alphasym) ) /* not bb and not alpha */ |
#if 0 |
|
|| (fontnum==1 && symdefs[idef].family==CMR10) /*textmode && rm text*/ |
|
|| (fontnum==2 && symdefs[idef].family==CMMI10) /*textmode && it text*/ |
|
|| (fontnum==3 && symdefs[idef].family==BBOLD10 /*textmode && bb text*/ |
|
&& symdefs[idef].handler==NULL) |
|
|| (fontnum==4 && symdefs[idef].family==CMMIB10 /*textmode && bf text*/ |
|
&& symdefs[idef].handler==NULL) ) |
|
#endif |
if ( (deflen=strlen(symdefs[idef].symbol)) < minlen ) /*new best match*/ |
if ( (deflen=strlen(symdefs[idef].symbol)) < minlen ) /*new best match*/ |
{ bestdef = idef; /* save index of new best match */ |
{ bestdef = idef; /* save index of new best match */ |
if ( (minlen = deflen) /* and save its len for next test */ |
if ( (minlen = deflen) /* and save its len for next test */ |
== symlen ) break; } /*perfect match, so return with it*/ |
== symlen ) break; } /*perfect match, so return with it*/ |
if ( bestdef < 0 ) /* failed to look up symbol */ |
if ( bestdef < 0 ) /* failed to look up symbol */ |
if ( istext != 0 ) /* we're in a restricted font mode */ |
if ( fontnum != 0 ) /* we're in a restricted font mode */ |
{ int wastext = istext; /* save current mode */ |
{ int oldfontnum = fontnum; /* save current font family */ |
mathchardef *symdef = NULL; /* lookup result with istext=0 */ |
mathchardef *symdef = NULL; /* lookup result with fontnum=0 */ |
istext = 0; /*try to look up symbol in any font*/ |
fontnum = 0; /*try to look up symbol in any font*/ |
symdef = get_symdef(symbol); /* repeat lookup with istext=0 */ |
symdef = get_symdef(symbol); /* repeat lookup with fontnum=0 */ |
istext = wastext; /* reset font mode */ |
fontnum = oldfontnum; /* reset font family */ |
return symdef; } /* caller gets istext=0 lookup */ |
return symdef; } /* caller gets fontnum=0 lookup */ |
if ( msgfp!=NULL && msglevel>=999 ) /* debugging output */ |
if ( msgfp!=NULL && msglevel>=999 ) /* debugging output */ |
{ fprintf(msgfp,"get_symdefs> symbol=%s matches symtable[%d]=%s\n", |
{ fprintf(msgfp,"get_symdef> symbol=%s matches symtable[%d]=%s\n", |
symbol,bestdef,(bestdef<0?"NotFound":symdefs[bestdef].symbol)); |
symbol,bestdef,(bestdef<0?"NotFound":symdefs[bestdef].symbol)); |
fflush(msgfp); } |
fflush(msgfp); } |
return ( (bestdef<0? NULL : &(symdefs[bestdef])) ); /*NULL or best symdef[]*/ |
return ( (bestdef<0? NULL : &(symdefs[bestdef])) ); /*NULL or best symdef[]*/ |
Line 3102 return ( (bestdef<0? NULL : &(symdefs[be
|
Line 3403 return ( (bestdef<0? NULL : &(symdefs[be
|
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: symdef (I) mathchardef * corresponding to symbol |
* Arguments: symdef (I) mathchardef * corresponding to symbol |
* whose corresponding chardef is wanted |
* whose corresponding chardef is wanted |
* size (I) int containing 0-4 for desired size |
* size (I) int containing 0-5 for desired size |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Returns: ( chardef * ) pointer to struct defining symbol at size, |
* Returns: ( chardef * ) pointer to struct defining symbol at size, |
* or NULL for any error |
* or NULL for any error |
Line 3197 return ( gfdata ); /*ptr to chardef fo
|
Line 3498 return ( gfdata ); /*ptr to chardef fo
|
* Purpose: returns new subraster ptr containing |
* Purpose: returns new subraster ptr containing |
* data for symdef at given size |
* data for symdef at given size |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: symdef (I) mathchardef * corresponding to symbol |
* Arguments: symdef (I) mathchardef * corresponding to symbol whose |
* whose corresponding chardef is wanted |
* corresponding chardef subraster is wanted |
* size (I) int containing 0-4 for desired size |
* size (I) int containing 0-5 for desired size |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Returns: ( subraster * ) pointer to struct defining symbol at size, |
* Returns: ( subraster * ) pointer to struct defining symbol at size, |
* or NULL for any error |
* or NULL for any error |
Line 3215 Allocations and Declarations
|
Line 3516 Allocations and Declarations
|
chardef *get_chardef(), *gfdata=NULL; /* chardef struct for symdef,size */ |
chardef *get_chardef(), *gfdata=NULL; /* chardef struct for symdef,size */ |
int get_baseline(); /* baseline of gfdata */ |
int get_baseline(); /* baseline of gfdata */ |
subraster *new_subraster(), *sp=NULL; /* subraster containing gfdata */ |
subraster *new_subraster(), *sp=NULL; /* subraster containing gfdata */ |
|
raster *bitmaprp=NULL, *gftobitmap(); /* convert .gf-format to bitmap */ |
|
int delete_subraster(); /* in case gftobitmap() fails */ |
int aasupsamp(), /*antialias char with supersampling*/ |
int aasupsamp(), /*antialias char with supersampling*/ |
grayscale=256; /* aasupersamp() parameters */ |
grayscale=256; /* aasupersamp() parameters */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 3225 if ( (gfdata=get_chardef(symdef,size)) /
|
Line 3528 if ( (gfdata=get_chardef(symdef,size)) /
|
if ( (sp=new_subraster(0,0,0)) /* allocate subraster "envelope" */ |
if ( (sp=new_subraster(0,0,0)) /* allocate subraster "envelope" */ |
!= NULL ) /* and check that we succeeded */ |
!= NULL ) /* and check that we succeeded */ |
{ |
{ |
sp->type = CHARASTER; /* static character raster */ |
raster *image = &(gfdata->image); /* ptr to chardef's bitmap or .gf */ |
|
int format = image->format; /* 1=bitmap, else .gf */ |
sp->symdef = symdef; /* replace NULL with caller's arg */ |
sp->symdef = symdef; /* replace NULL with caller's arg */ |
sp->size = size; /*replace default with caller's size*/ |
sp->size = size; /*replace default with caller's size*/ |
sp->baseline = get_baseline(gfdata); /* get baseline of character */ |
sp->baseline = get_baseline(gfdata); /* get baseline of character */ |
sp->image = &(gfdata->image); /* store ptr to its bitmap */ |
if ( format == 1 ) /* already a bitmap */ |
|
{ sp->type = CHARASTER; /* static char raster */ |
|
sp->image = image; } /* store ptr to its bitmap */ |
|
else /* need to convert .gf-to-bitmap */ |
|
if ( (bitmaprp = gftobitmap(image)) /* convert */ |
|
!= (raster *)NULL ) /* successful */ |
|
{ sp->type = IMAGERASTER; /* allocated raster will be freed */ |
|
sp->image = bitmaprp; } /* store ptr to converted bitmap */ |
|
else /* conversion failed */ |
|
{ delete_subraster(sp); /* free unneeded subraster */ |
|
sp = (subraster *)NULL; /* signal error to caller */ |
|
goto end_of_job; } /* quit */ |
if ( issupersampling ) /* antialias character right here */ |
if ( issupersampling ) /* antialias character right here */ |
{ |
{ |
raster *aa = NULL; /* antialiased char raster */ |
raster *aa = NULL; /* antialiased char raster */ |
Line 3245 if ( (gfdata=get_chardef(symdef,size)) /
|
Line 3560 if ( (gfdata=get_chardef(symdef,size)) /
|
sp->type = IMAGERASTER; } /* character is an image raster */ |
sp->type = IMAGERASTER; } /* character is an image raster */ |
} /* --- end-of-if(issupersampling) --- */ |
} /* --- end-of-if(issupersampling) --- */ |
} /* --- end-of-if(sp!=NULL) --- */ |
} /* --- end-of-if(sp!=NULL) --- */ |
if ( msgfp!=NULL && msglevel>=999 ) |
end_of_job: |
|
if ( msgfp!=NULL && msglevel>=999 ) |
{ fprintf(msgfp,"get_charsubraster> requested symbol=\"%s\" baseline=%d\n", |
{ fprintf(msgfp,"get_charsubraster> requested symbol=\"%s\" baseline=%d\n", |
symdef->symbol, (sp==NULL?0:sp->baseline)); fflush(msgfp); } |
symdef->symbol, (sp==NULL?0:sp->baseline)); fflush(msgfp); } |
return ( sp ); /* back to caller */ |
return ( sp ); /* back to caller */ |
Line 3253 return ( sp ); /* back to caller */
|
Line 3569 return ( sp ); /* back to caller */
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: get_symsubraster ( symbol, size ) |
|
* Purpose: returns new subraster ptr containing |
|
* data for symbol at given size |
|
* -------------------------------------------------------------------------- |
|
* Arguments: symbol (I) char * corresponding to symbol |
|
* whose corresponding subraster is wanted |
|
* size (I) int containing 0-5 for desired size |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( subraster * ) pointer to struct defining symbol at size, |
|
* or NULL for any error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o just combines get_symdef() and get_charsubraster() |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
subraster *get_symsubraster ( char *symbol, int size ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
subraster *sp=NULL, *get_charsubraster(); /* subraster containing gfdata */ |
|
mathchardef *symdef=NULL, *get_symdef(); /* mathchardef lookup for symbol */ |
|
/* ------------------------------------------------------------------------- |
|
look up mathchardef for symbol |
|
-------------------------------------------------------------------------- */ |
|
if ( symbol != NULL ) /* user supplied input symbol */ |
|
symdef = get_symdef(symbol); /*look up corresponding mathchardef*/ |
|
/* ------------------------------------------------------------------------- |
|
look up chardef for mathchardef and wrap a subraster structure around data |
|
-------------------------------------------------------------------------- */ |
|
if ( symdef != NULL ) /* lookup succeeded */ |
|
sp = get_charsubraster(symdef,size); /* so get symbol data in subraster */ |
|
return ( sp ); /* back to caller with sp or NULL */ |
|
} /* --- end-of-function get_symsubraster() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: get_baseline ( gfdata ) |
* Function: get_baseline ( gfdata ) |
* Purpose: returns baseline for a chardef struct |
* Purpose: returns baseline for a chardef struct |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 3367 for ( idef=0; ;idef++ ) /* until trail
|
Line 3719 for ( idef=0; ;idef++ ) /* until trail
|
if ( defsym == NULL ) break; /* reached end-of-table */ |
if ( defsym == NULL ) break; /* reached end-of-table */ |
else /* check against caller's symbol */ |
else /* check against caller's symbol */ |
if ( family<0 || deffam == family /* if explicitly in caller's family*/ |
if ( family<0 || deffam == family /* if explicitly in caller's family*/ |
|| (family==CMSYEX && (deffam==CMSY10||deffam==CMEX10)) ) |
|| (family==CMSYEX && (deffam==CMSY10||deffam==CMEX10||deffam==STMARY10)) ) |
{ |
{ |
strcpy(lcsymbol,defsym); /* local copy of symdefs[] symbol */ |
strcpy(lcsymbol,defsym); /* local copy of symdefs[] symbol */ |
if ( isunesc && *lcsymbol=='\\' ) /* ignored leading \ in symbol */ |
if ( isunesc && *lcsymbol=='\\' ) /* ignored leading \ in symbol */ |
Line 3404 construct subraster for best fit charact
|
Line 3756 construct subraster for best fit charact
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( bestdef >= 0 ) /* found a best fit for caller */ |
if ( bestdef >= 0 ) /* found a best fit for caller */ |
sp = get_charsubraster(&(symdefs[bestdef]),bestsize); /* best subraster */ |
sp = get_charsubraster(&(symdefs[bestdef]),bestsize); /* best subraster */ |
if ( sp==NULL && height-bigheight>5 ) /* try to construct delim */ |
if ( (sp==NULL && height-bigheight>5) /* try to construct delim */ |
|
|| bigdef < 0 ) /* delim not in font tables */ |
sp = make_delim(symbol,(iswidth?-height:height)); /* try to build delim */ |
sp = make_delim(symbol,(iswidth?-height:height)); /* try to build delim */ |
if ( sp==NULL && bigdef>=0 ) /* just give biggest to caller */ |
if ( sp==NULL && bigdef>=0 ) /* just give biggest to caller */ |
sp = get_charsubraster(&(symdefs[bigdef]),bigsize); /* biggest subraster */ |
sp = get_charsubraster(&(symdefs[bigdef]),bigsize); /* biggest subraster */ |
|
if ( msgfp!=NULL && msglevel>=99 ) |
|
fprintf(msgfp,"get_delim> symbol=%.50s, height=%d family=%d isokay=%s\n", |
|
(symbol==NULL?"null":symbol),height,family,(sp==NULL?"fail":"success")); |
return ( sp ); |
return ( sp ); |
} /* --- end-of-function get_delim() --- */ |
} /* --- end-of-function get_delim() --- */ |
|
|
Line 3436 Allocations and Declarations
|
Line 3792 Allocations and Declarations
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
subraster *sp = (subraster *)NULL, /* subraster returned to caller */ |
subraster *sp = (subraster *)NULL, /* subraster returned to caller */ |
*new_subraster(); /* allocate subraster */ |
*new_subraster(); /* allocate subraster */ |
|
subraster *get_symsubraster(), /* look up delim pieces in cmex10 */ |
|
*symtop=NULL, *symbot=NULL, *symmid=NULL, *symbar=NULL, /* pieces */ |
|
*topsym=NULL, *botsym=NULL, *midsym=NULL, *barsym=NULL, /* +filler */ |
|
*rastack(), *rastcat(); /* stack pieces, concat filler */ |
|
int isdrawparen = 0; /*1=draw paren, 0=build from pieces*/ |
raster *rasp = (raster *)NULL; /* sp->image */ |
raster *rasp = (raster *)NULL; /* sp->image */ |
int isokay=0, delete_subraster(); /* set true if delimiter drawn ok */ |
int isokay=0, delete_subraster(); /* set true if delimiter drawn ok */ |
int pixsz = 1; /* pixels are one bit each */ |
int pixsz = 1, /* pixels are one bit each */ |
|
symsize = 0; /* size arg for get_symsubraster() */ |
int thickness = 1; /* drawn lines are one pixel thick */ |
int thickness = 1; /* drawn lines are one pixel thick */ |
int aspectratio = 8; /* default height/width for parens */ |
int aspectratio = 8; /* default height/width for parens */ |
int iswidth = 0, /*true if width specified by height*/ |
int iswidth = 0, /*true if width specified by height*/ |
width = height; /* #pixels width (e.g., of ellipse)*/ |
width = height; /* #pixels width (e.g., of ellipse)*/ |
char *lp=NULL, *rp=NULL, *strchr(), /* check symbol for left or right */ |
char *lp=NULL, *rp=NULL, /* check symbol for left or right */ |
*lp2=NULL, *rp2=NULL; /* synonym for lp,rp */ |
*lp2=NULL, *rp2=NULL, /* synonym for lp,rp */ |
|
*lp3=NULL, *rp3=NULL, /* synonym for lp,rp */ |
|
*lp4=NULL, *rp4=NULL; /* synonym for lp,rp */ |
int circle_raster(), /* ellipse for ()'s in sp->image */ |
int circle_raster(), /* ellipse for ()'s in sp->image */ |
rule_rsater(), /* horizontal or vertical lines */ |
rule_rsater(), /* horizontal or vertical lines */ |
line_raster(); /* line between two points */ |
line_raster(); /* line between two points */ |
|
subraster *uparrow_subraster(); /* up/down arrows */ |
|
int isprealloc = 1; /*pre-alloc subraster, except arrow*/ |
|
int oldsmashmargin = smashmargin, /* save original smashmargin */ |
|
wascatspace = iscatspace; /* save original iscatspace */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 3460 if ( height < 3 ) goto end_of_job; /* to
|
Line 3828 if ( height < 3 ) goto end_of_job; /* to
|
if ( iswidth ) height = (width+(aspectratio+1)/2)/aspectratio; |
if ( iswidth ) height = (width+(aspectratio+1)/2)/aspectratio; |
else width = (height+(aspectratio+1)/2)/aspectratio; |
else width = (height+(aspectratio+1)/2)/aspectratio; |
if ( strchr(symbol,'=') != NULL /* left or right || bracket wanted */ |
if ( strchr(symbol,'=') != NULL /* left or right || bracket wanted */ |
|| strstr(symbol,"\\|") != NULL ) /* same || in standard tex notation*/ |
|| strstr(symbol,"\\|") != NULL /* same || in standard tex notation*/ |
width = max2(width,5); /* need space between two |'s */ |
|| strstr(symbol,"dbl") != NULL ) /* semantic bracket with ||'s */ |
|
width = max2(width,6); /* need space between two |'s */ |
if ( width < 2 ) width=2; /* set min width */ |
if ( width < 2 ) width=2; /* set min width */ |
if ( strchr(symbol,'(') != NULL /* if left ( */ |
if ( strchr(symbol,'(') != NULL /* if left ( */ |
|| strchr(symbol,')') != NULL ) /* or right ) paren wanted */ |
|| strchr(symbol,')') != NULL ) /* or right ) paren wanted */ |
width = (3*width)/2; /* adjust width */ |
{ width = (3*width)/2; /* adjust width */ |
|
if ( !isdrawparen ) isprealloc=0; } /* don't prealloc if building */ |
|
if ( strchr(symbol,'/') != NULL /* left / */ |
|
|| strstr(symbol,"\\\\") != NULL /* or \\ for right \ */ |
|
|| strstr(symbol,"backsl") != NULL ) /* or \backslash for \ */ |
|
width = max2(height/3,5); |
|
if ( strstr(symbol,"arrow") != NULL ) /* arrow wanted */ |
|
{ width = min2(height/3,20); /* adjust width */ |
|
isprealloc = 0; } /* don't preallocate subraster */ |
|
if ( strchr(symbol,'{') != NULL /* if left { */ |
|
|| strchr(symbol,'}') != NULL ) /* or right } brace wanted */ |
|
{ isprealloc = 0; } /* don't preallocate */ |
/* --- allocate and initialize subraster for constructed delimiter --- */ |
/* --- allocate and initialize subraster for constructed delimiter --- */ |
if ( (sp=new_subraster(width,height,pixsz)) /* allocate new subraster */ |
if ( isprealloc ) /* pre-allocation wanted */ |
== NULL ) goto end_of_job; /* quit if failed */ |
{ if ( (sp=new_subraster(width,height,pixsz)) /* allocate new subraster */ |
/* --- initialize delimiter subraster parameters --- */ |
== NULL ) goto end_of_job; /* quit if failed */ |
sp->type = IMAGERASTER; /* image */ |
/* --- initialize delimiter subraster parameters --- */ |
sp->symdef = NULL; /* not applicable for image */ |
sp->type = IMAGERASTER; /* image */ |
sp->baseline = height/2 + 2; /* is a little above center good? */ |
sp->symdef = NULL; /* not applicable for image */ |
sp->size = NORMALSIZE; /* size (probably unneeded) */ |
sp->baseline = height/2 + 2; /* is a little above center good? */ |
rasp = sp->image; /* pointer to image in subraster */ |
sp->size = NORMALSIZE; /* size (probably unneeded) */ |
|
rasp = sp->image; } /* pointer to image in subraster */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
( ) parens |
( ) parens |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( (lp=strchr(symbol,'(')) != NULL /* left ( paren wanted */ |
if ( (lp=strchr(symbol,'(')) != NULL /* left ( paren wanted */ |
|| (rp=strchr(symbol,')')) != NULL ) /* right ) paren wanted */ |
|| (rp=strchr(symbol,')')) != NULL ) /* right ) paren wanted */ |
{ |
{ |
int mywidth = min2(width,20); /* max width for ()'s */ |
if ( isdrawparen ) { /* draw the paren */ |
circle_raster ( rasp, /* embedded raster image */ |
int mywidth = min2(width,20); /* max width for ()'s */ |
|
circle_raster ( rasp, /* embedded raster image */ |
0, 0, /* row0,col0 are upper-left corner */ |
0, 0, /* row0,col0 are upper-left corner */ |
height-1, mywidth-1, /* row1,col1 are lower-right */ |
height-1, mywidth-1, /* row1,col1 are lower-right */ |
thickness, /* line thickness is 1 pixel */ |
thickness, /* line thickness is 1 pixel */ |
(rp==NULL?"23":"41") ); /* "1234" quadrants to be drawn */ |
(rp==NULL?"23":"41") ); /* "1234" quadrants to be drawn */ |
isokay = 1; /* set flag */ |
isokay = 1; } /* set flag */ |
|
else { |
|
int isleft = (lp!=NULL?1:0); /* true for left, false for right */ |
|
char *parentop = (isleft?"\\leftparentop":"\\rightparentop"), |
|
*parenbot = (isleft?"\\leftparenbot":"\\rightparenbot"), |
|
*parenbar = (isleft?"\\leftparenbar":"\\rightparenbar"); |
|
int baseht=0, barht=0, /* height of base=top+bot, bar */ |
|
ibar=0, nbars=0; /* bar index, #bars between top&bot*/ |
|
int largestsize = min2(2,LARGESTSIZE), /* largest size for parens */ |
|
topfill=(isleft?0:0), botfill=(isleft?0:0), |
|
barfill=(isleft?0:7); /* alignment fillers */ |
|
/* --- get pieces at largest size smaller than total height --- */ |
|
for ( symsize=largestsize; symsize>=0; symsize-- ) /*largest to smallest*/ |
|
{ |
|
/* --- get pieces at current test size --- */ |
|
isokay = 1; /* check for all pieces */ |
|
if ( (symtop=get_symsubraster(parentop,symsize)) == NULL ) isokay=0; |
|
if ( (symbot=get_symsubraster(parenbot,symsize)) == NULL ) isokay=0; |
|
if ( (symbar=get_symsubraster(parenbar,symsize)) == NULL ) isokay=0; |
|
/* --- check sum of pieces against total desired height --- */ |
|
if ( isokay ) { /* all pieces retrieved */ |
|
baseht = (symtop->image)->height + (symbot->image)->height; /*top+bot*/ |
|
barht = (symbar->image)->height; /* bar height */ |
|
if ( baseht < height+5 ) break; /* largest base that's not too big */ |
|
if ( symsize < 1 ) break; /* or smallest available base */ |
|
} /* --- end-of-if(isokay) --- */ |
|
/* --- free test pieces that were too big --- */ |
|
if ( symtop != NULL ) delete_subraster(symtop); /* free top */ |
|
if ( symbot != NULL ) delete_subraster(symbot); /* free bot */ |
|
if ( symbar != NULL ) delete_subraster(symbar); /* free bar */ |
|
isokay = 0; /* nothing available */ |
|
if ( symsize < 1 ) break; /* leave isokay=0 after smallest */ |
|
} /* --- end-of-for(symsize) --- */ |
|
/* --- construct brace from pieces --- */ |
|
if ( isokay ) { /* we have the pieces */ |
|
/* --- add alignment fillers --- */ |
|
smashmargin = iscatspace = 0; /*turn off rastcat smashing,space*/ |
|
topsym = (topfill>0?rastcat(new_subraster(topfill,1,1),symtop,3):symtop); |
|
botsym = (botfill>0?rastcat(new_subraster(botfill,1,1),symbot,3):symbot); |
|
barsym = (barfill>0?rastcat(new_subraster(barfill,1,1),symbar,3):symbar); |
|
smashmargin = oldsmashmargin; /* reset smashmargin */ |
|
iscatspace = wascatspace; /* reset iscatspace */ |
|
/* --- #bars needed between top and bot --- */ |
|
nbars = (barht<1?0:max2(0,1+(height-baseht)/barht)); /* #bars needed */ |
|
/* --- stack pieces --- */ |
|
sp = topsym; /* start with top piece */ |
|
if ( nbars > 0 ) /* need nbars between top and bot */ |
|
for ( ibar=1; ibar<=nbars; ibar++ ) sp = rastack(barsym,sp,1,0,0,2); |
|
sp = rastack(botsym,sp,1,0,0,3); /* bottom below bars or middle */ |
|
delete_subraster(barsym); /* barsym no longer needed */ |
|
} /* --- end-of-if(isokay) --- */ |
|
} /* --- end-of-if/else(isdrawparen) --- */ |
} /* --- end-of-if(left- or right-() paren wanted) --- */ |
} /* --- end-of-if(left- or right-() paren wanted) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
|
{ } braces |
|
-------------------------------------------------------------------------- */ |
|
else |
|
if ( (lp=strchr(symbol,'{')) != NULL /* left { brace wanted */ |
|
|| (rp=strchr(symbol,'}')) != NULL ) /* right } brace wanted */ |
|
{ |
|
int isleft = (lp!=NULL?1:0); /* true for left, false for right */ |
|
char *bracetop = (isleft?"\\leftbracetop":"\\rightbracetop"), |
|
*bracebot = (isleft?"\\leftbracebot":"\\rightbracebot"), |
|
*bracemid = (isleft?"\\leftbracemid":"\\rightbracemid"), |
|
*bracebar = (isleft?"\\leftbracebar":"\\rightbracebar"); |
|
int baseht=0, barht=0, /* height of base=top+bot+mid, bar */ |
|
ibar=0, nbars=0; /* bar index, #bars above,below mid*/ |
|
int largestsize = min2(2,LARGESTSIZE), /* largest size for braces */ |
|
topfill=(isleft?4:0), botfill=(isleft?4:0), |
|
midfill=(isleft?0:4), barfill=(isleft?4:4); /* alignment fillers */ |
|
/* --- get pieces at largest size smaller than total height --- */ |
|
for ( symsize=largestsize; symsize>=0; symsize-- ) /*largest to smallest*/ |
|
{ |
|
/* --- get pieces at current test size --- */ |
|
isokay = 1; /* check for all pieces */ |
|
if ( (symtop=get_symsubraster(bracetop,symsize)) == NULL ) isokay=0; |
|
if ( (symbot=get_symsubraster(bracebot,symsize)) == NULL ) isokay=0; |
|
if ( (symmid=get_symsubraster(bracemid,symsize)) == NULL ) isokay=0; |
|
if ( (symbar=get_symsubraster(bracebar,symsize)) == NULL ) isokay=0; |
|
/* --- check sum of pieces against total desired height --- */ |
|
if ( isokay ) { /* all pieces retrieved */ |
|
baseht = (symtop->image)->height + (symbot->image)->height |
|
+ (symmid->image)->height; /* top+bot+mid height */ |
|
barht = (symbar->image)->height; /* bar height */ |
|
if ( baseht < height+5 ) break; /* largest base that's not too big */ |
|
if ( symsize < 1 ) break; /* or smallest available base */ |
|
} /* --- end-of-if(isokay) --- */ |
|
/* --- free test pieces that were too big --- */ |
|
if ( symtop != NULL ) delete_subraster(symtop); /* free top */ |
|
if ( symbot != NULL ) delete_subraster(symbot); /* free bot */ |
|
if ( symmid != NULL ) delete_subraster(symmid); /* free mid */ |
|
if ( symbar != NULL ) delete_subraster(symbar); /* free bar */ |
|
isokay = 0; /* nothing available */ |
|
if ( symsize < 1 ) break; /* leave isokay=0 after smallest */ |
|
} /* --- end-of-for(symsize) --- */ |
|
/* --- construct brace from pieces --- */ |
|
if ( isokay ) { /* we have the pieces */ |
|
/* --- add alignment fillers --- */ |
|
smashmargin = iscatspace = 0; /*turn off rastcat smashing,space*/ |
|
topsym = (topfill>0?rastcat(new_subraster(topfill,1,1),symtop,3):symtop); |
|
botsym = (botfill>0?rastcat(new_subraster(botfill,1,1),symbot,3):symbot); |
|
midsym = (midfill>0?rastcat(new_subraster(midfill,1,1),symmid,3):symmid); |
|
barsym = (barfill>0?rastcat(new_subraster(barfill,1,1),symbar,3):symbar); |
|
smashmargin = oldsmashmargin; /* reset smashmargin */ |
|
iscatspace = wascatspace; /* reset iscatspace */ |
|
/* --- #bars needed on each side of mid piece --- */ |
|
nbars = (barht<1?0:max2(0,1+(height-baseht)/barht/2)); /*#bars per side*/ |
|
/* --- stack pieces --- */ |
|
sp = topsym; /* start with top piece */ |
|
if ( nbars > 0 ) /* need nbars above middle */ |
|
for ( ibar=1; ibar<=nbars; ibar++ ) sp = rastack(barsym,sp,1,0,0,2); |
|
sp = rastack(midsym,sp,1,0,0,3); /*mid after top or bars*/ |
|
if ( nbars > 0 ) /* need nbars below middle */ |
|
for ( ibar=1; ibar<=nbars; ibar++ ) sp = rastack(barsym,sp,1,0,0,2); |
|
sp = rastack(botsym,sp,1,0,0,3); /* bottom below bars or middle */ |
|
delete_subraster(barsym); /* barsym no longer needed */ |
|
} /* --- end-of-if(isokay) --- */ |
|
} /* --- end-of-if(left- or right-{} brace wanted) --- */ |
|
/* ------------------------------------------------------------------------- |
[ ] brackets |
[ ] brackets |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
else |
else |
if ( (lp=strchr(symbol,'[')) != NULL /* left [ bracket wanted */ |
if ( (lp=strchr(symbol,'[')) != NULL /* left [ bracket wanted */ |
|| (rp=strchr(symbol,']')) != NULL ) /* right ] bracket wanted */ |
|| (rp=strchr(symbol,']')) != NULL /* right ] bracket wanted */ |
{ |
|| (lp2=strstr(symbol,"lceil")) != NULL /* left ceiling wanted */ |
/* --- rule_raster ( rasp, top, left, width, height, type=0 ) --- */ |
|| (rp2=strstr(symbol,"rceil")) != NULL /* right ceiling wanted */ |
int mywidth = min2(width,12); /* max width for horizontal bars */ |
|| (lp3=strstr(symbol,"lfloor")) != NULL /* left floor wanted */ |
thickness = 1; /* set lines 1 or 2 pixels thick */ |
|| (rp3=strstr(symbol,"rfloor")) != NULL /* right floor wanted */ |
rule_raster(rasp, 0,0, mywidth,thickness, 0); /* top horizontal bar */ |
|| (lp4=strstr(symbol,"llbrack")) != NULL /* left semantic bracket */ |
rule_raster(rasp, height-thickness,0, mywidth,thickness, 0); /* bottom */ |
|| (rp4=strstr(symbol,"rrbrack")) != NULL ) /* right semantic bracket */ |
if ( lp != NULL ) /* left [ bracket wanted */ |
{ |
|
/* --- use rule_raster ( rasp, top, left, width, height, type=0 ) --- */ |
|
int mywidth = min2(width,12), /* max width for horizontal bars */ |
|
wthick = 1; /* thickness of top.bottom bars */ |
|
thickness = (height<25?1:2); /* set lines 1 or 2 pixels thick */ |
|
if ( lp2!=NULL || rp2!=NULL || lp3!=NULL || rp3 !=NULL ) /*ceil or floor*/ |
|
wthick = thickness; /* same thickness for top/bot bar */ |
|
if ( lp3==NULL && rp3==NULL ) /* set top bar if floor not wanted */ |
|
rule_raster(rasp, 0,0, mywidth,wthick, 0); /* top horizontal bar */ |
|
if ( lp2==NULL && rp2==NULL ) /* set bot bar if ceil not wanted */ |
|
rule_raster(rasp, height-wthick,0, mywidth,thickness, 0); /* bottom */ |
|
if ( lp!=NULL || lp2!=NULL || lp3!=NULL || lp4!=NULL ) /* left bracket */ |
rule_raster(rasp, 0,0, thickness,height, 0); /* left vertical bar */ |
rule_raster(rasp, 0,0, thickness,height, 0); /* left vertical bar */ |
if ( rp != NULL ) /* right ] bracket wanted */ |
if ( lp4 != NULL ) /* 2nd left vertical bar needed */ |
|
rule_raster(rasp, 0,thickness+1, 1,height, 0); /* 2nd left vertical bar */ |
|
if ( rp!=NULL || rp2!=NULL || rp3!=NULL || rp4!=NULL ) /* right bracket */ |
rule_raster(rasp, 0,mywidth-thickness, thickness,height, 0); /* right */ |
rule_raster(rasp, 0,mywidth-thickness, thickness,height, 0); /* right */ |
|
if ( rp4 != NULL ) /* 2nd right vertical bar needed */ |
|
rule_raster(rasp, 0,mywidth-thickness-2, 1,height, 0); /*2nd right vert*/ |
isokay = 1; /* set flag */ |
isokay = 1; /* set flag */ |
} /* --- end-of-if(left- or right-[] bracket wanted) --- */ |
} /* --- end-of-if(left- or right-[] bracket wanted) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 3514 else
|
Line 4027 else
|
if ( (lp=strchr(symbol,'<')) != NULL /* left < bracket wanted */ |
if ( (lp=strchr(symbol,'<')) != NULL /* left < bracket wanted */ |
|| (rp=strchr(symbol,'>')) != NULL ) /* right > bracket wanted */ |
|| (rp=strchr(symbol,'>')) != NULL ) /* right > bracket wanted */ |
{ |
{ |
/* --- line_raster ( rasp, row0, col0, row1, col1, thickness ) --- */ |
/* --- use line_raster( rasp, row0, col0, row1, col1, thickness ) --- */ |
int mywidth = min2(width,12); /* max width for brackets */ |
int mywidth = min2(width,12), /* max width for brackets */ |
thickness = 1; /* set line pixel thickness */ |
mythick = 1; /* all lines one pixel thick */ |
|
thickness = (height<25?1:2); /* set line pixel thickness */ |
if ( lp != NULL ) /* left < bracket wanted */ |
if ( lp != NULL ) /* left < bracket wanted */ |
{ line_raster(rasp,height/2,0,0,mywidth-1,thickness); |
{ line_raster(rasp,height/2,0,0,mywidth-1,mythick); |
line_raster(rasp,height/2,0,height-1,mywidth-1,thickness); } |
if ( thickness>1 ) |
|
line_raster(rasp,height/2,1,0,mywidth-1,mythick); |
|
line_raster(rasp,height/2,0,height-1,mywidth-1,mythick); |
|
if ( thickness>1 ) |
|
line_raster(rasp,height/2,1,height-1,mywidth-1,mythick); } |
if ( rp != NULL ) /* right > bracket wanted */ |
if ( rp != NULL ) /* right > bracket wanted */ |
{ line_raster(rasp,height/2,mywidth-1,0,0,thickness); |
{ line_raster(rasp,height/2,mywidth-1,0,0,mythick); |
line_raster(rasp,height/2,mywidth-1,height-1,0,thickness); } |
if ( thickness>1 ) |
|
line_raster(rasp,height/2,mywidth-2,0,0,mythick); |
|
line_raster(rasp,height/2,mywidth-1,height-1,0,mythick); |
|
if ( thickness>1 ) |
|
line_raster(rasp,height/2,mywidth-2,height-1,0,mythick); } |
isokay = 1; /* set flag */ |
isokay = 1; /* set flag */ |
} /* --- end-of-if(left- or right-<> bracket wanted) --- */ |
} /* --- end-of-if(left- or right-<> bracket wanted) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
|
/ \ delimiters |
|
-------------------------------------------------------------------------- */ |
|
else |
|
if ( (lp=strchr(symbol,'/')) != NULL /* left / wanted */ |
|
|| (rp=strstr(symbol,"\\\\")) != NULL /* right \ wanted */ |
|
|| (rp2=strstr(symbol,"backsl")) != NULL ) /* right \ wanted */ |
|
{ |
|
/* --- use line_raster( rasp, row0, col0, row1, col1, thickness ) --- */ |
|
int mywidth = width; /* max width for / \ */ |
|
thickness = 1; /* set line pixel thickness */ |
|
if ( lp != NULL ) /* left / wanted */ |
|
line_raster(rasp,0,mywidth-1,height-1,0,thickness); |
|
if ( rp!=NULL || rp2!=NULL ) /* right \ wanted */ |
|
line_raster(rasp,0,0,height-1,mywidth-1,thickness); |
|
isokay = 1; /* set flag */ |
|
} /* --- end-of-if(left- or right-/\ delimiter wanted) --- */ |
|
/* ------------------------------------------------------------------------- |
|
arrow delimiters |
|
-------------------------------------------------------------------------- */ |
|
else |
|
if ( strstr(symbol,"arrow") != NULL ) /* arrow delimiter wanted */ |
|
{ |
|
/* --- use uparrow_subraster(width,height,pixsz,drctn,isBig) --- */ |
|
int mywidth = width; /* max width for / \ */ |
|
int isBig = (strstr(symbol,"Up")!=NULL /* isBig if we have an Up */ |
|
|| strstr(symbol,"Down")!=NULL); /* or a Down */ |
|
int drctn = +1; /* init for uparrow */ |
|
if ( strstr(symbol,"down")!=NULL /* down if we have down */ |
|
|| strstr(symbol,"Down")!=NULL ) /* or Down */ |
|
{ drctn = (-1); /* reset direction to down */ |
|
if ( strstr(symbol,"up")!=NULL /* updown if we have up or Up */ |
|
|| strstr(symbol,"Up")!=NULL ) /* and down or Down */ |
|
drctn = 0; } /* reset direction to updown */ |
|
sp = uparrow_subraster(mywidth,height,pixsz,drctn,isBig); |
|
if ( sp != NULL ) |
|
{ sp->type = IMAGERASTER; /* image */ |
|
sp->symdef = NULL; /* not applicable for image */ |
|
sp->baseline = height/2 + 2; /* is a little above center good? */ |
|
sp->size = NORMALSIZE; /* size (probably unneeded) */ |
|
isokay = 1; } /* set flag */ |
|
} /* --- end-of-if(arrow delimiter wanted) --- */ |
|
/* ------------------------------------------------------------------------- |
\- for | | brackets or \= for || || brackets |
\- for | | brackets or \= for || || brackets |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
else |
else |
Line 3538 else
|
Line 4102 else
|
int midcol = width/2; /* middle col, left of mid if even */ |
int midcol = width/2; /* middle col, left of mid if even */ |
if ( rp != NULL /* left or right || bracket wanted */ |
if ( rp != NULL /* left or right || bracket wanted */ |
|| rp2 != NULL ) /* or || in standard tex notation */ |
|| rp2 != NULL ) /* or || in standard tex notation */ |
{ thickness = 1; /* each | of || one pixel thick */ |
{ thickness = (height<75?1:2); /* each | of || 1 or 2 pixels thick*/ |
rule_raster(rasp, 0,max2(0,midcol-2), thickness,height, 0); /* left */ |
rule_raster(rasp, 0,max2(0,midcol-2), thickness,height, 0); /* left */ |
rule_raster(rasp, 0,min2(width,midcol+2), thickness,height, 0); } |
rule_raster(rasp, 0,min2(width,midcol+2), thickness,height, 0); } |
else /*nb, lp2 spuriously set if rp2 set*/ |
else /*nb, lp2 spuriously set if rp2 set*/ |
if ( lp != NULL /* left or right | bracket wanted */ |
if ( lp != NULL /* left or right | bracket wanted */ |
|| lp2 != NULL ) /* ditto for synomym */ |
|| lp2 != NULL ) /* ditto for synomym */ |
{ thickness = 1; /* set | two pixels thick */ |
{ thickness = (height<75?1:2); /* set | 1 or 2 pixels thick */ |
rule_raster(rasp, 0,midcol, thickness,height, 0); } /*mid vertical bar*/ |
rule_raster(rasp, 0,midcol, thickness,height, 0); } /*mid vertical bar*/ |
isokay = 1; /* set flag */ |
isokay = 1; /* set flag */ |
} /* --- end-of-if(left- or right-[] bracket wanted) --- */ |
} /* --- end-of-if(left- or right-[] bracket wanted) --- */ |
Line 3552 else
|
Line 4116 else
|
back to caller |
back to caller |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
end_of_job: |
end_of_job: |
|
if ( msgfp!=NULL && msglevel>=99 ) |
|
fprintf(msgfp,"make_delim> symbol=%.50s, isokay=%d\n", |
|
(symbol==NULL?"null":symbol),isokay); |
if ( !isokay ) /* don't have requested delimiter */ |
if ( !isokay ) /* don't have requested delimiter */ |
{ delete_subraster(sp); /* so free unneeded structure */ |
{ if (sp!=NULL) delete_subraster(sp); /* so free unneeded structure */ |
sp = NULL; } /* and signal error to caller */ |
sp = NULL; } /* and signal error to caller */ |
return ( sp ); /*back to caller with delim or NULL*/ |
return ( sp ); /*back to caller with delim or NULL*/ |
} /* --- end-of-function make_delim() --- */ |
} /* --- end-of-function make_delim() --- */ |
Line 3639 if ( esclen < 1 ) /* \ followed by no
|
Line 4206 if ( esclen < 1 ) /* \ followed by no
|
*ptoken++ = *expression++; /*copy non-alpha, bump ptrs*/ |
*ptoken++ = *expression++; /*copy non-alpha, bump ptrs*/ |
else { /* normal alpha \sequence */ |
else { /* normal alpha \sequence */ |
/* --- respect spaces in text mode, except first space after \escape --- */ |
/* --- respect spaces in text mode, except first space after \escape --- */ |
if ( istext > 0 ) /* in \rm or \it text mode */ |
if ( istextmode ) /* in \rm or \it text mode */ |
if ( istext != 3 ) /* but not \mathbb */ |
if ( isthischar(*expression,WHITEDELIM) ) /* delim follows \sequence */ |
if ( isthischar(*expression,WHITEDELIM) ) /* delim follows \sequence */ |
expression++; } /* so flush delim */ |
expression++; } /* so flush delim */ |
|
*ptoken = '\000'; /* null-terminate token */ |
*ptoken = '\000'; /* null-terminate token */ |
/* --- back to caller --- */ |
/* --- back to caller --- */ |
end_of_job: |
end_of_job: |
Line 3708 char *texsubexpr ( char *expression, cha
|
Line 4274 char *texsubexpr ( char *expression, cha
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texchar(); /*next char (or \sequence) from expression*/ |
char *texchar(); /*next char (or \sequence) from expression*/ |
char *leftptr, leftdelim[32] = "(\000", /* left( found in expression */ |
char *leftptr, leftdelim[256] = "(\000", /* left( found in expression */ |
rightdelim[32] = ")\000"; /* and matching right) */ |
rightdelim[256] = ")\000"; /* and matching right) */ |
char *origexpression=expression, *origsubexpr=subexpr; /*original inputs*/ |
char *origexpression=expression, *origsubexpr=subexpr; /*original inputs*/ |
|
char *strtexchr(), *texleft(); /* check for \left, and get it */ |
int gotescape = 0, /* true if leading char of expression is \ */ |
int gotescape = 0, /* true if leading char of expression is \ */ |
prevescape = 0; /* while parsing, true if preceding char \ */ |
prevescape = 0; /* while parsing, true if preceding char \ */ |
int isbrace(); /* check for left,right braces */ |
int isbrace(); /* check for left,right braces */ |
Line 3731 if ( maxsubsz < 1 ) maxsubsz = 8192; /*
|
Line 4298 if ( maxsubsz < 1 ) maxsubsz = 8192; /*
|
/* --- check for escape --- */ |
/* --- check for escape --- */ |
if ( isthischar(*expression,ESCAPE) ) /* expression is escaped */ |
if ( isthischar(*expression,ESCAPE) ) /* expression is escaped */ |
gotescape = 1; /* so set flag accordingly */ |
gotescape = 1; /* so set flag accordingly */ |
|
/* --- check for \left...\right --- */ |
|
if ( gotescape ) /* begins with \ */ |
|
if ( memcmp(expression+1,"left",4) ) /* and followed by left */ |
|
if ( strchr(left,'l') != NULL ) /* caller wants \left's */ |
|
if ( strtexchr(expression,"\\left") == expression ) /*expression=\left...*/ |
|
{ char *pright = texleft(expression,subexpr,maxsubsz, /* find ...\right*/ |
|
(isdelim?NULL:leftdelim),rightdelim); |
|
if ( isdelim ) strcat(subexpr,rightdelim); /* caller wants delims */ |
|
return ( pright ); /*back to caller past \right*/ |
|
} /* --- end-of-if(expression=="\\left") --- */ |
/* --- if first char isn't left{ or script, just return it to caller --- */ |
/* --- if first char isn't left{ or script, just return it to caller --- */ |
if ( !isbrace(expression,left,isescape) ) /* not a left{ */ |
if ( !isbrace(expression,left,isescape) ) /* not a left{ */ |
if ( !isthischar(*expression,SCRIPTS) ) /* and not a script */ |
if ( !isthischar(*expression,SCRIPTS) ) /* and not a script */ |
Line 3811 while ( 1 ) /*until balanced right}
|
Line 4388 while ( 1 ) /*until balanced right}
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: texleft (expression,subexpr,maxsubsz,ldelim,rdelim) |
|
* Purpose: scans expression, starting after opening \left, |
|
* and returning ptr after matching closing \right. |
|
* Everything between is returned in subexpr, if given. |
|
* Likewise, if given, ldelim returns delimiter after \left |
|
* and rdelim returns delimiter after \right. |
|
* If ldelim is given, the returned subexpr doesn't include it. |
|
* If rdelim is given, the returned pointer is after that delim. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I) char * to first char of null-terminated |
|
* string immediately following opening \left |
|
* subexpr (O) char * to null-terminated string returning |
|
* either everything between balanced |
|
* \left ... \right. If leftdelim given, |
|
* subexpr does _not_ contain that delimiter. |
|
* maxsubsz (I) int containing max #bytes returned |
|
* in subexpr buffer (0 means unlimited) |
|
* ldelim (O) char * returning delimiter following |
|
* opening \left |
|
* rdelim (O) char * returning delimiter following |
|
* closing \right |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( char * ) ptr to the first char of expression |
|
* past closing \right, or past closing |
|
* right delimiter if rdelim!=NULL, |
|
* or NULL for any error. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
char *texleft ( char *expression, char *subexpr, int maxsubsz, |
|
char *ldelim, char *rdelim ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
char *texchar(), /* get delims after \left,\right */ |
|
*strtexchr(), *pright=expression; /* locate matching \right */ |
|
static char left[16]="\\left", right[16]="\\right"; /* tex delimiters */ |
|
int sublen = 0; /* #chars between \left...\right */ |
|
/* ------------------------------------------------------------------------- |
|
initialization |
|
-------------------------------------------------------------------------- */ |
|
/* --- init output --- */ |
|
if ( subexpr != NULL ) *subexpr = '\000'; /* init subexpr, if given */ |
|
if ( ldelim != NULL ) *ldelim = '\000'; /* init ldelim, if given */ |
|
if ( rdelim != NULL ) *rdelim = '\000'; /* init rdelim, if given */ |
|
/* --- check args --- */ |
|
if ( expression == NULL ) goto end_of_job; /* no input supplied */ |
|
if ( *expression == '\000' ) goto end_of_job; /* nothing after \left */ |
|
/* --- determine left delimiter --- */ |
|
if ( ldelim != NULL ) /* caller wants left delim */ |
|
{ skipwhite(expression); /* interpret \left ( as \left( */ |
|
expression = texchar(expression,ldelim); } /*delim from expression*/ |
|
/* ------------------------------------------------------------------------- |
|
locate \right balancing opening \left |
|
-------------------------------------------------------------------------- */ |
|
/* --- first \right following \left --- */ |
|
if ( (pright=strtexchr(expression,right)) /* look for \right after \left */ |
|
!= NULL ) { /* found it */ |
|
/* --- find matching \right by pushing past any nested \left's --- */ |
|
char *pleft = expression; /* start after first \left( */ |
|
while ( 1 ) { /*break when matching \right found*/ |
|
/* -- locate next nested \left if there is one --- */ |
|
if ( (pleft=strtexchr(pleft,left)) /* find next \left */ |
|
== NULL ) break; /*no more, so matching \right found*/ |
|
pleft += strlen(left); /* push ptr past \left token */ |
|
if ( pleft >= pright ) break; /* not nested if \left after \right*/ |
|
/* --- have nested \left, so push forward to next \right --- */ |
|
if ( (pright=strtexchr(pright+strlen(right),right)) /* find next \right */ |
|
== NULL ) break; /* ran out of \right's */ |
|
} /* --- end-of-while(1) --- */ |
|
} /* --- end-of-if(pright!=NULL) --- */ |
|
/* --- set subexpression length, push pright past \right --- */ |
|
if ( pright != (char *)NULL ) /* found matching \right */ |
|
{ sublen = (int)(pright-expression); /* #chars between \left...\right */ |
|
pright += strlen(right); } /* so push pright past \right */ |
|
/* ------------------------------------------------------------------------- |
|
get rightdelim and subexpr between \left...\right |
|
-------------------------------------------------------------------------- */ |
|
/* --- get delimiter following \right --- */ |
|
if ( rdelim != NULL ) /* caller wants right delim */ |
|
if ( pright == (char *)NULL ) /* assume \right. at end of exprssn*/ |
|
{ strcpy(rdelim,"."); /* set default \right. */ |
|
sublen = strlen(expression); /* use entire remaining expression */ |
|
pright = expression + sublen; } /* and push pright to end-of-string*/ |
|
else /* have explicit matching \right */ |
|
{ skipwhite(pright); /* interpret \right ) as \right) */ |
|
pright = texchar(pright,rdelim); /* pull delim from expression */ |
|
if ( *rdelim == '\000' ) strcpy(rdelim,"."); } /* or set \right. */ |
|
/* --- get subexpression between \left...\right --- */ |
|
if ( sublen > 0 ) /* have subexpr */ |
|
if ( subexpr != NULL ) { /* and caller wants it */ |
|
if ( maxsubsz > 0 ) sublen = min2(sublen,maxsubsz-1); /* max buffer size */ |
|
memcpy(subexpr,expression,sublen); /* stuff between \left...\right */ |
|
subexpr[sublen] = '\000'; } /* null-terminate subexpr */ |
|
end_of_job: |
|
if ( msglevel>=99 && msgfp!=NULL ) |
|
{ fprintf(msgfp,"texleft> ldelim=%s, rdelim=%s, subexpr=%.128s\n", |
|
(ldelim==NULL?"none":ldelim),(rdelim==NULL?"none":rdelim), |
|
(subexpr==NULL?"none":subexpr)); fflush(msgfp); } |
|
return ( pright ); |
|
} /* --- end-of-function texleft --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: texscripts ( expression, subscript, superscript, which ) |
* Function: texscripts ( expression, subscript, superscript, which ) |
* Purpose: scans expression, returning subscript and/or superscript |
* Purpose: scans expression, returning subscript and/or superscript |
* if expression is of the form _x^y or ^{x}_{y}, |
* if expression is of the form _x^y or ^{x}_{y}, |
Line 3846 Allocations and Declarations
|
Line 4529 Allocations and Declarations
|
char *texsubexpr(); /* next subexpression from expression */ |
char *texsubexpr(); /* next subexpression from expression */ |
int gotsub=0, gotsup=0; /* check that we don't eat, e.g., x_1_2 */ |
int gotsub=0, gotsup=0; /* check that we don't eat, e.g., x_1_2 */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
init "scripts" and skip leading whitespace |
init "scripts" |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- skip leading whitespace and check for end-of-string --- */ |
if ( subscript != NULL ) *subscript = '\000'; /*init in case no subscript*/ |
*subscript = *superscript = '\000'; /* init in case no scripts */ |
if ( superscript!=NULL ) *superscript = '\000'; /*init in case no super*/ |
skipwhite(expression); /* leading whitespace gone */ |
|
if ( *expression == '\000' ) return(expression); /* nothing left to scan */ |
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
get subscript and/or superscript from expression |
get subscript and/or superscript from expression |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
while ( expression != NULL ) |
while ( expression != NULL ) { |
|
skipwhite(expression); /* leading whitespace gone */ |
|
if ( *expression == '\000' ) return(expression); /* nothing left to scan */ |
if ( isthischar(*expression,SUBSCRIPT) /* found _ */ |
if ( isthischar(*expression,SUBSCRIPT) /* found _ */ |
&& (which==1 || which>2 ) ) /* and caller wants it */ |
&& (which==1 || which>2 ) ) /* and caller wants it */ |
{ if ( gotsub /* found 2nd subscript */ |
{ if ( gotsub /* found 2nd subscript */ |
Line 3871 while ( expression != NULL )
|
Line 4554 while ( expression != NULL )
|
expression = texsubexpr(expression+1,superscript,0,"{","}",0,0); } |
expression = texsubexpr(expression+1,superscript,0,"{","}",0,0); } |
else /* neither _ nor ^ */ |
else /* neither _ nor ^ */ |
return ( expression ); /*return ptr past "scripts"*/ |
return ( expression ); /*return ptr past "scripts"*/ |
|
} /* --- end-of-while(expression!=NULL) --- */ |
return ( expression ); |
return ( expression ); |
} /* --- end-of-function texscripts() --- */ |
} /* --- end-of-function texscripts() --- */ |
|
|
Line 4140 static struct { char *html; char *args;
|
Line 4824 static struct { char *html; char *args;
|
LaTeX Macro #args,default template... |
LaTeX Macro #args,default template... |
------------------------------------------ */ |
------------------------------------------ */ |
{ "\\lvec", "2n", "{#2_1,\\cdots,#2_{#1}}" }, |
{ "\\lvec", "2n", "{#2_1,\\cdots,#2_{#1}}" }, |
|
{ "\\grave", "1", "{\\stackrel{\\Huge\\gravesym}{#1}}" }, /* \grave */ |
|
{ "\\acute", "1", "{\\stackrel{\\Huge\\acutesym}{#1}}" }, /* \acute */ |
|
{ "\\check", "1", "{\\stackrel{\\Huge\\checksym}{#1}}" }, /* \check */ |
|
{ "\\breve", "1", "{\\stackrel{\\Huge\\brevesym}{#1}}" }, /* \breve */ |
{ "\\overset", NULL, "\\stackrel" }, /* just an alias */ |
{ "\\overset", NULL, "\\stackrel" }, /* just an alias */ |
{ "\\underset", "2", "\\relstack{#2}{#1}" }, /* reverse args */ |
{ "\\underset", "2", "\\relstack{#2}{#1}" }, /* reverse args */ |
/* --------------------------------------- |
/* --------------------------------------- |
html termchar LaTeX equivalent... |
html char termchar LaTeX equivalent... |
--------------------------------------- */ |
--------------------------------------- */ |
{ """, ";", "\"" }, /* " is first, " */ |
{ """, ";", "\"" }, /* " is first, " */ |
{ "&", ";", "&" }, |
{ "&", ";", "&" }, |
Line 4168 static struct { char *html; char *args;
|
Line 4856 static struct { char *html; char *args;
|
{ "ã", ";", "{\\rm~\\tilde~a}" }, |
{ "ã", ";", "{\\rm~\\tilde~a}" }, |
{ "ÿ", ";", "{\\rm~\\ddot~y}" }, /* ÿ is last, ÿ */ |
{ "ÿ", ";", "{\\rm~\\ddot~y}" }, /* ÿ is last, ÿ */ |
/* --------------------------------------- |
/* --------------------------------------- |
|
html tag termchar LaTeX equivalent... |
|
--------------------------------------- */ |
|
{ "<br>", NULL, "\\\\" }, |
|
{ "<br/>", NULL, "\\\\" }, |
|
{ "<Br>", NULL, "\\\\" }, |
|
{ "<Br/>", NULL, "\\\\" }, |
|
{ "<BR>", NULL, "\\\\" }, |
|
{ "<BR/>", NULL, "\\\\" }, |
|
/* --------------------------------------- |
LaTeX termchar mimeTeX equivalent... |
LaTeX termchar mimeTeX equivalent... |
--------------------------------------- */ |
--------------------------------------- */ |
{ "\\AA", NULL, "{\\rm~A\\limits^{-1$o}}" }, |
{ "\\AA", NULL, "{\\rm~A\\limits^{-1$o}}" }, |
{ "\\aa", NULL, "{\\rm~a\\limits^{-1$o}}" }, |
{ "\\aa", NULL, "{\\rm~a\\limits^{-1$o}}" }, |
{ "\\bmod", NULL, "{\\hspace2{\\rm~mod}\\hspace2}" }, |
{ "\\bmod", NULL, "{\\hspace2{\\rm~mod}\\hspace2}" }, |
{ "\\vdots", NULL, "{\\raisebox3{\\rotatebox{90}{\\ldots}}}" }, |
{ "\\vdots", NULL, "{\\raisebox3{\\rotatebox{90}{\\ldots}}}" }, |
|
{ "\\dots", NULL, "{\\cdots}" }, |
{ "\\cdots", NULL, "{\\raisebox3{\\ldots}}" }, |
{ "\\cdots", NULL, "{\\raisebox3{\\ldots}}" }, |
{ "\\ldots", NULL, "{\\fs4.\\hspace1.\\hspace1.}" }, |
{ "\\ldots", NULL, "{\\fs4.\\hspace1.\\hspace1.}" }, |
{ "\\ddots", NULL, "{\\fs4\\raisebox8.\\hspace1\\raisebox4.\\hspace1.}"}, |
{ "\\ddots", NULL, "{\\fs4\\raisebox8.\\hspace1\\raisebox4.\\hspace1.}"}, |
{ "\\notin", NULL, "{\\not\\in}" }, |
{ "\\notin", NULL, "{\\not\\in}" }, |
{ "\\neq", NULL, "{\\not=}" }, |
{ "\\neq", NULL, "{\\not=}" }, |
|
{ "\\ne", NULL, "{\\not=}" }, |
{ "\\hbar", NULL, "{\\compose~h{{\\fs{-1}-\\atop\\vspace3}}}" }, |
{ "\\hbar", NULL, "{\\compose~h{{\\fs{-1}-\\atop\\vspace3}}}" }, |
{ "\\angle", NULL, "{\\compose{\\hspace{3}\\lt}{\\circle(10,15;-80,80)}}"}, |
{ "\\angle", NULL, "{\\compose{\\hspace{3}\\lt}{\\circle(10,15;-80,80)}}"}, |
|
{ "\\textcelsius", NULL, "{\\textdegree C}"}, |
|
{ "\\textdegree", NULL, "{\\Large^{^{\\tiny\\mathbf o}}}"}, |
{ "\\cr", NULL, "\\\\" }, |
{ "\\cr", NULL, "\\\\" }, |
|
{ "\\iiint", NULL, "{\\int\\int\\int}\\limits" }, |
{ "\\iint", NULL, "{\\int\\int}\\limits" }, |
{ "\\iint", NULL, "{\\int\\int}\\limits" }, |
{ "\\Bigiint", NULL, "{\\Bigint\\Bigint}\\limits" }, |
{ "\\Bigiint", NULL, "{\\Bigint\\Bigint}\\limits" }, |
|
{ "\\bigsqcap",NULL, "{\\fs{+4}\\sqcap}" }, |
{ "!`", NULL, "{\\raisebox{-2}{\\rotatebox{180}{!}}}" }, |
{ "!`", NULL, "{\\raisebox{-2}{\\rotatebox{180}{!}}}" }, |
{ "?`", NULL, "{\\raisebox{-2}{\\rotatebox{180}{?}}}" }, |
{ "?`", NULL, "{\\raisebox{-2}{\\rotatebox{180}{?}}}" }, |
|
{ "^\'", "embed","\'" }, /* avoid ^^ when re-xlating \' below */ |
|
{ "\'\'\'\'","embed","^{\\fs{-1}\\prime\\prime\\prime\\prime}" }, |
|
{ "\'\'\'", "embed","^{\\fs{-1}\\prime\\prime\\prime}" }, |
|
{ "\'\'", "embed","^{\\fs{-1}\\prime\\prime}" }, |
|
{ "\'", "embed","^{\\fs{-1}\\prime}" }, |
{ "\\rightleftharpoons",NULL,"{\\rightharpoonup\\atop\\leftharpoondown}" }, |
{ "\\rightleftharpoons",NULL,"{\\rightharpoonup\\atop\\leftharpoondown}" }, |
|
{ "\\therefore",NULL,"{\\Huge\\raisebox{-4}{.\\atop.\\,.}}" }, |
{ "\\LaTeX", NULL, "{\\rm~L\\raisebox{3}{\\fs{-1}A}\\TeX}" }, |
{ "\\LaTeX", NULL, "{\\rm~L\\raisebox{3}{\\fs{-1}A}\\TeX}" }, |
{ "\\TeX", NULL, "{\\rm~T\\raisebox{-3}{E}X}" }, |
{ "\\TeX", NULL, "{\\rm~T\\raisebox{-3}{E}X}" }, |
{ "\\cyan", NULL, "{\\reverse\\red\\reversebg}" }, |
{ "\\cyan", NULL, "{\\reverse\\red\\reversebg}" }, |
{ "\\magenta",NULL, "{\\reverse\\green\\reversebg}" }, |
{ "\\magenta",NULL, "{\\reverse\\green\\reversebg}" }, |
{ "\\yellow",NULL, "{\\reverse\\blue\\reversebg}" }, |
{ "\\yellow",NULL, "{\\reverse\\blue\\reversebg}" }, |
|
{ "\\cancel",NULL, "\\Not" }, |
{ "\\hhline",NULL, "\\Hline" }, |
{ "\\hhline",NULL, "\\Hline" }, |
{ "\\Hline", NULL, "\\hline\\,\\\\\\hline" }, |
{ "\\Hline", NULL, "\\hline\\,\\\\\\hline" }, |
/* --------------------------------------------------------- |
/* --------------------------------------------------------- |
Line 4202 static struct { char *html; char *args;
|
Line 4912 static struct { char *html; char *args;
|
{ "cos", "1", "{\\cos{#1}}" }, |
{ "cos", "1", "{\\cos{#1}}" }, |
{ "asin", "1", "{\\sin^{-1}{#1}}" }, |
{ "asin", "1", "{\\sin^{-1}{#1}}" }, |
{ "acos", "1", "{\\cos^{-1}{#1}}" }, |
{ "acos", "1", "{\\cos^{-1}{#1}}" }, |
{ "exp", "1", "{e^{#1}}" }, |
{ "exp", "1", "{{\\rm~e}^{#1}}" }, |
{ "det", "1", "{\\left|{#1}\\right|}" }, |
{ "det", "1", "{\\left|{#1}\\right|}" }, |
/* --------------------------------------- |
/* --------------------------------------- |
LaTeX Constant termchar value... |
LaTeX Constant termchar value... |
Line 4277 for(isymbol=0; (htmlsym=symbols[isymbol]
|
Line 4987 for(isymbol=0; (htmlsym=symbols[isymbol]
|
{ |
{ |
int htmllen = strlen(htmlsym); /* length of escape, _without_ ; */ |
int htmllen = strlen(htmlsym); /* length of escape, _without_ ; */ |
int isalgebra = isalpha((int)(*htmlsym)); /* leading char alphabetic */ |
int isalgebra = isalpha((int)(*htmlsym)); /* leading char alphabetic */ |
|
int isembedded = 0; /* true to xlate even if embedded */ |
char *aleft="{([<|", *aright="})]>|"; /*left,right delims for alg syntax*/ |
char *aleft="{([<|", *aright="})]>|"; /*left,right delims for alg syntax*/ |
char *args = symbols[isymbol].args, /* number {}-args, optional []-arg */ |
char *args = symbols[isymbol].args, /* number {}-args, optional []-arg */ |
*htmlterm = args, /*if *args nonumeric, then html term*/ |
*htmlterm = args, /*if *args nonumeric, then html term*/ |
Line 4288 for(isymbol=0; (htmlsym=symbols[isymbol]
|
Line 4999 for(isymbol=0; (htmlsym=symbols[isymbol]
|
{ htmlterm = NULL; /* if so, then we have no htmlterm */ |
{ htmlterm = NULL; /* if so, then we have no htmlterm */ |
*abuff = *args; abuff[1] = '\000'; /* #args char in ascii buffer */ |
*abuff = *args; abuff[1] = '\000'; /* #args char in ascii buffer */ |
nargs = atoi(abuff); } /* interpret #args to numeric */ |
nargs = atoi(abuff); } /* interpret #args to numeric */ |
|
else if ( strncmp(args,"embed",5) == 0 ) /* xlate even if embedded */ |
|
{ htmlterm = NULL; /* if so, then we have no htmlterm */ |
|
isembedded = 1 ; } /* turn on embedded flag */ |
expptr = expression; /* re-start search at beginning */ |
expptr = expression; /* re-start search at beginning */ |
while ( (tokptr=strstr(expptr,htmlsym)) != NULL ) /* found another sym */ |
while ( (tokptr=strstr(expptr,htmlsym)) != NULL ) /* found another sym */ |
{ char termchar = *(tokptr+htmllen); /* char terminating html sequence */ |
{ char termchar = *(tokptr+htmllen), /* char terminating html sequence */ |
|
prevchar = (tokptr==expptr?' ':*(tokptr-1)); /*char preceding html*/ |
int escapelen = htmllen; /* total length of escape sequence */ |
int escapelen = htmllen; /* total length of escape sequence */ |
*abuff = '\000'; /* default to empty string */ |
*abuff = '\000'; /* default to empty string */ |
if ( latexsym != NULL ) /* table has .latex xlation */ |
if ( latexsym != NULL ) /* table has .latex xlation */ |
Line 4298 for(isymbol=0; (htmlsym=symbols[isymbol]
|
Line 5013 for(isymbol=0; (htmlsym=symbols[isymbol]
|
strcpy(abuff,latexsym); /* so get local copy */ |
strcpy(abuff,latexsym); /* so get local copy */ |
if ( htmlterm != NULL ) /* sequence may have terminator */ |
if ( htmlterm != NULL ) /* sequence may have terminator */ |
escapelen += (isthischar(termchar,htmlterm)?1:0); /*add terminator*/ |
escapelen += (isthischar(termchar,htmlterm)?1:0); /*add terminator*/ |
if ( isalpha((int)termchar) ) /*we just have prefix of longer sym*/ |
if ( !isembedded ) /* don't xlate embedded sequence */ |
|
if ( isalpha((int)termchar) ) /*we just have prefix of longer sym*/ |
{ expptr = tokptr+htmllen; /* just resume search after prefix */ |
{ expptr = tokptr+htmllen; /* just resume search after prefix */ |
continue; } /* but don't replace it */ |
continue; } /* but don't replace it */ |
|
if ( isembedded ) /* for embedded sequence */ |
|
if ( isthischar(prevchar,ESCAPE) ) /* don't xlate escaped char */ |
|
{ expptr = tokptr+htmllen; /*just resume search after literal*/ |
|
continue; } /* but don't replace it */ |
if ( !isthischar(*htmlsym,ESCAPE) /* our symbol isn't escaped */ |
if ( !isthischar(*htmlsym,ESCAPE) /* our symbol isn't escaped */ |
|
&& isalpha(*htmlsym) /* and our symbol starts with alpha*/ |
&& !isthischar(*htmlsym,"&") ) /* and not an &html; special char */ |
&& !isthischar(*htmlsym,"&") ) /* and not an &html; special char */ |
if ( tokptr != expression ) /* then if we're past beginning */ |
if ( tokptr != expression ) /* then if we're past beginning */ |
if ( isthischar(*(tokptr-1),ESCAPE) /*and if inline symbol escaped*/ |
if ( isthischar(*(tokptr-1),ESCAPE) /*and if inline symbol escaped*/ |
Line 4527 char *strtexchr ( char *string, char *te
|
Line 5248 char *strtexchr ( char *string, char *te
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *strstr(), delim, *ptexchr=(char *)NULL; /* ptr returned to caller*/ |
char delim, *ptexchr=(char *)NULL; /* ptr returned to caller*/ |
char *pstring = string; /* start or continue up search here*/ |
char *pstring = string; /* start or continue up search here*/ |
int texchrlen = (texchr==NULL?0:strlen(texchr)); /* #chars in texchr */ |
int texchrlen = (texchr==NULL?0:strlen(texchr)); /* #chars in texchr */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 4660 subraster *get_charsubraster(), /* char
|
Line 5381 subraster *get_charsubraster(), /* char
|
int delete_subraster(); /* free everything before returning*/ |
int delete_subraster(); /* free everything before returning*/ |
/*int pixsz = 1;*/ /*default #bits per pixel, 1=bitmap*/ |
/*int pixsz = 1;*/ /*default #bits per pixel, 1=bitmap*/ |
/* --- global values saved/restored at each recursive iteration --- */ |
/* --- global values saved/restored at each recursive iteration --- */ |
int wastext = istext, /* initial istext mode flag */ |
int wasstring = isstring, /* initial isstring mode flag */ |
wasstring = isstring, /* initial isstring mode flag */ |
|
wasdisplaystyle = isdisplaystyle, /*initial displaystyle mode flag*/ |
wasdisplaystyle = isdisplaystyle, /*initial displaystyle mode flag*/ |
|
oldfontnum = fontnum, /* initial font family */ |
oldfontsize = fontsize, /* initial fontsize */ |
oldfontsize = fontsize, /* initial fontsize */ |
olddisplaysize = displaysize, /* initial \displaystyle size */ |
olddisplaysize = displaysize, /* initial \displaystyle size */ |
oldshrinkfactor = shrinkfactor, /* initial shrinkfactor */ |
oldshrinkfactor = shrinkfactor, /* initial shrinkfactor */ |
oldsquashmargin = squashmargin, /* initial squashmargin */ |
oldsmashmargin = smashmargin, /* initial smashmargin */ |
oldissquashdelta = issquashdelta, /* initial issquashdelta */ |
oldissmashdelta = issmashdelta, /* initial issmashdelta */ |
*oldworkingparam = workingparam; /* initial working parameter */ |
*oldworkingparam = workingparam; /* initial working parameter */ |
subraster *oldworkingbox = workingbox, /* initial working box */ |
subraster *oldworkingbox = workingbox, /* initial working box */ |
*oldleftexpression = leftexpression; /*left half rasterized so far*/ |
*oldleftexpression = leftexpression; /*left half rasterized so far*/ |
Line 4724 while ( 1 )
|
Line 5445 while ( 1 )
|
if ( (leftsymdef=symdef=get_symdef(chartoken)) /*mathchardef for token*/ |
if ( (leftsymdef=symdef=get_symdef(chartoken)) /*mathchardef for token*/ |
== NULL ) /* lookup failed */ |
== NULL ) /* lookup failed */ |
{ char literal[512] = "[?]"; /*display for unrecognized literal*/ |
{ char literal[512] = "[?]"; /*display for unrecognized literal*/ |
int wastext = istext; /* error display in default mode */ |
int oldfontnum = fontnum; /* error display in default mode */ |
if ( msgfp!=NULL && msglevel >= 29 ) /* display unrecognized symbol */ |
if ( msgfp!=NULL && msglevel >= 29 ) /* display unrecognized symbol */ |
{ fprintf(msgfp,"rasterize> get_symdef() failed for \"%s\"\n", |
{ fprintf(msgfp,"rasterize> get_symdef() failed for \"%s\"\n", |
chartoken); fflush(msgfp); } |
chartoken); fflush(msgfp); } |
sp = (subraster *)NULL; /* init to signal failure */ |
sp = (subraster *)NULL; /* init to signal failure */ |
if ( warninglevel < 1 ) continue; /* warnings not wanted */ |
if ( warninglevel < 1 ) continue; /* warnings not wanted */ |
istext = 0; /* reset from \mathbb, etc */ |
fontnum = 0; /* reset from \mathbb, etc */ |
if ( isthischar(*chartoken,ESCAPE) ) /* we got unrecognized \escape */ |
if ( isthischar(*chartoken,ESCAPE) ) /* we got unrecognized \escape */ |
{ /* --- so display literal {\rm~[\backslash~chartoken?]} --- */ |
{ /* --- so display literal {\rm~[\backslash~chartoken?]} --- */ |
strcpy(literal,"{\\rm~[\\backslash~"); /* init token */ |
strcpy(literal,"{\\rm~[\\backslash~"); /* init token */ |
strcat(literal,chartoken+1); /* add chars following leading \ */ |
strcat(literal,chartoken+1); /* add chars following leading \ */ |
strcat(literal,"?]}"); } /* add closing brace */ |
strcat(literal,"?]}"); } /* add closing brace */ |
sp = rasterize(literal,size-1); /* rasterize literal token */ |
sp = rasterize(literal,size-1); /* rasterize literal token */ |
istext = wastext; /* reset text mode */ |
fontnum = oldfontnum; /* reset font family */ |
if ( sp == (subraster *)NULL ) continue; } /*flush if rasterize fails*/ |
if ( sp == (subraster *)NULL ) continue; } /*flush if rasterize fails*/ |
else /* --- check if we have special handler to process this token --- */ |
else /* --- check if we have special handler to process this token --- */ |
if ( symdef->handler != NULL ) /* have a handler for this token */ |
if ( symdef->handler != NULL ) /* have a handler for this token */ |
Line 4773 while ( 1 )
|
Line 5494 while ( 1 )
|
if ( natoms < 1 /* nothing previous to concat */ |
if ( natoms < 1 /* nothing previous to concat */ |
|| expraster == NULL /* or previous was complete error */ |
|| expraster == NULL /* or previous was complete error */ |
|| isreplaceleft ) /* or we're replacing previous */ |
|| isreplaceleft ) /* or we're replacing previous */ |
{ expraster = subrastcpy(sp); /* so just copy static CHARASTER */ |
{ if ( 1 && expraster!=NULL ) /* probably replacing left */ |
|
delete_subraster(expraster); /* so first free original left */ |
|
expraster = subrastcpy(sp); /* copy static CHARASTER or left */ |
isreplaceleft = 0; } /* reset replacement flag */ |
isreplaceleft = 0; } /* reset replacement flag */ |
else /*we've already built up atoms so...*/ |
else /*we've already built up atoms so...*/ |
if ( sp != NULL ) /* ...if we have a new component */ |
if ( sp != NULL ) /* ...if we have a new component */ |
Line 4796 end_of_job:
|
Line 5519 end_of_job:
|
if ( expraster != (subraster *)NULL ) /* i.e., if natoms>0 */ |
if ( expraster != (subraster *)NULL ) /* i.e., if natoms>0 */ |
type_raster(expraster->image,msgfp); /* display completed raster */ |
type_raster(expraster->image,msgfp); /* display completed raster */ |
fflush(msgfp); } /* flush msgfp buffer */ |
fflush(msgfp); } /* flush msgfp buffer */ |
|
/* --- set final raster buffer --- */ |
|
if ( 1 && expraster != (subraster *)NULL ) /* have an expression */ |
|
{ expraster->type = IMAGERASTER; /* set type to constructed image */ |
|
if ( istextmode ) /* but in text mode */ |
|
expraster->type = blanksignal; /* set type to avoid smash */ |
|
expraster->size = fontsize; } /* set original input font size */ |
/* --- restore flags/values to original saved values --- */ |
/* --- restore flags/values to original saved values --- */ |
istext = wastext; /* text mode reset */ |
|
isstring = wasstring; /* string mode reset */ |
isstring = wasstring; /* string mode reset */ |
isdisplaystyle = wasdisplaystyle; /* displaystyle mode reset */ |
isdisplaystyle = wasdisplaystyle; /* displaystyle mode reset */ |
|
fontnum = oldfontnum; /* font family reset */ |
fontsize = oldfontsize; /* fontsize reset */ |
fontsize = oldfontsize; /* fontsize reset */ |
displaysize = olddisplaysize; /* \displaystyle size reset */ |
displaysize = olddisplaysize; /* \displaystyle size reset */ |
shrinkfactor = oldshrinkfactor; /* shrinkfactor reset */ |
shrinkfactor = oldshrinkfactor; /* shrinkfactor reset */ |
squashmargin = oldsquashmargin; /* squashmargin reset */ |
smashmargin = oldsmashmargin; /* smashmargin reset */ |
issquashdelta = oldissquashdelta; /* issquashdelta reset */ |
issmashdelta = oldissmashdelta; /* issmashdelta reset */ |
workingparam = oldworkingparam; /* working parameter reset */ |
workingparam = oldworkingparam; /* working parameter reset */ |
workingbox = oldworkingbox; /* working box reset */ |
workingbox = oldworkingbox; /* working box reset */ |
leftexpression = oldleftexpression; /* leftexpression reset */ |
leftexpression = oldleftexpression; /* leftexpression reset */ |
Line 4812 end_of_job:
|
Line 5541 end_of_job:
|
unitlength = oldunitlength; /* unitlength reset */ |
unitlength = oldunitlength; /* unitlength reset */ |
recurlevel--; /* unwind one recursion level */ |
recurlevel--; /* unwind one recursion level */ |
/* --- return final subraster to caller --- */ |
/* --- return final subraster to caller --- */ |
if ( 1 && expraster != (subraster *)NULL ) /* have an expression */ |
|
{ expraster->type = IMAGERASTER; /* set type to constructed image */ |
|
expraster->size = fontsize; } /* set original input font size */ |
|
return ( expraster ); |
return ( expraster ); |
} /* --- end-of-function rasterize() --- */ |
} /* --- end-of-function rasterize() --- */ |
|
|
Line 4858 subraster *rasterize(), *sp=NULL; /* ras
|
Line 5584 subraster *rasterize(), *sp=NULL; /* ras
|
int isheight = 1; /*true=full height, false=baseline*/ |
int isheight = 1; /*true=full height, false=baseline*/ |
int height, /* height of rasterized noparens[] */ |
int height, /* height of rasterized noparens[] */ |
baseline; /* and its baseline */ |
baseline; /* and its baseline */ |
int family = CMEX10; /* family for paren chars */ |
int family = /*CMSYEX*/ CMEX10; /* family for paren chars */ |
subraster *get_delim(), *lp=NULL, *rp=NULL; /* left and right paren chars */ |
subraster *get_delim(), *lp=NULL, *rp=NULL; /* left and right paren chars */ |
subraster *rastcat(); /* concatanate subrasters */ |
subraster *rastcat(); /* concatanate subrasters */ |
int delete_subraster(); /*in case of error after allocation*/ |
int delete_subraster(); /*in case of error after allocation*/ |
Line 4952 subraster *rastscripts(), *rastdispmath(
|
Line 5678 subraster *rastscripts(), *rastdispmath(
|
*rastcat(), /* may need to concat scripts */ |
*rastcat(), /* may need to concat scripts */ |
*scriptsp = basesp; /* and this will become the result */ |
*scriptsp = basesp; /* and this will become the result */ |
int isdisplay = (-1); /* set 1 for displaystyle, else 0 */ |
int isdisplay = (-1); /* set 1 for displaystyle, else 0 */ |
int oldsquashmargin = squashmargin; /* save original squashmargin */ |
int oldsmashmargin = smashmargin; /* save original smashmargin */ |
int type_raster(); /* display debugging output */ |
int type_raster(); /* display debugging output */ |
/* --- to check for \limits or \nolimits preceding scripts --- */ |
/* --- to check for \limits or \nolimits preceding scripts --- */ |
char *texchar(), *exprptr=*expression, limtoken[255]; /*check for \limits*/ |
char *texchar(), *exprptr=*expression, limtoken[255]; /*check for \limits*/ |
Line 5013 else /* scripts alongside base symbo
|
Line 5739 else /* scripts alongside base symbo
|
scriptsp = basesp; /* so just return unscripted symbol*/ |
scriptsp = basesp; /* so just return unscripted symbol*/ |
else /* symbols followed by scripts */ |
else /* symbols followed by scripts */ |
if ( basesp != NULL ) /* have base symbol */ |
if ( basesp != NULL ) /* have base symbol */ |
{ squashmargin = 0; /* don't squash script */ |
{ smashmargin = 0; /* don't smash script */ |
scriptsp = rastcat(basesp,scriptsp,2); /*concat scripts to base sym*/ |
/*scriptsp = rastcat(basesp,scriptsp,2);*//*concat scripts to base sym*/ |
|
scriptsp = rastcat(basesp,scriptsp,3); /*concat scripts to base sym*/ |
scriptsp->type = IMAGERASTER; /* flip type of composite object */ |
scriptsp->type = IMAGERASTER; /* flip type of composite object */ |
scriptsp->size = size; } /* and set font size */ |
scriptsp->size = size; } /* and set font size */ |
end_of_job: |
end_of_job: |
squashmargin = oldsquashmargin; /* reset original squashmargin */ |
smashmargin = oldsmashmargin; /* reset original smashmargin */ |
if ( msgfp!=NULL && msglevel>=99 ) |
if ( msgfp!=NULL && msglevel>=99 ) |
{ fprintf(msgfp,"rastlimits> scriptlevel#%d returning %s\n", |
{ fprintf(msgfp,"rastlimits> scriptlevel#%d returning %s\n", |
scriptlevel,(scriptsp==NULL?"null":"...")); |
scriptlevel,(scriptsp==NULL?"null":"...")); |
Line 5259 end_of_job:
|
Line 5986 end_of_job:
|
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding leading left{ |
* immediately preceding leading left{ |
* (unused, but passed for consistency) |
* (unused, but passed for consistency) |
* ildelim (I) int containing ldelims index of |
* ildelim (I) int containing ldelims[] index of |
* left delimiter |
* left delimiter |
* arg2 (I) int unused |
* arg2 (I) int unused |
* arg3 (I) int unused |
* arg3 (I) int unused |
Line 5284 int family=CMSYEX, /* get_delim() fami
|
Line 6011 int family=CMSYEX, /* get_delim() fami
|
height=0, rheight=0, /* subexpr, right delim height */ |
height=0, rheight=0, /* subexpr, right delim height */ |
margin=(size+1), /* delim height margin over subexpr*/ |
margin=(size+1), /* delim height margin over subexpr*/ |
opmargin=(5); /* extra margin for \int,\sum,\etc */ |
opmargin=(5); /* extra margin for \int,\sum,\etc */ |
char subexpr[8192]; /* chars between \left...\right */ |
char /* *texleft(),*/ subexpr[8192]; /* chars between \left...\right */ |
char *texchar(), /* get delims after \left,\right */ |
char *texchar(), /* get delims after \left,\right */ |
ldelim[256]=".", rdelim[256]="."; /* delims following \left,\right */ |
ldelim[256]=".", rdelim[256]="."; /* delims following \left,\right */ |
char *strtexchr(), *pleft, *pright; /*locate \right matching our \left*/ |
char *strtexchr(), *pleft, *pright; /*locate \right matching our \left*/ |
int isleftdot=0, isrightdot=0; /* true if \left. or \right. */ |
int isleftdot=0, isrightdot=0; /* true if \left. or \right. */ |
int sublen=0; /* strlen(subexpr) */ |
int sublen=0; /* strlen(subexpr) */ |
int idelim=0; /* 1=left,2=right */ |
int idelim=0; /* 1=left,2=right */ |
|
/* int gotldelim = 0; */ /* true if ildelim given by caller */ |
int delete_subraster(); /* free subraster if rastleft fails*/ |
int delete_subraster(); /* free subraster if rastleft fails*/ |
int wasdisplaystyle = isdisplaystyle; /* save current displaystyle */ |
int wasdisplaystyle = isdisplaystyle; /* save current displaystyle */ |
|
int istextleft=0, istextright=0; /* true for non-displaystyle delims*/ |
/* --- recognized delimiters --- */ |
/* --- recognized delimiters --- */ |
static char left[16]="\\left", right[16]="\\right"; /* tex delimiters */ |
static char left[16]="\\left", right[16]="\\right"; /* tex delimiters */ |
static char *ldelims[] = { |
static char *ldelims[] = { |
Line 5329 static char *xto[] = /* ...to this ins
|
Line 6058 static char *xto[] = /* ...to this ins
|
"<", /* \langle to < */ |
"<", /* \langle to < */ |
">", /* \rangle to > */ |
">", /* \rangle to > */ |
NULL } ; /* --- end-of-xto[] --- */ |
NULL } ; /* --- end-of-xto[] --- */ |
|
/* --- non-displaystyle delimiters --- */ |
|
static char *textdelims[] = /* these delims _aren't_ display */ |
|
{ "|", "=", |
|
"(", ")", |
|
"[", "]", |
|
"<", ">", |
|
"{", "}", |
|
"dbl", /* \lbrackdbl and \rbrackdbl */ |
|
NULL } ; /* --- end-of-textdelims[] --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 5336 initialization
|
Line 6074 initialization
|
if ( *(*expression) == '\000' ) goto end_of_job; /* nothing after \left */ |
if ( *(*expression) == '\000' ) goto end_of_job; /* nothing after \left */ |
/* --- determine left delimiter, and set default \right. delimiter --- */ |
/* --- determine left delimiter, and set default \right. delimiter --- */ |
if ( ildelim!=NOVALUE && ildelim>=1 ) /* called with explicit left delim */ |
if ( ildelim!=NOVALUE && ildelim>=1 ) /* called with explicit left delim */ |
strcpy(ldelim,ldelims[ildelim]); /* so just get a local copy */ |
{ strcpy(ldelim,ldelims[ildelim]); /* so just get a local copy */ |
|
/* gotldelim = 1; */ } /* and set flag that we got it */ |
else /* trapped \left without delim */ |
else /* trapped \left without delim */ |
{ skipwhite(*expression); /* interpret \left ( as \left( */ |
{ skipwhite(*expression); /* interpret \left ( as \left( */ |
*expression = texchar(*expression,ldelim); } /*pull delim from expression*/ |
if ( *(*expression) == '\000' ) /* end-of-string after \left */ |
|
goto end_of_job; /* so return NULL */ |
|
*expression = texchar(*expression,ldelim); /*pull delim from expression*/ |
|
if ( *expression == NULL /* probably invalid end-of-string */ |
|
|| *ldelim == '\000' ) goto end_of_job; } /* no delimiter */ |
strcpy(rdelim,"."); /* init default \right. delim */ |
strcpy(rdelim,"."); /* init default \right. delim */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
locate \right balancing our opening \left |
locate \right balancing our opening \left |
Line 5364 if ( (pright=strtexchr(*expression,right
|
Line 6107 if ( (pright=strtexchr(*expression,right
|
push past \left(_a^b sub/superscripts, if present |
push past \left(_a^b sub/superscripts, if present |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
pleft = *expression; /*reset pleft after opening \left( */ |
pleft = *expression; /*reset pleft after opening \left( */ |
/*lp=*/ rastlimits(expression,size,lp); /*dummy call push expression past b*/ |
if ( (lp=rastlimits(expression,size,lp)) /*dummy call push expression past b*/ |
|
!= NULL ) /* found actual _a^b scripts, too */ |
|
{ delete_subraster(lp); /* but we don't need them */ |
|
lp = NULL; } /* reset pointer, too */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
get \right delimiter and subexpression between \left...\right, xlate delims |
get \right delimiter and subexpression between \left...\right, xlate delims |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 5384 else { /* have explicit matching \ri
|
Line 6130 else { /* have explicit matching \ri
|
/* --- get subexpression between \left...\right --- */ |
/* --- get subexpression between \left...\right --- */ |
if ( sublen < 1 ) goto end_of_job; /* nothing between delimiters */ |
if ( sublen < 1 ) goto end_of_job; /* nothing between delimiters */ |
subexpr[sublen] = '\000'; /* and null-terminate it */ |
subexpr[sublen] = '\000'; /* and null-terminate it */ |
|
/* --- adjust margin for expressions containing \middle's --- */ |
|
if ( strtexchr(subexpr,"\\middle") != NULL ) /* have enclosed \middle's */ |
|
margin = 1; /* so don't "overwhelm" them */ |
/* --- check for operator delimiter --- */ |
/* --- check for operator delimiter --- */ |
for ( idelim=0; opdelims[idelim]!=NULL; idelim++ ) |
for ( idelim=0; opdelims[idelim]!=NULL; idelim++ ) |
if ( strstr(ldelim,opdelims[idelim]) != NULL ) /* found operator */ |
if ( strstr(ldelim,opdelims[idelim]) != NULL ) /* found operator */ |
Line 5391 for ( idelim=0; opdelims[idelim]!=NULL;
|
Line 6140 for ( idelim=0; opdelims[idelim]!=NULL;
|
if ( *ldelim == '\\' ) /* have leading escape */ |
if ( *ldelim == '\\' ) /* have leading escape */ |
strcpy(ldelim,ldelim+1); /* squeeze it out */ |
strcpy(ldelim,ldelim+1); /* squeeze it out */ |
break; } /* no need to check rest of table */ |
break; } /* no need to check rest of table */ |
/* --- xlate delimiters --- */ |
/* --- xlate delimiters and check for textstyle --- */ |
for ( idelim=1; idelim<=2; idelim++ ) { /* 1=left, 2=right */ |
for ( idelim=1; idelim<=2; idelim++ ) { /* 1=left, 2=right */ |
char *lrdelim = (idelim==1? ldelim:rdelim); /* ldelim or rdelim */ |
char *lrdelim = (idelim==1? ldelim:rdelim); /* ldelim or rdelim */ |
int ix; char *xdelim; /* xfrom[] and xto[] index, delim */ |
int ix; char *xdelim; /* xfrom[] and xto[] index, delim */ |
Line 5399 for ( idelim=1; idelim<=2; idelim++ ) {
|
Line 6148 for ( idelim=1; idelim<=2; idelim++ ) {
|
if ( strcmp(lrdelim,xdelim) == 0 ) /* found delim to xlate */ |
if ( strcmp(lrdelim,xdelim) == 0 ) /* found delim to xlate */ |
{ strcpy(lrdelim,xto[ix]); /* replace with corresponding xto[]*/ |
{ strcpy(lrdelim,xto[ix]); /* replace with corresponding xto[]*/ |
break; } /* no need to check further */ |
break; } /* no need to check further */ |
|
for( ix=0; (xdelim=textdelims[ix]) != NULL; ix++ ) |
|
if ( strstr(lrdelim,xdelim) != 0 ) /* found textstyle delim */ |
|
{ if ( idelim == 1 ) /* if it's the \left one */ |
|
istextleft = 1; /* set left textstyle flag */ |
|
else istextright = 1; /* else set right textstyle flag */ |
|
break; } /* no need to check further */ |
} /* --- end-of-for(idelim) --- */ |
} /* --- end-of-for(idelim) --- */ |
/* --- debugging --- */ |
/* --- debugging --- */ |
if ( msgfp!=NULL && msglevel>=99 ) |
if ( msgfp!=NULL && msglevel>=99 ) |
Line 5419 rasterize delimiters, reset baselines, a
|
Line 6174 rasterize delimiters, reset baselines, a
|
isleftdot = (strchr(ldelim,'.')!=NULL); /* true if \left. */ |
isleftdot = (strchr(ldelim,'.')!=NULL); /* true if \left. */ |
isrightdot = (strchr(rdelim,'.')!=NULL); /* true if \right. */ |
isrightdot = (strchr(rdelim,'.')!=NULL); /* true if \right. */ |
/* --- get rasters for best-fit delim characters, add sub/superscripts --- */ |
/* --- get rasters for best-fit delim characters, add sub/superscripts --- */ |
isdisplaystyle = 9; /* force \displaystyle */ |
isdisplaystyle = (istextleft?0:9); /* force \displaystyle */ |
if ( !isleftdot ) /* if not \left. */ |
if ( !isleftdot ) /* if not \left. */ |
{ /* --- first get requested \left delimiter --- */ |
{ /* --- first get requested \left delimiter --- */ |
lp = get_delim(ldelim,rheight,family); /* get \left delim char */ |
lp = get_delim(ldelim,rheight,family); /* get \left delim char */ |
Line 5431 if ( !isleftdot ) /* if not \left. */
|
Line 6186 if ( !isleftdot ) /* if not \left. */
|
rheight = lheight-1; } /* make sure right delim matches */ |
rheight = lheight-1; } /* make sure right delim matches */ |
/* --- then add on any sub/superscripts attached to \left( --- */ |
/* --- then add on any sub/superscripts attached to \left( --- */ |
lp = rastlimits(&pleft,size,lp); } /*\left(_a^b and push pleft past b*/ |
lp = rastlimits(&pleft,size,lp); } /*\left(_a^b and push pleft past b*/ |
isdisplaystyle = 9; /* force \displaystyle */ |
isdisplaystyle = (istextright?0:9); /* force \displaystyle */ |
if ( !isrightdot ) /* and if not \right. */ |
if ( !isrightdot ) /* and if not \right. */ |
{ /* --- first get requested \right delimiter --- */ |
{ /* --- first get requested \right delimiter --- */ |
rp = get_delim(rdelim,rheight,family); /* get \right delim char */ |
rp = get_delim(rdelim,rheight,family); /* get \right delim char */ |
Line 5466 end_of_job:
|
Line 6221 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: rastright ( expression, size, basesp, ildelim, arg2, arg3 ) |
|
* Purpose: ...\right handler, intercepts an unexpected/unbalanced \right |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I) char ** to first char of null-terminated |
|
* string beginning with a \right |
|
* to be rasterized |
|
* size (I) int containing 0-5 default font size |
|
* basesp (I) subraster * to character (or subexpression) |
|
* immediately preceding leading left{ |
|
* (unused, but passed for consistency) |
|
* ildelim (I) int containing rdelims[] index of |
|
* right delimiter |
|
* arg2 (I) int unused |
|
* arg3 (I) int unused |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( subraster * ) ptr to subraster corresponding to subexpr, |
|
* or NULL for any parsing error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
subraster *rastright ( char **expression, int size, subraster *basesp, |
|
int ildelim, int arg2, int arg3 ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
subraster /* *rasterize(),*/ *sp=NULL; /*rasterize \right subexpr's*/ |
|
if ( sp != NULL ) /* returning entire expression */ |
|
{ |
|
isreplaceleft = 1; /* set flag to replace left half*/ |
|
} |
|
return ( sp ); |
|
} /* --- end-of-function rastright() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: rastmiddle ( expression, size, basesp, arg1, arg2, arg3 ) |
|
* Purpose: \middle handler, returns subraster corresponding to |
|
* entire expression with \middle delimiter(s) sized to fit. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I/O) char ** to first char of null-terminated |
|
* string immediately following \middle to be |
|
* rasterized, and returning ptr immediately |
|
* to terminating null. |
|
* size (I) int containing 0-5 default font size |
|
* basesp (I) subraster * to character (or subexpression) |
|
* immediately preceding \middle |
|
* (unused, but passed for consistency) |
|
* arg1 (I) int unused |
|
* arg2 (I) int unused |
|
* arg3 (I) int unused |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( subraster * ) ptr to subraster corresponding to expression, |
|
* or NULL for any parsing error |
|
* (expression ptr unchanged if error occurs) |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
subraster *rastmiddle ( char **expression, int size, subraster *basesp, |
|
int arg1, int arg2, int arg3 ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
subraster *rasterize(), *sp=NULL, *subsp[32]; /*rasterize \middle subexpr's*/ |
|
char *exprptr = *expression, /* local copy of ptr to expression */ |
|
*texchar(), delim[32][132], /* delimiters following \middle's */ |
|
*strtexchr(), /* locate \middle's */ |
|
subexpr[8193], *subptr=NULL; /* subexpression between \middle's */ |
|
int height=0, habove=0, hbelow=0; /* height, above & below baseline */ |
|
int idelim, ndelims=0, /* \middle count (max 32) */ |
|
family = CMSYEX; /* delims from CMSY10 or CMEX10 */ |
|
subraster *subrastcpy(), /* copy subraster */ |
|
*rastcat(), /* concatanate subraster */ |
|
*get_delim(); /* get rasterized delimiter */ |
|
int delete_subraster(); /* free work area subsp[]'s at eoj */ |
|
/* ------------------------------------------------------------------------- |
|
initialization |
|
-------------------------------------------------------------------------- */ |
|
subsp[0] = leftexpression; /* expressn preceding 1st \middle */ |
|
subsp[1] = NULL; /* set first null */ |
|
/* ------------------------------------------------------------------------- |
|
accumulate subrasters between consecutive \middle\delim...\middle\delim...'s |
|
-------------------------------------------------------------------------- */ |
|
while ( ndelims < 30 ) /* max of 31 \middle's */ |
|
{ |
|
/* --- maintain max height above,below baseline --- */ |
|
if ( subsp[ndelims] != NULL ) /*exprssn preceding current \middle*/ |
|
{ int baseline = (subsp[ndelims])->baseline; /* #rows above baseline */ |
|
height = ((subsp[ndelims])->image)->height; /* tot #rows (height) */ |
|
habove = max2(habove,baseline); /* max #rows above baseline */ |
|
hbelow = max2(hbelow,height-baseline); } /* max #rows below baseline */ |
|
/* --- get delimter after \middle --- */ |
|
skipwhite(exprptr); /*skip space betwn \middle & \delim*/ |
|
exprptr = texchar(exprptr,delim[ndelims]); /* \delim after \middle */ |
|
if ( *(delim[ndelims]) == '\000' ) /* \middle at end-of-expression */ |
|
break; /* ignore it and consider job done */ |
|
ndelims++; /* count another \middle\delim */ |
|
/* --- get subexpression between \delim and next \middle --- */ |
|
subsp[ndelims] = NULL; /* no subexpresion yet */ |
|
if ( *exprptr == '\000' ) /* end-of-expression after \delim */ |
|
break; /* so we have all subexpressions */ |
|
if ( (subptr = strtexchr(exprptr,"\\middle")) /* find next \middle */ |
|
== NULL ) /* no more \middle's */ |
|
{ strncpy(subexpr,exprptr,8192); /* get entire remaining expression */ |
|
subexpr[8192] = '\000'; /* make sure it's null-terminated */ |
|
exprptr += strlen(exprptr); } /* push exprptr to terminating '\0'*/ |
|
else /* have another \middle */ |
|
{ int sublen = (int)(subptr-exprptr); /* #chars between \delim...\middle*/ |
|
memcpy(subexpr,exprptr,min2(sublen,8192)); /* get subexpression */ |
|
subexpr[min2(sublen,8192)] = '\000'; /* and null-terminate it */ |
|
exprptr += (sublen+strlen("\\middle")); } /* push exprptr past \middle*/ |
|
/* --- rasterize subexpression --- */ |
|
subsp[ndelims] = rasterize(subexpr,size); /* rasterize subexpresion */ |
|
} /* --- end-of-while(1) --- */ |
|
/* ------------------------------------------------------------------------- |
|
construct \middle\delim's and concatanate them between subexpressions |
|
-------------------------------------------------------------------------- */ |
|
if ( ndelims < 1 /* no delims */ |
|
|| (height=habove+hbelow) < 1 ) /* or no subexpressions? */ |
|
goto end_of_job; /* just flush \middle directive */ |
|
for ( idelim=0; idelim<=ndelims; idelim++ ) |
|
{ |
|
/* --- first add on subexpression preceding delim --- */ |
|
if ( subsp[idelim] != NULL ) /* have subexpr preceding delim */ |
|
if ( sp == NULL ) /* this is first piece */ |
|
{ sp = subsp[idelim]; /* so just use it */ |
|
if ( idelim == 0 ) sp = subrastcpy(sp); } /* or copy leftexpression */ |
|
else sp = rastcat(sp,subsp[idelim],(idelim>0?3:1)); /* or concat it */ |
|
/* --- now construct delimiter --- */ |
|
if ( *(delim[idelim]) != '\000' ) /* have delimter */ |
|
{ subraster *delimsp = get_delim(delim[idelim],height,family); |
|
if ( delimsp != NULL ) /* rasterized delim */ |
|
{ delimsp->baseline = habove; /* set baseline */ |
|
if ( sp == NULL ) /* this is first piece */ |
|
sp = delimsp; /* so just use it */ |
|
else sp = rastcat(sp,delimsp,3); } } /*or concat to existing pieces*/ |
|
} /* --- end-of-for(idelim) --- */ |
|
/* --- back to caller --- */ |
|
end_of_job: |
|
if ( 0 ) /* now handled above */ |
|
for ( idelim=1; idelim<=ndelims; idelim++ ) /* free subsp[]'s (not 0) */ |
|
if ( subsp[idelim] != NULL ) /* have allocated subraster */ |
|
delete_subraster(subsp[idelim]); /* so free it */ |
|
if ( sp != NULL ) /* returning entire expression */ |
|
{ int newht = (sp->image)->height; /* height of returned subraster */ |
|
sp->baseline = min2(newht-1,newht/2+5); /* guess new baseline */ |
|
isreplaceleft = 1; /* set flag to replace left half*/ |
|
*expression += strlen(*expression); } /* and push to terminating null*/ |
|
return ( sp ); |
|
} /* --- end-of-function rastmiddle() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: rastflags ( expression, size, basesp, flag, value, arg3 ) |
* Function: rastflags ( expression, size, basesp, flag, value, arg3 ) |
* Purpose: sets an internal flag, e.g., for \rm, or sets an internal |
* Purpose: sets an internal flag, e.g., for \rm, or sets an internal |
* value, e.g., for \unitlength=<value>, and returns NULL |
* value, e.g., for \unitlength=<value>, and returns NULL |
Line 5476 end_of_job:
|
Line 6387 end_of_job:
|
* size (I) int containing base font size (not used, |
* size (I) int containing base font size (not used, |
* just stored in subraster) |
* just stored in subraster) |
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding space, whose baseline |
* immediately preceding "flags" directive |
* and height params are transferred to space |
* (unused but passed for consistency) |
* flag (I) int containing #define'd symbol specifying |
* flag (I) int containing #define'd symbol specifying |
* internal flag to be set |
* internal flag to be set |
* value (I) int containing new value of flag |
* value (I) int containing new value of flag |
Line 5507 set flag or value
|
Line 6418 set flag or value
|
switch ( flag ) |
switch ( flag ) |
{ |
{ |
default: break; /* unrecognized flag */ |
default: break; /* unrecognized flag */ |
case ISTEXT: |
case ISFONTFAM: |
if ( isthischar((*(*expression)),WHITEMATH) ) /* \rm followed by white */ |
if ( isthischar((*(*expression)),WHITEMATH) ) /* \rm followed by white */ |
(*expression)++; /* skip leading ~ after \rm */ |
(*expression)++; /* skip leading ~ after \rm */ |
istext=value; /* set text mode */ |
fontnum = value; /* set font family */ |
break; |
break; |
case ISSTRING: isstring=value; break; /* set string/image mode */ |
case ISSTRING: isstring=value; break; /* set string/image mode */ |
case ISDISPLAYSTYLE: /* set \displaystyle mode */ |
case ISDISPLAYSTYLE: /* set \displaystyle mode */ |
Line 5541 switch ( flag )
|
Line 6452 switch ( flag )
|
case ISADJACENTWT: /* set lowpass adjacent weight */ |
case ISADJACENTWT: /* set lowpass adjacent weight */ |
case ISCORNERWT: /* set lowpass corner weight */ |
case ISCORNERWT: /* set lowpass corner weight */ |
case ISCOLOR: /* set red(1),green(2),blue(3) */ |
case ISCOLOR: /* set red(1),green(2),blue(3) */ |
case ISSQUASH: /* set (minimum) "squash" margin */ |
case ISSMASH: /* set (minimum) "smash" margin */ |
if ( value != NOVALUE ) /* passed a fixed value to be set */ |
if ( value != NOVALUE ) /* passed a fixed value to be set */ |
argvalue = value; /* set given fixed value */ |
argvalue = value; /* set given fixed value */ |
else /* get value from expression */ |
else /* get value from expression */ |
Line 5578 switch ( flag )
|
Line 6489 switch ( flag )
|
fontsize = (isdelta? fontsize+argvalue : argvalue); |
fontsize = (isdelta? fontsize+argvalue : argvalue); |
fontsize = max2(0,min2(fontsize,largestsize)); |
fontsize = max2(0,min2(fontsize,largestsize)); |
shrinkfactor = shrinkfactors[fontsize]; |
shrinkfactor = shrinkfactors[fontsize]; |
if ( isdisplaystyle == 1 ) /* displaystyle enabled but not set*/ |
if ( isdisplaystyle == 1 /* displaystyle enabled but not set*/ |
|
|| (1 && isdisplaystyle==2) /* displaystyle enabled and set */ |
|
|| (0 && isdisplaystyle==0) )/*\textstyle disabled displaystyle*/ |
if ( displaystylelevel != recurlevel ) /*respect \displaystyle*/ |
if ( displaystylelevel != recurlevel ) /*respect \displaystyle*/ |
if ( !ispreambledollars ) /* respect $$...$$'s */ |
if ( !ispreambledollars ) /* respect $$...$$'s */ |
isdisplaystyle = (fontsize>=displaysize? 2:1); /* forced */ |
if ( fontsize >= displaysize ) |
|
isdisplaystyle = 2; /* forced */ |
|
else isdisplaystyle = 1; |
/*displaystylelevel = (-99);*/ } /* reset \displaystyle level */ |
/*displaystylelevel = (-99);*/ } /* reset \displaystyle level */ |
else /* embed font size in expression */ |
else /* embed font size in expression */ |
{ sprintf(valuearg,"%d",fontsize); /* convert size */ |
{ sprintf(valuearg,"%d",fontsize); /* convert size */ |
Line 5594 switch ( flag )
|
Line 6509 switch ( flag )
|
if ( argvalue != NOVALUE ) /* got a value */ |
if ( argvalue != NOVALUE ) /* got a value */ |
displaysize = (isdelta? displaysize+argvalue : argvalue); |
displaysize = (isdelta? displaysize+argvalue : argvalue); |
break; |
break; |
case ISSQUASH: /* set (minimum) "squash" margin */ |
case ISSMASH: /* set (minimum) "smash" margin */ |
if ( argvalue != NOVALUE ) /* got a value */ |
if ( argvalue != NOVALUE ) /* got a value */ |
{ squashmargin = argvalue; /* set value */ |
{ smashmargin = argvalue; /* set value */ |
if ( arg3 != NOVALUE ) isdelta=arg3; /* hard-coded isdelta */ |
if ( arg3 != NOVALUE ) isdelta=arg3; /* hard-coded isdelta */ |
issquashdelta = (isdelta?1:0); } /* and set delta flag */ |
issmashdelta = (isdelta?1:0); } /* and set delta flag */ |
squashmargin = max2((isdelta?-5:0),min2(squashmargin,32)); /*sanity*/ |
smashmargin = max2((isdelta?-5:0),min2(smashmargin,32)); /*sanity*/ |
break; |
break; |
case ISSHRINK: /* set shrinkfactor */ |
case ISSHRINK: /* set shrinkfactor */ |
if ( argvalue != NOVALUE ) /* got a value */ |
if ( argvalue != NOVALUE ) /* got a value */ |
Line 5701 int pixsz = 1; /*default #bits per pix
|
Line 6616 int pixsz = 1; /*default #bits per pix
|
char *texsubexpr(), widtharg[256]; /* parse for optional {width} */ |
char *texsubexpr(), widtharg[256]; /* parse for optional {width} */ |
subraster *rasterize(), *rightsp=NULL; /*rasterize right half of expression*/ |
subraster *rasterize(), *rightsp=NULL; /*rasterize right half of expression*/ |
subraster *rastcat(); /* cat rightsp after \hfill */ |
subraster *rastcat(); /* cat rightsp after \hfill */ |
int blanksignal = (-991234); /*rastsquash signal right-hand blank*/ |
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 5767 return ( spacesp );
|
Line 6681 return ( spacesp );
|
* string immediately following \\ to be |
* string immediately following \\ to be |
* rasterized, and returning ptr immediately |
* rasterized, and returning ptr immediately |
* to terminating null. |
* to terminating null. |
* size (I) int containing 0-4 default font size |
* size (I) int containing 0-5 default font size |
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding \accent |
* immediately preceding \\ |
* (unused, but passed for consistency) |
* (unused, but passed for consistency) |
* arg1 (I) int unused |
* arg1 (I) int unused |
* arg2 (I) int unused |
* arg2 (I) int unused |
Line 5812 rasterize right half of expression and s
|
Line 6726 rasterize right half of expression and s
|
if ( (rightsp=rasterize(*expression,size)) /* rasterize right half */ |
if ( (rightsp=rasterize(*expression,size)) /* rasterize right half */ |
== NULL ) goto end_of_job; /* quit if failed */ |
== NULL ) goto end_of_job; /* quit if failed */ |
/* --- stack left half above it --- */ |
/* --- stack left half above it --- */ |
newlsp = rastack(rightsp,leftexpression,1,vspace,0,3); /*right under left*/ |
/*newlsp = rastack(rightsp,leftexpression,1,vspace,0,3);*//*right under left*/ |
|
newlsp = rastack(rightsp,leftexpression,1,vspace,0,1); /*right under left*/ |
/* --- back to caller --- */ |
/* --- back to caller --- */ |
end_of_job: |
end_of_job: |
if ( newlsp != NULL ) /* returning entire expression */ |
if ( newlsp != NULL ) /* returning entire expression */ |
Line 6166 int baseht=0, baseln=0; /* height,basel
|
Line 7081 int baseht=0, baseln=0; /* height,basel
|
/*int istweak = 1;*/ /*true to tweak baseline alignment*/ |
/*int istweak = 1;*/ /*true to tweak baseline alignment*/ |
int rule_raster(), /* draw horizontal line for frac */ |
int rule_raster(), /* draw horizontal line for frac */ |
lineheight = 1; /* thickness of fraction line */ |
lineheight = 1; /* thickness of fraction line */ |
int vspace = 1; /*vertical space between components*/ |
int vspace = (size>2?2:1); /*vertical space between components*/ |
int delete_subraster(); /*free work areas in case of error*/ |
int delete_subraster(); /*free work areas in case of error*/ |
int type_raster(); /* display debugging output */ |
int type_raster(); /* display debugging output */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 6588 subwidth = (subsp->image)->width; /* an
|
Line 7503 subwidth = (subsp->image)->width; /* an
|
pixsz = (subsp->image)->pixsz; /* original pixsz remains constant */ |
pixsz = (subsp->image)->pixsz; /* original pixsz remains constant */ |
/* --- determine desired width, height of accent --- */ |
/* --- determine desired width, height of accent --- */ |
accwidth = subwidth; /* same width as subexpr */ |
accwidth = subwidth; /* same width as subexpr */ |
accheight = 3; /* default for bars */ |
accheight = 4; /* default for bars */ |
switch ( accent ) |
switch ( accent ) |
{ default: break; /* default okay */ |
{ default: break; /* default okay */ |
case DOTACCENT: case DDOTACCENT: |
case DOTACCENT: case DDOTACCENT: |
accheight = (size<3? 3:4); /* default for dots */ |
accheight = (size<4? 3:4); /* default for dots */ |
break; |
break; |
case HATACCENT: case VECACCENT: |
case VECACCENT: |
|
vspace = 1; /* set 1-pixel vertical space */ |
|
case HATACCENT: |
accheight = 7; /* default */ |
accheight = 7; /* default */ |
if ( subwidth < 10 ) accheight = 5; /* unless small width */ |
if ( subwidth < 10 ) accheight = 5; /* unless small width */ |
else if ( subwidth > 25 ) accheight = 9; /* or large */ |
else if ( subwidth > 25 ) accheight = 9; /* or large */ |
Line 6640 end_of_job:
|
Line 7557 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: rastfont (expression,size,basesp,font,arg2,arg3) |
* Function: rastfont (expression,size,basesp,ifontnum,arg2,arg3) |
* Purpose: \cal{}, \scr{}, \etc handler, returns subraster corresponding |
* Purpose: \cal{}, \scr{}, \etc handler, returns subraster corresponding |
* to char(s) within {}'s rendered at size |
* to char(s) within {}'s rendered at size |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 6652 end_of_job:
|
Line 7569 end_of_job:
|
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding \accent |
* immediately preceding \accent |
* (unused, but passed for consistency) |
* (unused, but passed for consistency) |
* font (I) int containing 1 for \cal{}, 2 for \scr{} |
* ifontnum (I) int containing 1 for \cal{}, 2 for \scr{} |
* arg2 (I) int unused |
* arg2 (I) int unused |
* arg3 (I) int unused |
* arg3 (I) int unused |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 6663 end_of_job:
|
Line 7580 end_of_job:
|
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
subraster *rastfont ( char **expression, int size, subraster *basesp, |
subraster *rastfont ( char **expression, int size, subraster *basesp, |
int font, int arg2, int arg3 ) |
int ifontnum, int arg2, int arg3 ) |
{ |
{ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
Line 6671 Allocations and Declarations
|
Line 7588 Allocations and Declarations
|
char *texsubexpr(), fontchars[8192], /*parse chars to be rendered in font*/ |
char *texsubexpr(), fontchars[8192], /*parse chars to be rendered in font*/ |
subexpr[8192]; /* turn \cal{AB} into \calA\calB */ |
subexpr[8192]; /* turn \cal{AB} into \calA\calB */ |
char *pfchars=fontchars, fchar='\0'; /* run thru fontchars one at a time*/ |
char *pfchars=fontchars, fchar='\0'; /* run thru fontchars one at a time*/ |
char *name = NULL; /* fonts[font].name */ |
char *name = NULL; /* fontinfo[ifontnum].name */ |
int class = 0, /* fonts[font].class */ |
int family = 0, /* fontinfo[ifontnum].family */ |
istext = 0; /* set true for text type */ |
istext = 0, /* fontinfo[ifontnum].istext */ |
|
class = 0; /* fontinfo[ifontnum].class */ |
subraster *rasterize(), *fontsp=NULL, /* rasterize chars in font */ |
subraster *rasterize(), *fontsp=NULL, /* rasterize chars in font */ |
*rastflags(); /* or just set flag to switch font */ |
*rastflags(); /* or just set flag to switch font */ |
int oldsquashmargin = squashmargin; /* turn off squash in text mode */ |
int oldsmashmargin = smashmargin; /* turn off smash in text mode */ |
int blanksignal = (-991234); /*rastsquash signal right-hand blank*/ |
#if 0 |
/* --- fonts recognized by rastfont --- */ |
/* --- fonts recognized by rastfont --- */ |
static int nfonts = 5; /* legal font #'s are 1...nfonts */ |
static int nfonts = 6; /* legal font #'s are 1...nfonts */ |
static struct {char *name; int class;} |
static struct {char *name; int class;} |
fonts[] = |
fonts[] = |
{ /* --- name class 1=upper,2=alpha,3=alnum,4=lower,5=digit,9=all --- */ |
{ /* --- name class 1=upper,2=alpha,3=alnum,4=lower,5=digit,9=all --- */ |
{ "\\badfont", 0 }, |
{ "\\math", 0 }, |
{ "\\cal", 1 }, /*(1) calligraphic, uppercase */ |
{ "\\mathcal", 1 }, /*(1) calligraphic, uppercase */ |
{ "\\scr", 1 }, /*(2) rsfs/script, uppercase */ |
{ "\\mathscr", 1 }, /*(2) rsfs/script, uppercase */ |
{ "\\rm", -1 }, /*(3) \rm,\text{abc} --> {\rm~abc} */ |
{ "\\textrm", -1 }, /*(3) \rm,\text{abc} --> {\rm~abc} */ |
{ "\\it", -1 }, /*(4) \it,\textit{abc}-->{\it~abc} */ |
{ "\\textit", -1 }, /*(4) \it,\textit{abc}-->{\it~abc} */ |
{ "\\bb", -1 }, /*(5) \bb,\mathbb{abc}-->{\bb~abc} */ |
{ "\\mathbb", -1 }, /*(5) \bb,\mathbb{abc}-->{\bb~abc} */ |
|
{ "\\mathbf", -1 }, /*(6) \bf,\mathbf{abc}-->{\bf~abc} */ |
{ NULL, 0 } |
{ NULL, 0 } |
} ; /* --- end-of-fonts[] --- */ |
} ; /* --- end-of-fonts[] --- */ |
|
#endif |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
first get font name and class to determine type of conversion desired |
first get font name and class to determine type of conversion desired |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( font<=0 || font>nfonts ) font=0; /* set error if out-of-bounds */ |
if (ifontnum<=0 || ifontnum>nfontinfo) ifontnum=0; /*math if out-of-bounds*/ |
name = fonts[font].name; /* font name */ |
name = fontinfo[ifontnum].name; /* font name */ |
class = fonts[font].class; /* font class */ |
family = fontinfo[ifontnum].family; /* font family */ |
if ( font==3 || font==4 ) /* text (respect blanks) */ |
istext = fontinfo[ifontnum].istext; /*true in text mode (respect space)*/ |
{ istext = 1; /* signal text mode */ |
class = fontinfo[ifontnum].class; /* font class */ |
squashmargin = 0; } /* don't squash internal blanks */ |
if ( istext ) /* text (respect blanks) */ |
|
smashmargin = 0; /* don't smash internal blanks */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
now convert \font{abc} --> {\font~abc}, or convert ABC to \calA\calB\calC |
now convert \font{abc} --> {\font~abc}, or convert ABC to \calA\calB\calC |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( class < 0 ) /* not character-by-character */ |
if ( 1 || class<0 ) /* not character-by-character */ |
{ |
{ |
/* --- |
/* --- |
if \font not immediately followed by { then it has no arg, so just set flag |
if \font not immediately followed by { then it has no arg, so just set flag |
Line 6711 if ( class < 0 ) /* not character-by-c
|
Line 7632 if ( class < 0 ) /* not character-by-c
|
if ( *(*expression) != '{' ) /* no \font arg, so just set flag */ |
if ( *(*expression) != '{' ) /* no \font arg, so just set flag */ |
{ |
{ |
if ( msgfp!=NULL && msglevel>=99 ) |
if ( msgfp!=NULL && msglevel>=99 ) |
fprintf(msgfp,"rastfont> \\%s rastflags() for font#%d\n",name,font); |
fprintf(msgfp,"rastfont> \\%s rastflags() for font#%d\n",name,ifontnum); |
switch ( font ) /* set flag by our internal font# */ |
fontsp = rastflags(expression,size,basesp,ISFONTFAM,ifontnum,arg3); |
{ case 3: /* \rm, \text sets flag istext=1 */ |
|
fontsp = rastflags(expression,size,basesp,ISTEXT,1,arg3); break; |
|
case 4: /* \it, \text sets flag istext=2 */ |
|
fontsp = rastflags(expression,size,basesp,ISTEXT,2,arg3); break; |
|
case 5: /* \bb, \mathbb sets flag istext=3 */ |
|
fontsp = rastflags(expression,size,basesp,ISTEXT,3,arg3); break; |
|
default: break; } /* unrecognized, set no flags */ |
|
goto end_of_job; |
goto end_of_job; |
} /* --- end-of-if(*(*expression)!='{') --- */ |
} /* --- end-of-if(*(*expression)!='{') --- */ |
/* --- |
/* --- |
Line 6752 else /* character-by-character */
|
Line 7666 else /* character-by-character */
|
for ( pfchars=fontchars; (fchar= *pfchars)!='\000'; pfchars++ ) |
for ( pfchars=fontchars; (fchar= *pfchars)!='\000'; pfchars++ ) |
{ |
{ |
if ( isthischar(fchar,WHITEMATH) ) /* some whitespace */ |
if ( isthischar(fchar,WHITEMATH) ) /* some whitespace */ |
{ if ( 0 || istext ) /* and we're in a text mode */ |
{ if ( 0 || istext ) /* and we're in a text mode font */ |
strcat(subexpr,"\\;"); } /* so respect whitespace */ |
strcat(subexpr,"\\;"); } /* so respect whitespace */ |
else /* char to be displayed in font */ |
else /* char to be displayed in font */ |
{ int exprlen = 0; /* #chars in subexpr before fchar */ |
{ int exprlen = 0; /* #chars in subexpr before fchar */ |
int isinclass = 0; /* set true if fchar in font class */ |
int isinclass = 0; /* set true if fchar in font class */ |
|
/* --- class: 1=upper, 2=alpha, 3=alnum, 4=lower, 5=digit, 9=all --- */ |
switch ( class ) /* check if fchar is in font class */ |
switch ( class ) /* check if fchar is in font class */ |
{ default: break; /* no chars in unrecognized class */ |
{ default: break; /* no chars in unrecognized class */ |
case 1: if ( isupper((int)fchar) ) isinclass=1; break; |
case 1: if ( isupper((int)fchar) ) isinclass=1; break; |
Line 6790 if ( (fontsp = rasterize(subexpr,size))
|
Line 7705 if ( (fontsp = rasterize(subexpr,size))
|
back to caller with chars rendered in font |
back to caller with chars rendered in font |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
end_of_job: |
end_of_job: |
squashmargin = oldsquashmargin; /* restore squash */ |
smashmargin = oldsmashmargin; /* restore smash */ |
if ( istext && fontsp!=NULL ) /* raster contains text */ |
if ( istext && fontsp!=NULL ) /* raster contains text mode font */ |
fontsp->type = blanksignal; /* signal nosquash */ |
fontsp->type = blanksignal; /* signal nosmash */ |
return ( fontsp ); /* chars rendered in font */ |
return ( fontsp ); /* chars rendered in font */ |
} /* --- end-of-function rastfont() --- */ |
} /* --- end-of-function rastfont() --- */ |
|
|
Line 7328 while ( 1 ) /* scan chars till end */
|
Line 8243 while ( 1 ) /* scan chars till end */
|
{ skipwhite(tokptr); /* flush whitespace after \hline */ |
{ skipwhite(tokptr); /* flush whitespace after \hline */ |
if ( *tokptr == '\000' /* end-of-expression after \hline */ |
if ( *tokptr == '\000' /* end-of-expression after \hline */ |
|| isthischar(*tokptr,coldelim) ) /* or unescaped coldelim */ |
|| isthischar(*tokptr,coldelim) ) /* or unescaped coldelim */ |
istokwhite = ishonly = 1; /* so token contains \hline only */ |
{ istokwhite = 1; /* so token contains \hline only */ |
|
if ( iseox ) ishonly = 1; } /* ignore entire row at eox */ |
else /* token contains more than \hline */ |
else /* token contains more than \hline */ |
strcpy(token,tokptr); } /* so flush \hline from token */ |
strcpy(token,tokptr); } /* so flush \hline from token */ |
} /* --- end-of-if(ncols[nrows]==0) --- */ |
} /* --- end-of-if(ncols[nrows]==0) --- */ |
Line 7452 for ( irow=0; irow<=nrows; irow++ ) /*to
|
Line 8368 for ( irow=0; irow<=nrows; irow++ ) /*to
|
for ( icol=0; icol<ncols[irow]; icol++ ) /* go through cells in this row */ |
for ( icol=0; icol<ncols[irow]; icol++ ) /* go through cells in this row */ |
{ |
{ |
subraster *tsp = toksp[itoken]; /* token that belongs in this cell */ |
subraster *tsp = toksp[itoken]; /* token that belongs in this cell */ |
|
/* --- first adjust leftcol for vline to left of icol, if present ---- */ |
|
leftcol += vlinespace(icol); /* space for vline to left of col */ |
|
/* --- now rasterize cell ---- */ |
if ( tsp != NULL ) /* have a rasterized cell token */ |
if ( tsp != NULL ) /* have a rasterized cell token */ |
{ |
{ |
/* --- local parameters --- */ |
/* --- local parameters --- */ |
Line 7461 for ( irow=0; irow<=nrows; irow++ ) /*to
|
Line 8380 for ( irow=0; irow<=nrows; irow++ ) /*to
|
tokencol = 0, /*H offset (init for left justify)*/ |
tokencol = 0, /*H offset (init for left justify)*/ |
tokenrow = baseline - tsp->baseline;/*V offset (init for baseline)*/ |
tokenrow = baseline - tsp->baseline;/*V offset (init for baseline)*/ |
/* --- adjust leftcol for vline to left of icol, if present ---- */ |
/* --- adjust leftcol for vline to left of icol, if present ---- */ |
leftcol += vlinespace(icol); /* space for vline to left of col */ |
/*leftcol += vlinespace(icol);*/ /* space for vline to left of col */ |
/* --- reset justification (if not left-justified) --- */ |
/* --- reset justification (if not left-justified) --- */ |
if ( justify[icol] == 0 ) /* but user wants it centered */ |
if ( justify[icol] == 0 ) /* but user wants it centered */ |
tokencol = (cwidth-twidth+1)/2; /* so split margin left/right */ |
tokencol = (cwidth-twidth+1)/2; /* so split margin left/right */ |
Line 7761 char *texsubexpr(),linexpr[257], *xptr=l
|
Line 8680 char *texsubexpr(),linexpr[257], *xptr=l
|
subraster *new_subraster(), *linesp=NULL; /* subraster for line */ |
subraster *new_subraster(), *linesp=NULL; /* subraster for line */ |
/*char *origexpression = *expression;*/ /*original expression after \line*/ |
/*char *origexpression = *expression;*/ /*original expression after \line*/ |
int pixsz = 1; /* pixels are one bit each */ |
int pixsz = 1; /* pixels are one bit each */ |
|
int thickness = 1; /* line thickness */ |
double strtod(), /* convert ascii params to doubles */ |
double strtod(), /* convert ascii params to doubles */ |
xinc=0.0, yinc=0.0, /* x,y-increments for line, */ |
xinc=0.0, yinc=0.0, /* x,y-increments for line, */ |
xlen=0.0, ylen=0.0; /* x,y lengths for line */ |
xlen=0.0, ylen=0.0; /* x,y lengths for line */ |
int width=0, height=0; /* #pixels width,height of line */ |
int width=0, height=0, /* #pixels width,height of line */ |
|
rwidth=0, rheight=0; /*alloc width,height plus thickness*/ |
int istop=0, isright=0, /* origin at bot-left if x,yinc>=0 */ |
int istop=0, isright=0, /* origin at bot-left if x,yinc>=0 */ |
origin = 0; /* x,yinc: ++=00 +-=01 -+=10 --=11 */ |
origin = 0; /* x,yinc: ++=00 +-=01 -+=10 --=11 */ |
int line_raster(); /* draw line in linesp->image */ |
int line_raster(); /* draw line in linesp->image */ |
Line 7774 obtain (xinc,yinc) arguments immediately
|
Line 8695 obtain (xinc,yinc) arguments immediately
|
/* --- parse for (xinc,yinc) arguments, and bump expression past it --- */ |
/* --- parse for (xinc,yinc) arguments, and bump expression past it --- */ |
*expression = texsubexpr(*expression,linexpr,253,"(",")",0,0); |
*expression = texsubexpr(*expression,linexpr,253,"(",")",0,0); |
if ( *linexpr == '\000' ) goto end_of_job; /* couldn't get (xinc,yinc) */ |
if ( *linexpr == '\000' ) goto end_of_job; /* couldn't get (xinc,yinc) */ |
/* --- now interpret xinc,yinc returned in linexpr --- */ |
/* --- now interpret xinc,yinc;thickness returned in linexpr --- */ |
|
if ( (xptr=strchr(linexpr,';')) != NULL ) /* look for ';' after xinc,yinc */ |
|
{ *xptr = '\000'; /* terminate linexpr at ; */ |
|
thickness = (int)strtol(xptr+1,NULL,10); } /* get int thickness */ |
if ( (xptr=strchr(linexpr,',')) != NULL ) /* look for ',' in xinc,yinc */ |
if ( (xptr=strchr(linexpr,',')) != NULL ) /* look for ',' in xinc,yinc */ |
*xptr = '\000'; /* found it, so replace ',' by '\0'*/ |
*xptr = '\000'; /* found it, so replace ',' by '\0'*/ |
if ( *linexpr != '\000' ) /* check against missing 1st arg */ |
if ( *linexpr != '\000' ) /* check against missing 1st arg */ |
Line 7803 calculate width,height, etc, based on xl
|
Line 8727 calculate width,height, etc, based on xl
|
xlen = absval(xlen); /* force xlen positive */ |
xlen = absval(xlen); /* force xlen positive */ |
ylen = absval(ylen); /* force ylen positive */ |
ylen = absval(ylen); /* force ylen positive */ |
/* --- calculate corresponding lengths in pixels --- */ |
/* --- calculate corresponding lengths in pixels --- */ |
width = max2(1,iround(unitlength*xlen)); /*scale by unitlength and round,*/ |
width = max2(1,iround(unitlength*xlen)); /*scale by unitlength and round,*/ |
height = max2(1,iround(unitlength*ylen)); /* and must be at least 1 pixel */ |
height = max2(1,iround(unitlength*ylen)); /* and must be at least 1 pixel */ |
|
rwidth = width + (ylen<0.001?0:max2(0,thickness-1)); |
|
rheight = height + (xlen<0.001?0:max2(0,thickness-1)); |
/* --- set origin corner, x,yinc's: ++=0=(0,0) +-=1=(0,1) -+=10=(1,0) --- */ |
/* --- set origin corner, x,yinc's: ++=0=(0,0) +-=1=(0,1) -+=10=(1,0) --- */ |
if ( xinc < 0.0 ) isright = 1; /*negative xinc, so corner is (1,?)*/ |
if ( xinc < 0.0 ) isright = 1; /*negative xinc, so corner is (1,?)*/ |
if ( yinc < 0.0 ) istop = 1; /*negative yinc, so corner is (?,1)*/ |
if ( yinc < 0.0 ) istop = 1; /*negative yinc, so corner is (?,1)*/ |
Line 7815 if ( msgfp!=NULL && msglevel>=29 ) /* de
|
Line 8741 if ( msgfp!=NULL && msglevel>=29 ) /* de
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
allocate subraster and raster for complete picture |
allocate subraster and raster for complete picture |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- sanity check on width,height args --- */ |
/* --- sanity check on width,height,thickness args --- */ |
if ( width < 1 || width > 600 |
if ( width < 1 || width > 600 |
|| height < 1 || height > 600 ) goto end_of_job; |
|| height < 1 || height > 600 |
|
|| thickness<1||thickness>25 ) goto end_of_job; |
/* --- allocate and initialize subraster for constructed line --- */ |
/* --- allocate and initialize subraster for constructed line --- */ |
if ( (linesp=new_subraster(width,height,pixsz)) /* allocate new subraster */ |
if ( (linesp=new_subraster(rwidth,rheight,pixsz)) /* alloc new subraster */ |
== NULL ) goto end_of_job; /* quit if failed */ |
== NULL ) goto end_of_job; /* quit if failed */ |
/* --- initialize line subraster parameters --- */ |
/* --- initialize line subraster parameters --- */ |
linesp->type = IMAGERASTER; /* image */ |
linesp->type = IMAGERASTER; /* image */ |
linesp->symdef = NULL; /* not applicable for image */ |
linesp->symdef = NULL; /* not applicable for image */ |
linesp->baseline = height/2 + 2; /* is a little above center good? */ |
linesp->baseline = height/2 + 2 /* is a little above center good? */ |
|
+ (rheight-height)/2; /* account for line thickness too */ |
linesp->size = size; /* size (probably unneeded) */ |
linesp->size = size; /* size (probably unneeded) */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
draw the line |
draw the line |
Line 7834 line_raster ( linesp->image, /* embedde
|
Line 8762 line_raster ( linesp->image, /* embedde
|
(isright? width-1 : 0), /* col0, from left or right */ |
(isright? width-1 : 0), /* col0, from left or right */ |
(istop? height-1 : 0), /* row1, to top or bottom */ |
(istop? height-1 : 0), /* row1, to top or bottom */ |
(isright? 0 : width-1), /* col1, to right or left */ |
(isright? 0 : width-1), /* col1, to right or left */ |
1 ); /* line thickness is 1 pixel */ |
thickness ); /* line thickness (usually 1 pixel)*/ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
return constructed line to caller |
return constructed line to caller |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 8381 char *texsubexpr(), tag[512]="\000", fil
|
Line 9309 char *texsubexpr(), tag[512]="\000", fil
|
subraster *rasterize(), *inputsp=NULL; /* rasterized input image */ |
subraster *rasterize(), *inputsp=NULL; /* rasterized input image */ |
int status, rastreadfile(); /* read input file */ |
int status, rastreadfile(); /* read input file */ |
int format=0, npts=0; /* don't reformat (numerical) input */ |
int format=0, npts=0; /* don't reformat (numerical) input */ |
char subexpr[8192], /* concatanated lines from input file */ |
char subexpr[8192] = "\000", /* concatanated lines from input file */ |
*mimeprep(), /* preprocess inputted data */ |
*mimeprep(), /* preprocess inputted data */ |
*dtoa(), *reformat=NULL; /* reformat numerical input */ |
*dbltoa(), *reformat=NULL; /* reformat numerical input */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
obtain [tag]{filename} argument |
obtain [tag]{filename} argument |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 8391 obtain [tag]{filename} argument
|
Line 9319 obtain [tag]{filename} argument
|
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
{ char argfld[2048]; /* optional argument field */ |
{ char argfld[2048]; /* optional argument field */ |
*expression = texsubexpr(*expression,argfld,2047,"[","]",0,0); |
*expression = texsubexpr(*expression,argfld,2047,"[","]",0,0); |
if ( (reformat=strstr(argfld,"dtoa")) != NULL ) /* dtoa requested */ |
if ( (reformat=strstr(argfld,"dtoa")) != NULL ) /*dtoa/dbltoa requested*/ |
{ format = 1; /* signal dtoa() format */ |
{ format = 1; /* signal dtoa()/dbltoa() format */ |
if ( (reformat=strchr(reformat,'=')) != NULL ) /* have dtoa= */ |
if ( (reformat=strchr(reformat,'=')) != NULL ) /* have dtoa= */ |
npts = (int)strtol(reformat+1,NULL,0); } /* so set npts */ |
npts = (int)strtol(reformat+1,NULL,0); } /* so set npts */ |
if ( format == 0 ) /* reformat not requested */ |
if ( format == 0 ) /* reformat not requested */ |
Line 8409 if ( *filename != '\000' /* got filenam
|
Line 9337 if ( *filename != '\000' /* got filenam
|
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
Read file and rasterize constructed subexpression |
Read file and rasterize constructed subexpression |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
status = rastreadfile(filename,tag,subexpr); /* read file */ |
status = rastreadfile(filename,0,tag,subexpr); /* read file */ |
if ( *subexpr == '\000' ) goto end_of_job; /* quit if problem */ |
if ( *subexpr == '\000' ) goto end_of_job; /* quit if problem */ |
/* --- rasterize input subexpression --- */ |
/* --- rasterize input subexpression --- */ |
mimeprep(subexpr); /* preprocess subexpression */ |
mimeprep(subexpr); /* preprocess subexpression */ |
if ( format == 1 ) /* dtoa() */ |
if ( format == 1 ) /* dtoa()/dbltoa() */ |
{ double d = strtod(subexpr,NULL); /* interpret subexpr as double */ |
{ double d = strtod(subexpr,NULL); /* interpret subexpr as double */ |
if ( d != 0.0 ) /* conversion to double successful */ |
if ( d != 0.0 ) /* conversion to double successful */ |
if ( (reformat=dtoa(d,npts)) != NULL ) /* reformat successful */ |
if ( (reformat=dbltoa(d,npts)) != NULL ) /* reformat successful */ |
strcpy(subexpr,reformat); } /*replace subexpr with reformatted*/ |
strcpy(subexpr,reformat); } /*replace subexpr with reformatted*/ |
inputsp = rasterize(subexpr,size); /* rasterize subexpression */ |
inputsp = rasterize(subexpr,size); /* rasterize subexpression */ |
/* --- return input image to caller --- */ |
/* --- return input image to caller --- */ |
Line 8447 end_of_job:
|
Line 9375 end_of_job:
|
* requested, or NULL for any parsing error |
* requested, or NULL for any parsing error |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Notes: o Summary of syntax... |
* Notes: o Summary of syntax... |
* \counter[value][logfile]{filename} |
* \counter[value][logfile]{filename:tag} |
* o |
* o :tag is optional |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
subraster *rastcounter ( char **expression, int size, subraster *basesp, |
subraster *rastcounter ( char **expression, int size, subraster *basesp, |
Line 8458 subraster *rastcounter ( char **expressi
|
Line 9386 subraster *rastcounter ( char **expressi
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
char *texsubexpr(), filename[1024]="\000", /* counter file */ |
char *texsubexpr(), filename[1024]="\000", /* counter file */ |
logfile[1024]="\000", tag[512]="\000"; /* log file and tag */ |
logfile[1024]="\000", tag[512]="\000"; /*optional log file and tag*/ |
subraster *rasterize(), *countersp=NULL; /* rasterized counter image */ |
subraster *rasterize(), *countersp=NULL; /* rasterized counter image */ |
FILE /* *fp=NULL,*/ *logfp=NULL; /* counter and log file pointers */ |
FILE /* *fp=NULL,*/ *logfp=NULL; /* counter and log file pointers */ |
int rastreadfile(), rastwritefile(); /* to read and write counter file */ |
int status=0,rastreadfile(),rastwritefile(), /*read,write counter file*/ |
char text[2048] = "1_", /* first (and only) line in counter file */ |
isstrict = 1; /* true to only write to existing files */ |
|
char text[8192] = "1_", /* only line in counter file without tags */ |
*delim = NULL, /* delimiter in text */ |
*delim = NULL, /* delimiter in text */ |
utext[32] = "1_", /* default delimiter */ |
utext[128] = "1_", /* default delimiter */ |
*udelim = utext+1; /* underscore delimiter */ |
*udelim = utext+1; /* underscore delimiter */ |
char *timestamp(), /* timestamp for logging */ |
char *rasteditfilename(), /* edit log file name */ |
*dtoa(); /* double to comma-separated */ |
*timestamp(), /* timestamp for logging */ |
|
*dbltoa(); /* double to comma-separated ascii */ |
int counter = 1, /* atoi(text) (after _ removed, if present) */ |
int counter = 1, /* atoi(text) (after _ removed, if present) */ |
gotcount = 0, /* set true once counter value determined */ |
value = 1, /* optional [value] argument */ |
|
gotvalue = 0, /* set true if [value] supplied */ |
|
isdelta = 0, /* set true if [+value] or [-value] is delta*/ |
ordindex = (-1); /* ordinal[] index to append ordinal suffix */ |
ordindex = (-1); /* ordinal[] index to append ordinal suffix */ |
/*--- ordinal suffixes based on units digit of counter ---*/ |
/*--- ordinal suffixes based on units digit of counter ---*/ |
static char *ordinal[]={"th","st","nd","rd","th","th","th","th","th","th"}; |
static char *ordinal[]={"th","st","nd","rd","th","th","th","th","th","th"}; |
Line 8480 first obtain optional [value][logfile] a
|
Line 9412 first obtain optional [value][logfile] a
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- first check for optional \counter[value] --- */ |
/* --- first check for optional \counter[value] --- */ |
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
{ *expression = texsubexpr(*expression,text,2047,"[","]",0,0); |
{ *expression = texsubexpr(*expression,text,1023,"[","]",0,0); |
if ( *text != '\000' ) /* got counter value */ |
if ( *text != '\000' ) /* got counter value (or logfile) */ |
if ( strlen(text) >= 1 ) /* and it's not an empty string */ |
if ( strlen(text) >= 1 ) /* and it's not an empty string */ |
if ( isdigit((int)(*text)) ) /* leading 0-9 digit signals value */ |
if ( isthischar(*text,"+-0123456789") ) /* check for leading +-digit */ |
{ counter = (int)(strtod(text,&udelim)+0.1); /* value and delim */ |
gotvalue = 1; /* signal we got optional value */ |
gotcount = 1; } /* signal we got counter value */ |
else /* not +-digit, so must be logfile */ |
else /* not a digit, so must be logfile */ |
strcpy(logfile,text); /* so just copy it */ |
strcpy(logfile,text); /* so just copy it */ |
|
} /* --- end-of-if(**expression=='[') --- */ |
} /* --- end-of-if(**expression=='[') --- */ |
/* --- next check for optional \counter[][logfile] --- */ |
/* --- next check for optional \counter[][logfile] --- */ |
if ( *(*expression) == '[' ) /* check for []-enclosed logfile */ |
if ( *(*expression) == '[' ) /* check for []-enclosed logfile */ |
{ *expression = texsubexpr(*expression,filename,1023,"[","]",0,0); |
{ *expression = texsubexpr(*expression,filename,1023,"[","]",0,0); |
if ( *text != '\000' ) /* got logfile value */ |
if ( *filename != '\000' ) /* got logfile (or counter value) */ |
if ( strlen(filename) >= 1 ) /* and it's not an empty string */ |
if ( strlen(filename) >= 1 ) /* and it's not an empty string */ |
if ( !(isdigit((int)(*filename))) /*leading non-digit signals logfile*/ |
if ( !(isthischar(*text,"+-0123456789")) /* not a leading +-digit */ |
|| gotcount ) /* or we already got counter value */ |
|| gotvalue ) /* or we already got counter value */ |
strcpy(logfile,filename); /* so just copy it */ |
strcpy(logfile,filename); /* so just copy it */ |
else /* 0-9 digit, so must be value */ |
else /* leading +-digit must be value */ |
{ strcpy(text,filename); /* copy value to text line */ |
{ strcpy(text,filename); /* copy value to text line */ |
counter = (int)(strtod(text,&udelim)+0.1); /* value and delim */ |
gotvalue = 1; } /* and signal we got optional value*/ |
gotcount = 1; } /* signal we got counter value */ |
|
} /* --- end-of-if(**expression=='[') --- */ |
} /* --- end-of-if(**expression=='[') --- */ |
|
/* --- evaluate [value] if present --- */ |
|
if ( gotvalue ) { /*leading +-digit should be in text*/ |
|
if ( *text == '+' ) isdelta = (+1); /* signal adding */ |
|
if ( *text == '-' ) isdelta = (-1); /* signal subtracting */ |
|
value = (int)(strtod((isdelta==0?text:text+1),&udelim)+0.1); /*abs(value)*/ |
|
if ( isdelta == (-1) ) value = (-value); /* set negative value if needed */ |
|
counter = value; /* re-init counter */ |
|
} /* --- end-of-if(gotvalue) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
obtain counter {filename} argument |
obtain counter {filename} argument |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 8519 Read and parse file, increment and rewri
|
Line 9457 Read and parse file, increment and rewri
|
if ( strlen(filename) > 1 ) /* make sure we got {filename} arg */ |
if ( strlen(filename) > 1 ) /* make sure we got {filename} arg */ |
{ |
{ |
/* --- read and interpret first (and only) line from counter file --- */ |
/* --- read and interpret first (and only) line from counter file --- */ |
if ( !gotcount ) /* if no [count] argument supplied */ |
if ( !gotvalue || (isdelta!=0) ) /*if no [count] arg or if delta arg*/ |
if ( rastreadfile(filename,tag,text) != 0 ) /* try reading it from file */ |
if ( (status=rastreadfile(filename,1,tag,text)) > 0 ) /*try reading file*/ |
{ counter= 1 + (int)(strtod(text,&udelim)+0.1); /*counter val and delim*/ |
{ char *vdelim = NULL; /* underscore delim from file */ |
gotcount = 1; } /* signal we got counter value */ |
double fileval = strtod(text,&vdelim); /* value and delim from file */ |
|
counter = (int)(fileval<0.0?fileval-0.1:fileval+0.1); /* integerized */ |
|
counter += value; /* bump count by 1 or add/sub delta*/ |
|
if ( !gotvalue ) udelim=vdelim; } /* default to file's current delim */ |
/* --- check for ordinal suffix --- */ |
/* --- check for ordinal suffix --- */ |
if ( udelim != (char *)NULL ) /* have some delim after value */ |
if ( udelim != (char *)NULL ) /* have some delim after value */ |
if ( *udelim == '_' ) /* underscore signals ordinal */ |
if ( *udelim == '_' ) /* underscore signals ordinal */ |
{ ordindex = counter%10; /* least significant digit */ |
{ int abscount = (counter>=0?counter:(-counter)); /* abs(counter) */ |
if ( counter >= 10 ) /* counter is 10 or greater */ |
ordindex = abscount%10; /* least significant digit */ |
if ( (counter/10)%10 == 1 ) /* and the last two are 10-19 */ |
if ( abscount >= 10 ) /* counter is 10 or greater */ |
|
if ( (abscount/10)%10 == 1 ) /* and the last two are 10-19 */ |
ordindex = 0; } /* use th for 11,12,13 rather than st,nd,rd */ |
ordindex = 0; } /* use th for 11,12,13 rather than st,nd,rd */ |
/* --- rewrite counter file --- */ |
/* --- rewrite counter file --- */ |
sprintf(text,"%d",counter); /*build image of incremented counter*/ |
if ( status >= 0 ) /* file was read okay */ |
if ( ordindex >= 0 ) strcat(text,"_"); /* tack on _ */ |
{ sprintf(text,"%d",counter); /*build image of incremented counter*/ |
if ( *tag == '\000' ) strcat(text,"\n"); /* and newline */ |
if ( ordindex >= 0 ) strcat(text,"_"); /* tack on _ */ |
rastwritefile(filename,tag,text,1); /* rewrite incremented counter */ |
if ( *tag == '\000' ) strcat(text,"\n"); /* and newline */ |
|
status = rastwritefile(filename,tag,text,isstrict); } /*rewrite counter*/ |
} /* --- end-of-if(strlen(filename)>1) --- */ |
} /* --- end-of-if(strlen(filename)>1) --- */ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
log counter request |
log counter request |
Line 8543 if ( strlen(logfile) > 1 ) /* optional
|
Line 9486 if ( strlen(logfile) > 1 ) /* optional
|
{ |
{ |
char comment[1024] = "\000", /* embedded comment, logfile:comment*/ |
char comment[1024] = "\000", /* embedded comment, logfile:comment*/ |
*commptr = strchr(logfile,':'); /* check for : signalling comment */ |
*commptr = strchr(logfile,':'); /* check for : signalling comment */ |
|
int islogokay = 1; /* logfile must exist if isstrict */ |
if ( commptr != NULL ) /* have embedded comment */ |
if ( commptr != NULL ) /* have embedded comment */ |
{ strcpy(comment,commptr+1); /* comment follows : */ |
{ strcpy(comment,commptr+1); /* comment follows : */ |
*commptr = '\000'; } /* null-terminate actual logfile */ |
*commptr = '\000'; } /* null-terminate actual logfile */ |
if ( (logfp = fopen(logfile,"a")) /* open logfile */ |
strcpy(logfile,rasteditfilename(logfile)); /* edit log file name */ |
!= (FILE *)NULL ) /* opened successfully */ |
if ( *logfile == '\000' ) islogokay = 0; /* given an invalid file name */ |
{ |
else if ( isstrict ) { /*okay, but only write if it exists*/ |
int ilog=0; /* logvars[] index */ |
if ( (logfp=fopen(logfile,"r")) == (FILE *)NULL ) /*doesn't already exist*/ |
fprintf(logfp,"%s ",timestamp()); /* first emit timestamp */ |
islogokay = 0; /* so don't write log file */ |
if (*tag=='\000') fprintf(logfp,"%s",filename); /* emit counter filename */ |
else fclose(logfp); } /* close file opened for test read */ |
else fprintf(logfp,"<%s>",tag); /* or tag if we have one */ |
if ( islogokay ) /* okay to write logfile */ |
fprintf(logfp,"=%d",counter); /* emit counter value */ |
if ( (logfp = fopen(logfile,"a")) /* open logfile */ |
for ( ilog=0; logvars[ilog] != NULL; ilog++ ) /* log till end-of-table */ |
!= (FILE *)NULL ) { /* opened successfully for append */ |
if ( ilog == commentvar /* replace with comment... */ |
int ilog=0; /* logvars[] index */ |
&& commptr != NULL ) /* ...if available */ |
fprintf(logfp,"%s ",timestamp(TZDELTA,0)); /* first emit timestamp */ |
fprintf(logfp," %.256s",comment); /* log embedded comment */ |
if (*tag=='\000') fprintf(logfp,"%s",filename); /* emit counter filename */ |
else |
else fprintf(logfp,"<%s>",tag); /* or tag if we have one */ |
{ char *logval = getenv(logvars[ilog]); /* getenv(variable) to be logged*/ |
fprintf(logfp,"=%d",counter); /* emit counter value */ |
fprintf(logfp," %.64s", /* log variable */ |
if ( status < 1 ) /* read or re-write failed */ |
|
fprintf(logfp,"(%s %d)","error status",status); /* emit error */ |
|
for ( ilog=0; logvars[ilog] != NULL; ilog++ ) /* log till end-of-table */ |
|
if ( ilog == commentvar /* replace with comment... */ |
|
&& commptr != NULL ) /* ...if available */ |
|
fprintf(logfp," %.256s",comment); /* log embedded comment */ |
|
else |
|
{ char *logval = getenv(logvars[ilog]); /*getenv(variable) to be logged*/ |
|
fprintf(logfp," %.64s", /* log variable */ |
(logval!=NULL?logval:"<unknown>")); } /* emit value or <unknown> */ |
(logval!=NULL?logval:"<unknown>")); } /* emit value or <unknown> */ |
fprintf(logfp,"\n"); /* terminating newline */ |
fprintf(logfp,"\n"); /* terminating newline */ |
fclose(logfp); /* close logfile */ |
fclose(logfp); /* close logfile */ |
} /* --- end-of-if(logfp!=NULL) --- */ |
} /* --- end-of-if(islogokay&&logfp!=NULL) --- */ |
} /* --- end-of-if(strlen(logfile)>1) --- */ |
} /* --- end-of-if(strlen(logfile)>1) --- */ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
construct counter expression and rasterize it |
construct counter expression and rasterize it |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- construct expression --- */ |
/* --- construct expression --- */ |
/*sprintf(text,"%d",counter);*/ /* start with counter */ |
/*sprintf(text,"%d",counter);*/ /* start with counter */ |
strcpy(text,dtoa(((double)counter),0)); /* comma-separated counter value */ |
strcpy(text,dbltoa(((double)counter),0)); /* comma-separated counter value */ |
if ( ordindex >= 0 ) /* need to tack on ordinal suffix */ |
if ( ordindex >= 0 ) /* need to tack on ordinal suffix */ |
{ strcat(text,"^{\\underline{\\rm~"); /* start with ^ and {\underline{\rm */ |
{ strcat(text,"^{\\underline{\\rm~"); /* start with ^ and {\underline{\rm */ |
strcat(text,ordinal[ordindex]); /* then st,nd,rd, or th */ |
strcat(text,ordinal[ordindex]); /* then st,nd,rd, or th */ |
Line 8585 countersp = rasterize(text,size); /* ras
|
Line 9537 countersp = rasterize(text,size); /* ras
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: rasttoday ( expression, size, basesp, arg1, arg2, arg3 ) |
|
* Purpose: handle \today |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I/O) char ** to first char of null-terminated |
|
* string immediately following \today, |
|
* and returning ptr immediately |
|
* following last character processed. |
|
* size (I) int containing 0-5 default font size |
|
* basesp (I) subraster * to character (or subexpression) |
|
* immediately preceding \today |
|
* (unused, but passed for consistency) |
|
* arg1 (I) int unused |
|
* arg2 (I) int unused |
|
* arg3 (I) int unused |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( subraster * ) subraster ptr to date stamp |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
subraster *rasttoday ( char **expression, int size, subraster *basesp, |
|
int arg1, int arg2, int arg3 ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
char *texsubexpr(), optarg[2050]; /* optional [+/-tzdelta,ifmt] args */ |
|
char *timestamp(), *today=optarg; /* timestamp to be rasterized */ |
|
subraster *rasterize(), *todaysp=NULL; /* rasterize timestamp */ |
|
int ifmt=1, tzdelta=0; /* default timestamp() args */ |
|
/* ------------------------------------------------------------------------- |
|
Get optional args \today[+/-tzdelta,ifmt] |
|
-------------------------------------------------------------------------- */ |
|
/* --- check for optional \today[+/-tzdelta,ifmt] --- */ |
|
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
|
{ *expression = texsubexpr(*expression,optarg,2047,"[","]",0,0); |
|
if ( *optarg != '\000' ) /* got optional arg */ |
|
{ char *comma = strchr(optarg,','); /* comma between +/-tzdelta,ifmt */ |
|
int iarg, nargs=(comma==NULL?1:2); /* #optional args between []'s */ |
|
if ( comma != NULL ) *comma = '\000'; /* null-terminate first arg */ |
|
for ( iarg=1; iarg<=nargs; iarg++ ) /* process one or both args */ |
|
{ char *arg = (iarg==1?optarg:comma+1); /* choose 1st or 2nd arg */ |
|
if ( isthischar(*arg,"+-") ) /* leading +/- signals tzdelta */ |
|
tzdelta = atoi(arg); /* so interpret arg as tzdelta */ |
|
else ifmt = atoi(arg); } /* else interpret args as ifmt */ |
|
} /* --- end-of-if(*optarg!='\0') --- */ |
|
} /* --- end-of-if(**expression=='[') --- */ |
|
/* ------------------------------------------------------------------------- |
|
Get timestamp and rasterize it |
|
-------------------------------------------------------------------------- */ |
|
strcpy(today,"\\text{"); /* rasterize timestamp as text */ |
|
strcat(today,timestamp(tzdelta,ifmt)); /* get timestamp */ |
|
strcat(today,"}"); /* terminate \text{} braces */ |
|
todaysp = rasterize(today,size); /* rasterize timestamp */ |
|
/* --- return timestamp raster to caller --- */ |
|
/*end_of_job:*/ |
|
return ( todaysp ); /* return timestamp to caller */ |
|
} /* --- end-of-function rasttoday() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: rastcalendar ( expression, size, basesp, arg1, arg2, arg3 ) |
|
* Purpose: handle \calendar |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I/O) char ** to first char of null-terminated |
|
* string immediately following \calendar |
|
* and returning ptr immediately |
|
* following last character processed. |
|
* size (I) int containing 0-5 default font size |
|
* basesp (I) subraster * to character (or subexpression) |
|
* immediately preceding \calendar |
|
* (unused, but passed for consistency) |
|
* arg1 (I) int unused |
|
* arg2 (I) int unused |
|
* arg3 (I) int unused |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( subraster * ) subraster ptr to rendered one-month calendar |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
subraster *rastcalendar ( char **expression, int size, subraster *basesp, |
|
int arg1, int arg2, int arg3 ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
char *texsubexpr(), optarg[2050]; /* optional [year,month] args */ |
|
char *calendar(), *calstr=NULL; /* calendar to be rasterized */ |
|
subraster *rasterize(), *calendarsp=NULL; /* rasterize calendar string */ |
|
int year=0,month=0,day=0, argval=0; /* default calendar() args */ |
|
/* ------------------------------------------------------------------------- |
|
Get optional args \today[+/-tzdelta,ifmt] |
|
-------------------------------------------------------------------------- */ |
|
/* --- check for optional \calendar[year,month] --- */ |
|
if ( *(*expression) == '[' ) /* check for []-enclosed value */ |
|
{ *expression = texsubexpr(*expression,optarg,2047,"[","]",0,0); |
|
if ( *optarg != '\000' ) /* got optional arg */ |
|
{ char *comma = strchr(optarg,','), /* comma between year,month */ |
|
*comma2 = NULL; /* second comma before day */ |
|
int iarg, nargs=(comma==NULL?1:2); /* #optional args between []'s */ |
|
if ( comma != NULL ) { *comma = '\000'; /*null-terminate first arg*/ |
|
if ( (comma2=strchr(comma+1,',')) != NULL ) /* have third arg */ |
|
{ *comma2 = '\000'; nargs++; } } /* null-term 2nd arg, bump count */ |
|
for ( iarg=1; iarg<=nargs; iarg++ ) /* process one or both args */ |
|
{ char *arg= (iarg==1?optarg:(iarg==2?comma+1:comma2+1)); /*get arg*/ |
|
argval = atoi(arg); /* interpret arg as integer */ |
|
if ( iarg < 3 ) /* first two args are month,year */ |
|
{if ( argval>1972 && argval<2100 ) year = argval; /* year value */ |
|
else if ( argval>=1 && argval<=12 ) month = argval;} /*or month*/ |
|
else /* only 3rd arg can be day */ |
|
if ( argval>=1 && argval<=31 ) day = argval; } /* day value */ |
|
} /* --- end-of-if(*optarg!='\0') --- */ |
|
} /* --- end-of-if(**expression=='[') --- */ |
|
/* ------------------------------------------------------------------------- |
|
Get calendar string and rasterize it |
|
-------------------------------------------------------------------------- */ |
|
if ( msgfp!= NULL && msglevel>=9 ) |
|
fprintf(msgfp,"rastcalendar> year=%d, month=%d, day=%d\n", |
|
year,month,day); |
|
calstr = calendar(year,month,day); /* get calendar string */ |
|
calendarsp = rasterize(calstr,size); /* rasterize calendar string */ |
|
/* --- return calendar raster to caller --- */ |
|
/*end_of_job:*/ |
|
return ( calendarsp ); /* return calendar to caller */ |
|
} /* --- end-of-function rastcalendar() --- */ |
|
|
|
|
|
/* ========================================================================== |
* Function: rastnoop ( expression, size, basesp, nargs, arg2, arg3 ) |
* Function: rastnoop ( expression, size, basesp, nargs, arg2, arg3 ) |
* Purpose: no op -- flush \escape without error |
* Purpose: no op -- flush \escape without error |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
Line 8594 countersp = rasterize(text,size); /* ras
|
Line 9675 countersp = rasterize(text,size); /* ras
|
* following last character processed. |
* following last character processed. |
* size (I) int containing 0-5 default font size |
* size (I) int containing 0-5 default font size |
* basesp (I) subraster * to character (or subexpression) |
* basesp (I) subraster * to character (or subexpression) |
* immediately preceding \fbox |
* immediately preceding \escape |
* (unused, but passed for consistency) |
* (unused, but passed for consistency) |
* nargs (I) int containing number of {}-args after |
* nargs (I) int containing number of {}-args after |
* \escape to be flushed along with it |
* \escape to be flushed along with it |
Line 8648 FILE *rastopenfile ( char *filename, cha
|
Line 9729 FILE *rastopenfile ( char *filename, cha
|
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
FILE *fp = (FILE *)NULL /*,*fopen()*/; /*file pointer to opened filename*/ |
FILE *fp = (FILE *)NULL /*,*fopen()*/; /*file pointer to opened filename*/ |
char texfile[2048] = "\000", /* local copy of input filename */ |
char texfile[2048] = "\000", /* local, edited copy of filename */ |
|
*rasteditfilename(), /* prepend pathprefix if necessary */ |
amode[128] = "r"; /* test open mode if arg mode=NULL */ |
amode[128] = "r"; /* test open mode if arg mode=NULL */ |
int ismode = 0, /* true of mode!=NULL */ |
int ismode = 0; /* true of mode!=NULL */ |
isprefix = (*pathprefix=='\000'?0:1); /* true if paths have prefix */ |
|
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
Check mode and open file |
Check mode and open file |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- check filename --- */ |
/* --- edit filename --- */ |
if ( filename != (char *)NULL ) /* caller passed filename arg */ |
strcpy(texfile,rasteditfilename(filename)); /*edited copy of input filename*/ |
if ( strlen(filename) >= 1 ) /* make sure we got actual filename*/ |
|
{ char *pfilename = filename; /* ptr to 1st char of filename */ |
|
*texfile = '\000'; /* init filename as null string */ |
|
while ( isthischar(*pfilename," /\\") ) /* absolute paths invalid */ |
|
pfilename++; /* so flush leading / or \ (or ' ')*/ |
|
if ( isprefix && *pfilename!='\000' ) /* paths preceded by prefix */ |
|
{ strcat(texfile,pathprefix); /* init filename with path */ |
|
while ( memcmp(pfilename,"../",3)==0 /* have leading ../ */ |
|
|| memcmp(pfilename,"..\\",3)==0 ) /* or ..\ with prefix */ |
|
pfilename += 3; } /* flush leading ../ or ..\ */ |
|
strcat(texfile,pfilename); /* local copy of given filename */ |
|
compress(texfile,' '); } /* remove embedded blanks */ |
|
/* --- check mode --- */ |
/* --- check mode --- */ |
if ( mode != (char *)NULL ) /* caller passed mode arg */ |
if ( mode != (char *)NULL ) /* caller passed mode arg */ |
if ( *mode != '\000' ) /* and it's not an empty string */ |
if ( *mode != '\000' ) /* and it's not an empty string */ |
Line 8697 if ( !ismode && fp!=NULL ) /* no mode,
|
Line 9766 if ( !ismode && fp!=NULL ) /* no mode,
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: rastreadfile ( filename, tag, value ) |
* Function: rasteditfilename ( filename ) |
|
* Purpose: edits filename to remove security problems, |
|
* e.g., removes all ../'s and ..\'s. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: filename (I) char * to null-terminated string containing |
|
* name of file to be edited |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( char * ) pointer to edited filename, |
|
* or empty string "\000" if any problem |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
char *rasteditfilename ( char *filename ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
static char editname[2048]; /*edited filename returned to caller*/ |
|
char *strchange(); /* prepend pathprefix if necessary */ |
|
int strreplace(), /* remove ../'s and ..\'s */ |
|
isprefix = (*pathprefix=='\000'?0:1); /* true if paths have prefix */ |
|
/* -------------------------------------------------------------------------- |
|
edit filename |
|
-------------------------------------------------------------------------- */ |
|
/* --- first check filename arg --- */ |
|
*editname = '\000'; /* init edited name as empty string*/ |
|
if ( filename == (char *)NULL ) goto end_of_job; /* no filename arg */ |
|
if ( *filename == '\000' ) goto end_of_job; /* filename is an empty string */ |
|
/* --- init edited filename --- */ |
|
strcpy(editname,filename); /* init edited name as input name */ |
|
compress(editname,' '); /* remove embedded blanks */ |
|
/* --- remove leading or embedded ....'s --- */ |
|
while ( strreplace(editname,"....",NULL,0) > 0 ) ; /* squeeze out ....'s */ |
|
/* --- remove leading / and \ and dots (and blanks) --- */ |
|
if ( *editname != '\000' ) /* still have chars in filename */ |
|
while ( isthischar(*editname," ./\\") ) /* absolute paths invalid */ |
|
strcpy(editname,editname+1); /* so flush leading / or \ (or ' ')*/ |
|
if ( *editname == '\000' ) goto end_of_job; /* no chars left in filename */ |
|
/* --- remove leading or embedded ../'s and ..\'s --- */ |
|
while ( strreplace(editname,"../",NULL,0) > 0 ) ; /* squeeze out ../'s */ |
|
while ( strreplace(editname,"..\\",NULL,0) > 0 ) ; /* and ..\'s */ |
|
while ( strreplace(editname,"../",NULL,0) > 0 ) ; /* and ../'s again */ |
|
/* --- prepend path prefix (if compiled with -DPATHPREFIX) --- */ |
|
if ( isprefix && *editname!='\000' ) /* filename is preceded by prefix */ |
|
strchange(0,editname,pathprefix); /* so prepend prefix */ |
|
end_of_job: |
|
return ( editname ); /* back with edited filename */ |
|
} /* --- end-of-function rasteditfilename() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: rastreadfile ( filename, islock, tag, value ) |
* Purpose: Read filename, returning value as string |
* Purpose: Read filename, returning value as string |
* between <tag>...</tag> or entire file if tag=NULL passed. |
* between <tag>...</tag> or entire file if tag=NULL passed. |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: filename (I) char * to null-terminated string containing |
* Arguments: filename (I) char * to null-terminated string containing |
* name of file to read (preceded by path |
* name of file to read (preceded by path |
* relative to mimetex executable) |
* relative to mimetex executable) |
|
* islock (I) int containing 1 to lock file while reading |
|
* (hopefully done by opening in "r+" mode) |
* tag (I) char * to null-terminated string containing |
* tag (I) char * to null-terminated string containing |
* html-like tagname. File contents between |
* html-like tagname. File contents between |
* <tag> and </tag> will be returned, or |
* <tag> and </tag> will be returned, or |
Line 8716 if ( !ismode && fp!=NULL ) /* no mode,
|
Line 9839 if ( !ismode && fp!=NULL ) /* no mode,
|
* Notes: o |
* Notes: o |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
int rastreadfile ( char *filename, char *tag, char *value ) |
int rastreadfile ( char *filename, int islock, char *tag, char *value ) |
{ |
{ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
Line 8726 char texfile[2048] = "\000", /* local c
|
Line 9849 char texfile[2048] = "\000", /* local c
|
text[4096]; /* line from input file */ |
text[4096]; /* line from input file */ |
char *tagp, tag1[512], tag2[512]; /* left <tag> and right <tag/> */ |
char *tagp, tag1[512], tag2[512]; /* left <tag> and right <tag/> */ |
int vallen=0, maxvallen=8000; /* #chars in value, max allowed */ |
int vallen=0, maxvallen=8000; /* #chars in value, max allowed */ |
int status = 0; /* status returned, 1=okay */ |
int status = (-1); /* status returned, 1=okay */ |
int tagnum = 0; /* tag we're looking for */ |
int tagnum = 0; /* tag we're looking for */ |
|
/*int islock = 1;*/ /* true to lock file */ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
Open file |
Open file |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 8737 if ( value == (char *)NULL ) goto end_of
|
Line 9861 if ( value == (char *)NULL ) goto end_of
|
/* --- open filename or filename.tex --- */ |
/* --- open filename or filename.tex --- */ |
if ( filename != (char *)NULL ) /* make sure we got filename arg */ |
if ( filename != (char *)NULL ) /* make sure we got filename arg */ |
{ strcpy(texfile,filename); /* local copy of filename */ |
{ strcpy(texfile,filename); /* local copy of filename */ |
fp = rastopenfile(texfile,"r"); } /* try opening it */ |
fp = rastopenfile(texfile,(islock?"r+":"r")); } /* try opening it */ |
/* --- check that file opened --- */ |
/* --- check that file opened --- */ |
if ( fp == (FILE *)NULL ) /* failed to open file */ |
if ( fp == (FILE *)NULL ) /* failed to open file */ |
{ sprintf(value,"{\\normalsize\\rm[file %s?]}",texfile); |
{ sprintf(value,"{\\normalsize\\rm[file %s?]}",texfile); |
goto end_of_job; } /* return error message to caller */ |
goto end_of_job; } /* return error message to caller */ |
|
status = 0; /* file opened successfully */ |
|
if ( islock ) rewind(fp); /* start at beginning of file */ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
construct <tag>'s |
construct <tag>'s |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 8757 Read file, concatnate lines
|
Line 9883 Read file, concatnate lines
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
while ( fgets(text,4090,fp) != (char *)NULL ) { /* read input till eof */ |
while ( fgets(text,4090,fp) != (char *)NULL ) { /* read input till eof */ |
switch ( tagnum ) { /* look for left- or right-tag */ |
switch ( tagnum ) { /* look for left- or right-tag */ |
case 0: break; /* no tag to look for */ |
case 0: status = 1; break; /* no tag to look for */ |
case 1: /* looking for opening left <tag> */ |
case 1: /* looking for opening left <tag> */ |
if ( (tagp=strstr(text,tag1)) == NULL ) break; /*haven't found it yet*/ |
if ( (tagp=strstr(text,tag1)) == NULL ) break; /*haven't found it yet*/ |
strcpy(text,tagp+strlen(tag1)); /* shift out preceding text */ |
strcpy(text,tagp+strlen(tag1)); /* shift out preceding text */ |
Line 8766 while ( fgets(text,4090,fp) != (char *)N
|
Line 9892 while ( fgets(text,4090,fp) != (char *)N
|
if ( (tagp=strstr(text,tag2)) == NULL ) break; /*haven't found it yet*/ |
if ( (tagp=strstr(text,tag2)) == NULL ) break; /*haven't found it yet*/ |
*tagp = '\000'; /* terminate line at tag */ |
*tagp = '\000'; /* terminate line at tag */ |
tagnum = 3; /* done after this line */ |
tagnum = 3; /* done after this line */ |
|
status = 1; /* successfully read tag */ |
break; |
break; |
} /* ---end-of-switch(tagnum) --- */ |
} /* ---end-of-switch(tagnum) --- */ |
if ( tagnum != 1 ) { /* no tag or left tag already found*/ |
if ( tagnum != 1 ) { /* no tag or left tag already found*/ |
Line 8821 int istag=0, rastreadfile(), /* read fil
|
Line 9948 int istag=0, rastreadfile(), /* read fil
|
/*isstrict = (seclevel>5? 1:0),*/ /*true only writes existing files*/ |
/*isstrict = (seclevel>5? 1:0),*/ /*true only writes existing files*/ |
isnewfile = 0, /* true if writing new file */ |
isnewfile = 0, /* true if writing new file */ |
status = 0; /* status returned, 1=okay */ |
status = 0; /* status returned, 1=okay */ |
|
int istimestamp = 0; /* true to update <timestamp> tag */ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
check args |
check args |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 8850 read existing file if just rewriting a s
|
Line 9978 read existing file if just rewriting a s
|
*filebuff = '\000'; /* init as empty file */ |
*filebuff = '\000'; /* init as empty file */ |
if ( !isnewfile ) /* if file already exists */ |
if ( !isnewfile ) /* if file already exists */ |
if ( istag ) /* and just rewriting one tag */ |
if ( istag ) /* and just rewriting one tag */ |
if ( rastreadfile(texfile,NULL,filebuff) /* read entire existing file */ |
if ( rastreadfile(texfile,1,NULL,filebuff) /* read entire existing file */ |
== 0 ) goto end_of_job; /* signal error if failed to read */ |
<= 0 ) goto end_of_job; /* signal error if failed to read */ |
/* -------------------------------------------------------------------------- |
/* -------------------------------------------------------------------------- |
construct new file data if needed (entire file replaced by value if no tag) |
construct new file data if needed (entire file replaced by value if no tag) |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 8908 if ( fputs((istag?filebuff:value),fp) /*
|
Line 10036 if ( fputs((istag?filebuff:value),fp) /*
|
!= EOF ) status = 1; /* signal success if succeeded */ |
!= EOF ) status = 1; /* signal success if succeeded */ |
fclose ( fp ); /* close output file after writing */ |
fclose ( fp ); /* close output file after writing */ |
/* --- modify timestamp --- */ |
/* --- modify timestamp --- */ |
if ( istag ) /* log mod time in tagged file */ |
if ( status > 0 ) /*forget timestamp if write failed*/ |
if ( strstr(tag,"timestamp") == (char *)NULL ) /* but avoid recursion */ |
if ( istimestamp ) /* if we're updating timestamp */ |
{ char fbuff[2048]; /* field buff <timestamp> value */ |
if ( istag ) /* only log time in tagged file */ |
strcpy(fbuff,tag); /* tag modified */ |
if ( strstr(tag,"timestamp") == (char *)NULL ) /* but avoid recursion */ |
strcat(fbuff," modified at "); /* spacer */ |
{ char fbuff[2048]; /* field buff <timestamp> value */ |
strcat(fbuff,timestamp()); /* start with timestamp */ |
strcpy(fbuff,tag); /* tag modified */ |
rastwritefile(filename,"timestamp",fbuff,1); } |
strcat(fbuff," modified at "); /* spacer */ |
|
strcat(fbuff,timestamp(TZDELTA,0)); /* start with timestamp */ |
|
status = rastwritefile(filename,"timestamp",fbuff,1); } |
/* --- return status to caller --- */ |
/* --- return status to caller --- */ |
end_of_job: |
end_of_job: |
return ( status ); /* return status to caller */ |
return ( status ); /* return status to caller */ |
Line 8922 end_of_job:
|
Line 10052 end_of_job:
|
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: timestamp ( ) |
* Function: calendar ( year, month, day ) |
|
* Purpose: returns null-terminated character string containing |
|
* \begin{array}...\end{array} for the one-month calendar |
|
* specified by year=1973...2099 and month=1...12. |
|
* If either arg out-of-range, today's value is used. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: year (I) int containing 1973...2099 or 0 for current |
|
* year |
|
* month (I) int containing 1...12 or 0 for current month |
|
* day (I) int containing day to emphasize or 0 |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( char * ) char ptr to null-terminated buffer |
|
* containing \begin{array}...\end{array} |
|
* string that will render calendar for |
|
* requested month, or NULL for any error. |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
char *calendar( int year, int month, int day ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
static char calbuff[4096]; /* calendar returned to caller */ |
|
time_t time_val = (time_t)(0); /* binary value returned by time() */ |
|
struct tm *tmstruct=(struct tm *)NULL, *localtime(); /* interpret time_val */ |
|
int yy=0, mm=0, dd=0; /* today (emphasize today's dd) */ |
|
int idd=1, iday=0, daynumber(); /* day-of-week for idd=1...31 */ |
|
char aval[64]; /* ascii day or 4-digit year */ |
|
/* --- calendar data --- */ |
|
static char *monthnames[] = { "?", "January", "February", "March", "April", |
|
"May", "June", "July", "August", "September", "October", |
|
"November", "December", "?" } ; |
|
static int modays[] = |
|
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0 }; |
|
/* ------------------------------------------------------------------------- |
|
initialization |
|
-------------------------------------------------------------------------- */ |
|
/* --- get current date/time --- */ |
|
time((time_t *)(&time_val)); /* get date and time */ |
|
tmstruct = localtime((time_t *)(&time_val)); /* interpret time_val */ |
|
yy = 1900 + (int)(tmstruct->tm_year); /* current four-digit year */ |
|
mm = 1 + (int)(tmstruct->tm_mon); /* current month, 1-12 */ |
|
dd = (int)(tmstruct->tm_mday); /* current day, 1-31 */ |
|
/* --- check args --- */ |
|
if ( year<1973 || year>2099 ) year = yy; /* current year if out-of-bounds */ |
|
if ( month<1 || month>12 ) month = mm; /* current month if out-of-bounds */ |
|
if ( month==mm && year==yy && day==0 ) /* current month and default day */ |
|
day = dd; /* emphasize current day */ |
|
modays[2] = (year%4==0?29:28); /* Feb has 29 days in leap years */ |
|
/* --- initialize calendar string --- */ |
|
strcpy(calbuff,"{\\begin{gather}"); /* center `month year` above cal */ |
|
strcat(calbuff,"\\small\\text{"); /* month set in roman */ |
|
strcat(calbuff,monthnames[month]); /* insert month name */ |
|
strcat(calbuff," }"); /* add a space */ |
|
sprintf(aval,"%d",year); /* convert year to ascii */ |
|
strcat(calbuff,aval); /* add year */ |
|
strcat(calbuff,"\\\\"); /* end top row */ |
|
strcat(calbuff, /* now begin calendar arrayr */ |
|
"\\begin{array}{|c|c|c|c|c|c|c|CCCCCC} \\hline" |
|
"\\tiny\\text{Sun} & \\tiny\\text{Mon} & \\tiny\\text{Tue} &" |
|
"\\tiny\\text{Wed} & \\tiny\\text{Thu} & \\tiny\\text{Fri} &" |
|
"\\tiny\\text{Sat} \\\\ \\hline " ); |
|
/* ------------------------------------------------------------------------- |
|
generate calendar |
|
-------------------------------------------------------------------------- */ |
|
for ( idd=1; idd<=modays[month]; idd++ ) /* run through days of month */ |
|
{ |
|
/* --- get day-of-week for this day --- */ |
|
iday = 1 + (daynumber(year,month,idd)%7); /* 1=Monday...7=Sunday */ |
|
if ( iday == 7 ) iday = 0; /* now 0=Sunday...6=Saturday */ |
|
/* --- may need empty cells at beginning of month --- */ |
|
if ( idd == 1 ) /* first day of month */ |
|
if ( iday > 0 ) /* need to skip cells */ |
|
{ strcpy(aval,"\\ &\\ &\\ &\\ &\\ &\\ &\\ &\\ &\\ &\\"); /*cells to skip*/ |
|
aval[3*iday] = '\000'; /*skip cells preceding 1st of month*/ |
|
strcat(calbuff,aval); } /* add skip string to buffer */ |
|
/* --- add idd to current cell --- */ |
|
sprintf(aval,"%d",idd); /* convert idd to ascii */ |
|
if ( idd == day /* emphasize today's date */ |
|
/*&& month==mm && year==yy*/ ) /* only if this month's calendar */ |
|
{ strcat(calbuff,"{\\fs{-1}\\left\\langle "); /*emphasize, 1 size smaller*/ |
|
strcat(calbuff,aval); /* put in idd */ |
|
strcat(calbuff,"\\right\\rangle}"); } /* finish emphasis */ |
|
else /* not today's date */ |
|
strcat(calbuff,aval); /* so just put in idd */ |
|
/* --- terminate cell --- */ |
|
if ( idd < modays[month] ) /* not yet end-of-month */ |
|
if ( iday < 6 ) /* still have days left in week */ |
|
strcat(calbuff,"&"); /* new cell in same week */ |
|
else /* reached end-of-week */ |
|
strcat(calbuff,"\\\\ \\hline"); /* so start new week */ |
|
} /* --- end-of-for(idd) --- */ |
|
strcat(calbuff,"\\\\ \\hline"); /* final underline at end-of-month */ |
|
/* --- return calendar to caller --- */ |
|
strcat(calbuff,"\\end{array}\\end{gather}}"); /* terminate array */ |
|
return ( calbuff ); /* back to caller with calendar */ |
|
} /* --- end-of-function calendar() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: timestamp ( tzdelta, ifmt ) |
* Purpose: returns null-terminated character string containing |
* Purpose: returns null-terminated character string containing |
* current date:time stamp as ccyy-mm-dd:hh:mm:ss{am,pm} |
* current date:time stamp as ccyy-mm-dd:hh:mm:ss{am,pm} |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: ( none ) |
* Arguments: tzdelta (I) integer, positive or negative, containing |
|
* containing number of hours to be added or |
|
* subtracted from system time (to accommodate |
|
* your desired time zone). |
|
* ifmt (I) integer containing 0 for default format |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Returns: ( char * ) ptr to null-terminated buffer |
* Returns: ( char * ) ptr to null-terminated buffer |
* containing current date:time stamp |
* containing current date:time stamp |
Line 8934 end_of_job:
|
Line 10170 end_of_job:
|
* Notes: o |
* Notes: o |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
char *timestamp( ) |
char *timestamp( int tzdelta, int ifmt ) |
{ |
{ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
static char timebuff[64]; /* date:time buffer back to caller */ |
static char timebuff[256]; /* date:time buffer back to caller */ |
/*long time_val = 0L;*/ /* binary value returned by time() */ |
/*long time_val = 0L;*/ /* binary value returned by time() */ |
time_t time_val = (time_t)(0); /* binary value returned by time() */ |
time_t time_val = (time_t)(0); /* binary value returned by time() */ |
struct tm *tmstruct=(struct tm *)NULL, *localtime(); /* interpret time_val */ |
struct tm *tmstruct=(struct tm *)NULL, *localtime(); /* interpret time_val */ |
int year=0, hour=0,ispm=1; /* adjust year, and set am/pm hour */ |
int year=0, hour=0,ispm=1, /* adjust year, and set am/pm hour */ |
|
month=0, day=0; /* adjust day and month for delta */ |
|
int tzadjust(); /* time zone adjustment function */ |
|
int daynumber(); /* #days since Jan 1, 1973 */ |
|
static char *daynames[] = { "Monday", "Tuesday", "Wednesday", |
|
"Thursday", "Friday", "Saturday", "Sunday" } ; |
|
static char *monthnames[] = { "?", "January", "February", "March", "April", |
|
"May", "June", "July", "August", "September", "October", |
|
"November", "December", "?" } ; |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
get current date:time, adjust values, and and format stamp |
get current date:time, adjust values, and and format stamp |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
|
/* --- first init returned timebuff in case of any error --- */ |
|
*timebuff = '\000'; |
/* --- get current date:time --- */ |
/* --- get current date:time --- */ |
time((time_t *)(&time_val)); /* get date and time */ |
time((time_t *)(&time_val)); /* get date and time */ |
tmstruct = localtime((time_t *)(&time_val)); /* interpret time_val */ |
tmstruct = localtime((time_t *)(&time_val)); /* interpret time_val */ |
/* --- adjust year and hour as necessary --- */ |
/* --- extract fields --- */ |
year = (int)(tmstruct->tm_year); /* local copy of year */ |
year = (int)(tmstruct->tm_year); /* local copy of year, 0=1900 */ |
hour = (int)(tmstruct->tm_hour); /* local copy of hour */ |
month = (int)(tmstruct->tm_mon) + 1; /* local copy of month, 1-12 */ |
|
day = (int)(tmstruct->tm_mday); /* local copy of day, 1-31 */ |
|
hour = (int)(tmstruct->tm_hour); /* local copy of hour, 0-23 */ |
|
/* --- adjust year --- */ |
year += 1900; /* set century in year */ |
year += 1900; /* set century in year */ |
if ( hour < 12 ) /* am check */ |
/* --- adjust for timezone --- */ |
{ ispm=0; /* reset pm flag */ |
tzadjust(tzdelta,&year,&month,&day,&hour); |
if ( hour == 0 ) hour = 12; } /* set 00hrs = 12am */ |
/* --- check params --- */ |
if ( hour > 12 ) hour -= 12; /* pm check sets 13hrs to 1pm, etc */ |
if ( hour<0 || hour>23 |
|
|| day<1 || day>31 |
|
|| month<1 || month>12 |
|
|| year<1973 ) goto end_of_job; |
|
/* --- adjust hour for am/pm --- */ |
|
switch ( ifmt ) |
|
{ |
|
default: |
|
case 0: |
|
if ( hour < 12 ) /* am check */ |
|
{ ispm=0; /* reset pm flag */ |
|
if ( hour == 0 ) hour = 12; } /* set 00hrs = 12am */ |
|
if ( hour > 12 ) hour -= 12; /* pm check sets 13hrs to 1pm, etc */ |
|
break; |
|
} /* --- end-of-switch(ifmt) --- */ |
/* --- format date:time stamp --- */ |
/* --- format date:time stamp --- */ |
sprintf(timebuff,"%04d-%02d-%02d:%02d:%02d:%02d%s", |
switch ( ifmt ) |
year,(int)((tmstruct->tm_mon)+1),(int)(tmstruct->tm_mday), |
{ |
hour,(int)(tmstruct->tm_min),(int)(tmstruct->tm_sec),((ispm)?"pm":"am")); |
default: |
return ( timebuff ); /* return stamp to caller */ |
case 0: /* --- 2005-03-05:11:49:59am --- */ |
|
sprintf(timebuff,"%04d-%02d-%02d:%02d:%02d:%02d%s", year,month,day, |
|
hour,(int)(tmstruct->tm_min),(int)(tmstruct->tm_sec),((ispm)?"pm":"am")); |
|
break; |
|
case 1: /* --- Saturday, March 5, 2005 --- */ |
|
sprintf(timebuff,"%s, %s %d, %d", |
|
daynames[daynumber(year,month,day)%7],monthnames[month],day,year); |
|
break; |
|
case 2: /* --- Saturday, March 5, 2005, 11:49:59am --- */ |
|
sprintf(timebuff,"%s, %s %d, %d, %d:%02d:%02d%s", |
|
daynames[daynumber(year,month,day)%7],monthnames[month],day,year, |
|
hour,(int)(tmstruct->tm_min),(int)(tmstruct->tm_sec),((ispm)?"pm":"am")); |
|
break; |
|
case 3: /* --- 11:49:59am --- */ |
|
sprintf(timebuff,"%d:%02d:%02d%s", |
|
hour,(int)(tmstruct->tm_min),(int)(tmstruct->tm_sec),((ispm)?"pm":"am")); |
|
break; |
|
} /* --- end-of-switch(ifmt) --- */ |
|
end_of_job: |
|
return ( timebuff ); /* return stamp to caller */ |
} /* --- end-of-function timestamp() --- */ |
} /* --- end-of-function timestamp() --- */ |
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: dtoa ( dblval, npts ) |
* Function: tzadjust ( tzdelta, year, month, day, hour ) |
|
* Purpose: Adjusts hour, and day,month,year if necessary, |
|
* by delta increment to accommodate your time zone. |
|
* -------------------------------------------------------------------------- |
|
* Arguments: tzdelta (I) integer, positive or negative, containing |
|
* containing number of hours to be added or |
|
* subtracted from given time (to accommodate |
|
* your desired time zone). |
|
* year (I) addr of int containing 4-digit year |
|
* month (I) addr of int containing month 1=Jan - 12=Dec. |
|
* day (I) addr of int containing day 1-31 for Jan. |
|
* hour (I) addr of int containing hour 0-23 |
|
* Returns: ( int ) 1 for success, or 0 for error |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int tzadjust ( int tzdelta, int *year, int *month, int *day, int *hour ) |
|
{ |
|
/* -------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int yy = *year, mm = *month, dd = *day, hh = *hour; /*dereference args*/ |
|
/* --- calendar data --- */ |
|
static int modays[] = |
|
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0 }; |
|
/* -------------------------------------------------------------------------- |
|
check args |
|
-------------------------------------------------------------------------- */ |
|
if ( mm<1 || mm>12 ) return(-1); /* bad month */ |
|
if ( dd<1 || dd>modays[mm] ) return(-1); /* bad day */ |
|
if ( hh<0 || hh>23 ) return(-1); /* bad hour */ |
|
if ( tzdelta>23 || tzdelta<(-23) ) return(-1); /* bad tzdelta */ |
|
/* -------------------------------------------------------------------------- |
|
make adjustments |
|
-------------------------------------------------------------------------- */ |
|
/* --- adjust hour --- */ |
|
hh += tzdelta; /* apply caller's delta */ |
|
/* --- adjust for feb 29 --- */ |
|
modays[2] = (yy%4==0?29:28); /* Feb has 29 days in leap years */ |
|
/* --- adjust day --- */ |
|
if ( hh < 0 ) /* went to preceding day */ |
|
{ dd--; hh += 24; } |
|
if ( hh > 23 ) /* went to next day */ |
|
{ dd++; hh -= 24; } |
|
/* --- adjust month --- */ |
|
if ( dd < 1 ) /* went to preceding month */ |
|
{ mm--; dd = modays[mm]; } |
|
if ( dd > modays[mm] ) /* went to next month */ |
|
{ mm++; dd = 1; } |
|
/* --- adjust year --- */ |
|
if ( mm < 1 ) /* went to preceding year */ |
|
{ yy--; mm = 12; dd = modays[mm]; } |
|
if ( mm > 12 ) /* went to next year */ |
|
{ yy++; mm = 1; dd = 1; } |
|
/* --- back to caller --- */ |
|
*year=yy; *month=mm; *day=dd; *hour=hh; /* reset adjusted args */ |
|
return ( 1 ); |
|
} /* --- end-of-function tzadjust() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: daynumber ( year, month, day ) |
|
* Purpose: Returns number of actual calendar days from Jan 1, 1973 |
|
* to the given date (e.g., bvdaynumber(1974,1,1)=365). |
|
* -------------------------------------------------------------------------- |
|
* Arguments: year (I) int containing year -- may be either 1995 or |
|
* 95, or may be either 2010 or 110 for those |
|
* years. |
|
* month (I) int containing month, 1=Jan thru 12=Dec. |
|
* day (I) int containing day of month, 1-31 for Jan, etc. |
|
* Returns: ( int ) Number of days from Jan 1, 1973 to given date, |
|
* or -1 for error (e.g., year<1973). |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int daynumber ( int year, int month, int day ) |
|
{ |
|
/* -------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
/* --- returned value (note: returned as a default "int") --- */ |
|
int ndays; /* #days since jan 1, year0 */ |
|
/* --- initial conditions --- */ |
|
static int year0 = 73, /* jan 1 was a monday, 72 was a leap */ |
|
days4yrs = 1461, /* #days in 4 yrs = 365*4 + 1 */ |
|
days1yr = 365; |
|
/* --- table of accumulated days per month (last index not used) --- */ |
|
static int modays[] = |
|
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; |
|
/* --- variables for #days since day0 --- */ |
|
int nyears, nfouryrs; /*#years, #4-yr periods since year0*/ |
|
/* -------------------------------------------------------------------------- |
|
Check input |
|
-------------------------------------------------------------------------- */ |
|
if ( month < 1 || month > 12 ) /*month used as index, so must be ok*/ |
|
return ( -1 ); /* otherwise, forget it */ |
|
if ( year >= 1900 ) year -= 1900; /*use two-digit years (3 after 2000)*/ |
|
/* -------------------------------------------------------------------------- |
|
Find #days since jan 1, 1973 |
|
-------------------------------------------------------------------------- */ |
|
/* --- figure #complete 4-year periods and #remaining yrs till current --- */ |
|
nyears = year - year0; /* #years since year0 */ |
|
if ( nyears < 0 ) return ( -1 ); /* we're not working backwards */ |
|
nfouryrs = nyears/4; /* #complete four-year periods */ |
|
nyears -= (4*nfouryrs); /* remainder excluding current year*/ |
|
/* --- #days from jan 1, year0 till jan 1, this year --- */ |
|
ndays = (days4yrs*nfouryrs) /* #days in 4-yr periods */ |
|
+ (days1yr*nyears); /* +remaining days */ |
|
/*if ( year > 100 ) ndays--;*/ /* subtract leap year for 2000AD */ |
|
/* --- add #days within current year --- */ |
|
ndays += (modays[month-1] + (day-1)); |
|
/* --- may need an extra day if current year is a leap year --- */ |
|
if ( nyears == 3 ) /*three preceding yrs so this is 4th*/ |
|
{ if ( month > 2 ) /* past feb so need an extra day */ |
|
/*if ( year != 100 )*/ /* unless it's 2000AD */ |
|
ndays++; } /* so add it in */ |
|
return ( (int)(ndays) ); /* #days back to caller */ |
|
} /* --- end-of-function daynumber() --- */ |
|
|
|
|
|
/* ========================================================================== |
|
* Function: dbltoa ( dblval, npts ) |
* Purpose: Converts double to ascii, in financial format |
* Purpose: Converts double to ascii, in financial format |
* (e.g., comma-separated and negatives enclosed in ()'s). |
* (e.g., comma-separated and negatives enclosed in ()'s). |
* ------------------------------------------------------------------------- |
* ------------------------------------------------------------------------- |
Line 8980 return ( timebuff ); /* return stamp t
|
Line 10385 return ( timebuff ); /* return stamp t
|
* Notes: o |
* Notes: o |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
char *dtoa ( dblval, npts ) |
char *dbltoa ( double dblval, int npts ) |
double dblval; |
/* double dblval; |
int npts; |
int npts; */ |
{ |
{ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
Line 9048 End-of-Job
|
Line 10453 End-of-Job
|
if ( isneg ) *finptr++ = ')'; /*trailing paren for negative value*/ |
if ( isneg ) *finptr++ = ')'; /*trailing paren for negative value*/ |
*finptr = '\000'; /* null-terminate converted double */ |
*finptr = '\000'; /* null-terminate converted double */ |
return ( finval ); /* converted double back to caller */ |
return ( finval ); /* converted double back to caller */ |
} /* --- end-of-function dtoa() --- */ |
} /* --- end-of-function dbltoa() --- */ |
|
|
|
|
/* ========================================================================== |
/* ========================================================================== |
Line 9279 for ( irow=0; irow<height; irow++ )
|
Line 10684 for ( irow=0; irow<height; irow++ )
|
(eebitval==fgbitval && ssbitval==fgbitval) || /*lower-right edge*/ |
(eebitval==fgbitval && ssbitval==fgbitval) || /*lower-right edge*/ |
(ssbitval==fgbitval && wwbitval==fgbitval) || /*lower-left edge*/ |
(ssbitval==fgbitval && wwbitval==fgbitval) || /*lower-left edge*/ |
(wwbitval==fgbitval && nnbitval==fgbitval) ; /*upper-left edge*/ |
(wwbitval==fgbitval && nnbitval==fgbitval) ; /*upper-left edge*/ |
|
/* ---check top/bot left/right edges for corners (added by j.forkosh)--- */ |
|
if ( 1 ) { /* true to perform test */ |
|
int isbghorz=0, isfghorz=0, isbgvert=0, isfgvert=0; /* horz/vert edges */ |
|
isbghorz = /* top or bottom edge is all bg */ |
|
(nwbitval+nnbitval+nebitval == 3*bgbitval) || /* top edge bg */ |
|
(swbitval+ssbitval+sebitval == 3*bgbitval) ; /* bottom edge bg */ |
|
isfghorz = /* top or bottom edge is all fg */ |
|
(nwbitval+nnbitval+nebitval == 3*fgbitval) || /* top edge fg */ |
|
(swbitval+ssbitval+sebitval == 3*fgbitval) ; /* bottom edge fg */ |
|
isbgvert = /* left or right edge is all bg */ |
|
(nwbitval+wwbitval+swbitval == 3*bgbitval) || /* left edge bg */ |
|
(nebitval+eebitval+sebitval == 3*bgbitval) ; /* right edge bg */ |
|
isfgvert = /* left or right edge is all bg */ |
|
(nwbitval+wwbitval+swbitval == 3*fgbitval) || /* left edge fg */ |
|
(nebitval+eebitval+sebitval == 3*fgbitval) ; /* right edge fg */ |
|
if ( (isbghorz && isbgvert && (bitval==fgbitval)) /* we're at an...*/ |
|
|| (isfghorz && isfgvert && (bitval==bgbitval)) ) /*...inside corner */ |
|
continue; /* don't antialias */ |
|
} /* --- end-of-if(1) --- */ |
|
/* --- check #gaps for checkerboard (added by j.forkosh) --- */ |
|
if ( 0 ) { /* true to perform test */ |
|
int ngaps=0, mingaps=1,maxgaps=2; /* count #fg/bg flips (max=4 noop) */ |
|
if ( nwbitval!=nnbitval ) ngaps++; /* upper-left =? upper */ |
|
if ( nnbitval!=nebitval ) ngaps++; /* upper =? upper-right */ |
|
if ( nebitval!=eebitval ) ngaps++; /* upper-right =? right */ |
|
if ( eebitval!=sebitval ) ngaps++; /* right =? lower-right */ |
|
if ( sebitval!=ssbitval ) ngaps++; /* lower-right =? lower */ |
|
if ( ssbitval!=swbitval ) ngaps++; /* lower =? lower-left */ |
|
if ( swbitval!=wwbitval ) ngaps++; /* lower-left =? left */ |
|
if ( wwbitval!=nwbitval ) ngaps++; /* left =? upper-left */ |
|
if ( ngaps > 0 ) ngaps /= 2; /* each gap has 2 bg/fg flips */ |
|
if ( ngaps<mingaps || ngaps>maxgaps ) continue; |
|
} /* --- end-of-if(1) --- */ |
/* --- antialias if necessary --- */ |
/* --- antialias if necessary --- */ |
if ( (isbgalias && isbgedge) /* alias pixel surrounding bg */ |
if ( (isbgalias && isbgedge) /* alias pixel surrounding bg */ |
|| (isfgalias && isfgedge) /* alias pixel surrounding fg */ |
|| (isfgalias && isfgedge) /* alias pixel surrounding fg */ |
Line 9849 messages
|
Line 11287 messages
|
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
static char *copyright = /* copyright, gnu/gpl notice */ |
static char *copyright = /* copyright, gnu/gpl notice */ |
"+-----------------------------------------------------------------------+\n" |
"+-----------------------------------------------------------------------+\n" |
"|mimeTeX vers 1.61, Copyright(c) 2002-2005, John Forkosh Associates, Inc|\n" |
"|mimeTeX vers 1.63, Copyright(c) 2002-2006, John Forkosh Associates, Inc|\n" |
"+-----------------------------------------------------------------------+\n" |
"+-----------------------------------------------------------------------+\n" |
"| mimeTeX is free software, licensed to you under terms of the GNU/GPL, |\n" |
"| mimeTeX is free software, licensed to you under terms of the GNU/GPL, |\n" |
"| and comes with absolutely no warranty whatsoever. |\n" |
"| and comes with absolutely no warranty whatsoever. |\n" |
Line 9890 int unescape_url(); /* convert %xx's t
|
Line 11328 int unescape_url(); /* convert %xx's t
|
int emitcache(); /* emit cached image if it exists */ |
int emitcache(); /* emit cached image if it exists */ |
int isquery = 0, /* true if input from QUERY_STRING */ |
int isquery = 0, /* true if input from QUERY_STRING */ |
isqempty = 0, /* true if query string empty */ |
isqempty = 0, /* true if query string empty */ |
|
isqforce = 0, /* true to force query emulation */ |
isqlogging = 0, /* true if logging in query mode */ |
isqlogging = 0, /* true if logging in query mode */ |
isformdata = 0, /* true if input from html form */ |
isformdata = 0, /* true if input from html form */ |
isdumpimage = 0; /* true to dump image on stdout */ |
isinmemory = 1, /* true to generate image in memory*/ |
|
isdumpimage = 0, /* true to dump image on stdout */ |
|
isdumpbuffer = 0; /* true to dump to memory buffer */ |
/* --- rasterization --- */ |
/* --- rasterization --- */ |
subraster *rasterize(), *sp; /* rasterize expression */ |
subraster *rasterize(), *sp=NULL; /* rasterize expression */ |
raster *border_raster(), *bp; /* put a border around raster */ |
raster *border_raster(), *bp=NULL; /* put a border around raster */ |
|
int delete_subraster(); /* for clean-up at end-of-job */ |
int type_raster(), type_bytemap(), /* screen dump function prototypes */ |
int type_raster(), type_bytemap(), /* screen dump function prototypes */ |
xbitmap_raster(); /* mime xbitmap output function */ |
xbitmap_raster(); /* mime xbitmap output function */ |
/* --- http_referer --- */ |
/* --- http_referer --- */ |
Line 9918 int norefmaxlen = NOREFMAXLEN; /*max que
|
Line 11360 int norefmaxlen = NOREFMAXLEN; /*max que
|
void GIF_SetColor(),GIF_SetTransparent(); /* ...gifsave enntry points */ |
void GIF_SetColor(),GIF_SetTransparent(); /* ...gifsave enntry points */ |
#endif |
#endif |
char *gif_outfile = (char *)NULL, /* gif output defaults to stdout */ |
char *gif_outfile = (char *)NULL, /* gif output defaults to stdout */ |
|
gif_buffer[64000] = "\000", /* or gif written in memory buffer */ |
cachefile[256] = "\000", /* full path and name to cache file*/ |
cachefile[256] = "\000", /* full path and name to cache file*/ |
*md5str(); /* md5 has of expression */ |
*md5str(); /* md5 has of expression */ |
int maxage = 7200; /* max-age is two hours */ |
int maxage = 7200; /* max-age is two hours */ |
|
/* --- pbm/pgm (-g switch) --- */ |
|
int ispbmpgm = 0; /* true to write pbm/pgm file */ |
|
int type_pbmpgm(), ptype=0; /* entry point, graphic format */ |
|
char *pbm_outfile = (char *)NULL; /* output file defaults to stdout */ |
/* --- anti-aliasing --- */ |
/* --- anti-aliasing --- */ |
intbyte *bytemap_raster = NULL, /* anti-aliased bitmap */ |
intbyte *bytemap_raster = NULL, /* anti-aliased bitmap */ |
colors[256]; /* grayscale vals in bytemap */ |
colors[256]; /* grayscale vals in bytemap */ |
Line 9948 initialization
|
Line 11395 initialization
|
/* --- set global variables --- */ |
/* --- set global variables --- */ |
msgfp = stdout; /* for comamnd-line mode output */ |
msgfp = stdout; /* for comamnd-line mode output */ |
isss = issupersampling; /* set supersampling flag */ |
isss = issupersampling; /* set supersampling flag */ |
|
gifSize = 0; /* signal that image not in memory */ |
shrinkfactor = shrinkfactors[NORMALSIZE]; /* set shrinkfactor */ |
shrinkfactor = shrinkfactors[NORMALSIZE]; /* set shrinkfactor */ |
/* --- |
/* --- |
* check QUERY_STRING query for expression overriding command-line arg |
* check QUERY_STRING query for expression overriding command-line arg |
Line 9962 if ( !isquery ) /* empty query string
|
Line 11410 if ( !isquery ) /* empty query string
|
*name = getenv("SERVER_NAME"), *addr = getenv("SERVER_ADDR"); |
*name = getenv("SERVER_NAME"), *addr = getenv("SERVER_ADDR"); |
if ( host!=NULL || name!=NULL || addr!=NULL ) /* assume http query */ |
if ( host!=NULL || name!=NULL || addr!=NULL ) /* assume http query */ |
{ isquery = 1; /* set flag to signal query */ |
{ isquery = 1; /* set flag to signal query */ |
strcpy(expression,"\\red\\small\\rm~missing~query~string"); } |
strcpy(expression,"\\red\\small\\fbox{\\rm~no~query~string}"); } |
isqempty = 1; /* signal empty query string */ |
isqempty = 1; /* signal empty query string */ |
} /* --- end-of-if(!isquery) --- */ |
} /* --- end-of-if(!isquery) --- */ |
/* --- |
/* --- |
Line 9997 if ( !isquery /* don't have an html q
|
Line 11445 if ( !isquery /* don't have an html q
|
if ( !isstopsignal /* haven't seen stopsignal switch */ |
if ( !isstopsignal /* haven't seen stopsignal switch */ |
&& *argv[argnum] == '-' ) /* and have some '-' switch */ |
&& *argv[argnum] == '-' ) /* and have some '-' switch */ |
{ |
{ |
char flag = tolower(*(argv[argnum]+1)); /* single char following '-' */ |
char *field = argv[argnum] + 1; /* ptr to char(s) following - */ |
int arglen = strlen(argv[argnum]) - 1; /* #chars following - */ |
char flag = tolower(*field); /* single char following '-' */ |
|
int arglen = strlen(field); /* #chars following - */ |
argnum++; /* arg following flag/switch is usually its value */ |
argnum++; /* arg following flag/switch is usually its value */ |
nswitches++; /* another switch on command line */ |
nswitches++; /* another switch on command line */ |
if ( isstrict && arglen!=1 ) /* only single-char switch allowed */ |
if ( isstrict && /* if strict checking then... */ |
|
!isthischar(flag,"g") && arglen!=1 ) /*must be single-char switch*/ |
{ nbadargs++; argnum--; } /* so ignore longer -xxx switch */ |
{ nbadargs++; argnum--; } /* so ignore longer -xxx switch */ |
else /* process single-char -x switch */ |
else /* process single-char -x switch */ |
switch ( flag ) { /* see what user wants to tell us */ |
switch ( flag ) { /* see what user wants to tell us */ |
/* --- ignore uninterpreted flag --- */ |
/* --- ignore uninterpreted flag --- */ |
default: nbadargs++; argnum--; break; |
default: nbadargs++; argnum--; break; |
/* --- adjustable program parameters (not checking input) --- */ |
/* --- adjustable program parameters (not checking input) --- */ |
|
case 'b': isdumpimage++; isdumpbuffer++; argnum--; break; |
case 'd': isdumpimage++; argnum--; break; |
case 'd': isdumpimage++; argnum--; break; |
case 'e': isdumpimage++; gif_outfile=argv[argnum]; break; |
case 'e': isdumpimage++; gif_outfile=argv[argnum]; break; |
case 'f': isdumpimage++; infilearg=argnum; break; |
case 'f': isdumpimage++; infilearg=argnum; break; |
|
case 'g': ispbmpgm++; |
|
if ( arglen > 1 ) ptype = atoi(field+1); /* -g2 ==> ptype=2 */ |
|
if ( 1 || *argv[argnum]=='-' ) argnum--; /*next arg is -switch*/ |
|
else pbm_outfile = argv[argnum]; break; /*next arg is filename*/ |
case 'm': msglevel = atoi(argv[argnum]); break; |
case 'm': msglevel = atoi(argv[argnum]); break; |
case 'o': istransparent = 0; argnum--; break; |
case 'o': istransparent = 0; argnum--; break; |
|
case 'q': isqforce = 1; argnum--; break; |
case 's': size = atoi(argv[argnum]); break; |
case 's': size = atoi(argv[argnum]); break; |
} /* --- end-of-switch(flag) --- */ |
} /* --- end-of-switch(flag) --- */ |
} /* --- end-of-if(*argv[argnum]=='-') --- */ |
} /* --- end-of-if(*argv[argnum]=='-') --- */ |
Line 10024 if ( !isquery /* don't have an html q
|
Line 11480 if ( !isquery /* don't have an html q
|
else nbadargs++; /* infile and expression invalid */ |
else nbadargs++; /* infile and expression invalid */ |
} /* --- end-of-while(argc>++argnum) --- */ |
} /* --- end-of-while(argc>++argnum) --- */ |
if ( msglevel>=999 && msgfp!=NULL ) /* display command-line info */ |
if ( msglevel>=999 && msgfp!=NULL ) /* display command-line info */ |
fprintf(msgfp,"argc=%d, progname=%s, #args=%d, #badargs=%d\n", |
{ fprintf(msgfp,"argc=%d, progname=%s, #args=%d, #badargs=%d\n", |
argc,progname,nargs,nbadargs); |
argc,progname,nargs,nbadargs); |
|
fprintf(msgfp,"cachepath=\"%.50s\" pathprefix=\"%.50s\"\n", |
|
cachepath,pathprefix); } |
/* --- |
/* --- |
* decide whether command-line input overrides query_string |
* decide whether command-line input overrides query_string |
* -------------------------------------------------------- */ |
* -------------------------------------------------------- */ |
Line 10057 if ( !isquery /* don't have an html q
|
Line 11515 if ( !isquery /* don't have an html q
|
strcat(expression,instring); /* concat line to end of expression*/ |
strcat(expression,instring); /* concat line to end of expression*/ |
fclose ( infile ); } /*close input file after reading expression*/ |
fclose ( infile ); } /*close input file after reading expression*/ |
} /* --- end-of-if(infilearg>0) --- */ |
} /* --- end-of-if(infilearg>0) --- */ |
|
/* --- |
|
* check if emulating query (for testing) |
|
* -------------------------------------- */ |
|
if ( isqforce ) isquery = 1; /* emulate query string processing */ |
|
/* --- |
|
* check if emitting pbm/pgm graphic |
|
* --------------------------------- */ |
|
if ( isgoodargs && ispbmpgm > 0 ) /* have a good -g arg */ |
|
if ( 1 && gif_outfile != NULL ) /* had an -e switch with file */ |
|
if ( *gif_outfile != '\000' ) /* make sure string isn't empty */ |
|
{ pbm_outfile = gif_outfile; /* use -e switch file for pbm/pgm */ |
|
gif_outfile = (char *)NULL; /* reset gif output file */ |
|
/*isdumpimage--;*/ } /* and decrement -e count */ |
} /* --- end-of-if(!isquery) --- */ |
} /* --- end-of-if(!isquery) --- */ |
/* --- |
/* --- |
* check for <form> input |
* check for <form> input |
Line 10221 if ( isquery ) /* not relevant if "in
|
Line 11692 if ( isquery ) /* not relevant if "in
|
/* --- |
/* --- |
* check for image caching |
* check for image caching |
* ----------------------- */ |
* ----------------------- */ |
if ( strstr(expression,"\\counter") != NULL /* can't cache \counter{} */ |
if ( strstr(expression,"\\counter") != NULL /* can't cache \counter{} */ |
|| strstr(expression,"\\input") != NULL /* can't cache \input{} */ |
|| strstr(expression,"\\input") != NULL /* can't cache \input{} */ |
|| strstr(expression,"\\nocach") != NULL /* no caching requested */ |
|| strstr(expression,"\\today") != NULL /* can't cache \today */ |
|
|| strstr(expression,"\\calendar") != NULL /* can't cache \calendar */ |
|
|| strstr(expression,"\\nocach") != NULL /* no caching requested */ |
|
|| isformdata /* don't cache user form input */ |
) { iscaching = 0; /* so turn caching off */ |
) { iscaching = 0; /* so turn caching off */ |
maxage = 2; } /* and set max-age to two seconds */ |
maxage = 5; } /* and set max-age to 5 seconds */ |
if ( isquery ) /* don't cache command-line images */ |
if ( isquery ) /* don't cache command-line images */ |
if ( iscaching ) /* image caching enabled */ |
if ( iscaching ) /* image caching enabled */ |
{ |
{ |
Line 10239 if ( isquery ) /* don't cache command
|
Line 11713 if ( isquery ) /* don't cache command
|
strcat(cachefile,md5hash); /* add md5 hash of expression */ |
strcat(cachefile,md5hash); /* add md5 hash of expression */ |
strcat(cachefile,".gif"); /* finish with .gif extension */ |
strcat(cachefile,".gif"); /* finish with .gif extension */ |
gif_outfile = cachefile; /* signal GIF_Create() to cache */ |
gif_outfile = cachefile; /* signal GIF_Create() to cache */ |
/* --- (always) emit mime content-type line --- */ |
/* --- emit mime content-type line --- */ |
fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
if ( 0 ) /* now done in emitcache() */ |
fprintf( stdout, "Content-type: image/gif\n\n" ); |
{ fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
|
fprintf( stdout, "Content-type: image/gif\n\n" ); } |
/* --- emit cached image if it already exists --- */ |
/* --- emit cached image if it already exists --- */ |
if ( emitcache(cachefile) > 0 ) /* cached image emitted */ |
if ( emitcache(cachefile,maxage,0) > 0 ) /* cached image emitted */ |
goto end_of_job; /* so nothing else to do */ |
goto end_of_job; /* so nothing else to do */ |
/* --- log caching request --- */ |
/* --- log caching request --- */ |
if ( msglevel >= 1 /* check if logging */ |
if ( msglevel >= 1 /* check if logging */ |
Line 10258 if ( isquery ) /* don't cache command
|
Line 11733 if ( isquery ) /* don't cache command
|
!= NULL ) /* ignore logging if can't open */ |
!= NULL ) /* ignore logging if can't open */ |
{ int isreflogged = 0; /* set true if http_referer logged */ |
{ int isreflogged = 0; /* set true if http_referer logged */ |
fprintf(filefp,"%s %s\n", /* timestamp, md5 file */ |
fprintf(filefp,"%s %s\n", /* timestamp, md5 file */ |
timestamp(),cachefile+strlen(cachepath)); /* (path not shown) */ |
timestamp(TZDELTA,0),cachefile+strlen(cachepath)); /*skip path*/ |
fprintf(filefp,"%s\n",expression); /* expression in filename */ |
fprintf(filefp,"%s\n",expression); /* expression in filename */ |
if ( http_referer != NULL ) /* show referer if we have one */ |
if ( http_referer != NULL ) /* show referer if we have one */ |
if ( *http_referer != '\000' ) /* and if not an empty string*/ |
if ( *http_referer != '\000' ) /* and if not an empty string*/ |
Line 10305 if ( issupersampling ) /* no border ne
|
Line 11780 if ( issupersampling ) /* no border ne
|
else /* for mime xbitmaps must have... */ |
else /* for mime xbitmaps must have... */ |
bp = border_raster(sp->image,0,0,0,1); /* image width multiple of 8 bits */ |
bp = border_raster(sp->image,0,0,0,1); /* image width multiple of 8 bits */ |
sp->image = bitmap_raster = bp; /* global copy for gif,png output */ |
sp->image = bitmap_raster = bp; /* global copy for gif,png output */ |
|
if ( ispbmpgm && ptype<2 ) /* -g switch or -g1 switch */ |
|
type_pbmpgm(bp,ptype,pbm_outfile); /* emit b/w pbm file */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
generate anti-aliased bytemap from (bordered) bitmap |
generate anti-aliased bytemap from (bordered) bitmap |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
Line 10351 if ( isaa ) /* we want anti-aliased b
|
Line 11828 if ( isaa ) /* we want anti-aliased b
|
{ isaa = 0; /* so turn off anti-aliasing */ |
{ isaa = 0; /* so turn off anti-aliasing */ |
ncolors = 2; } /* and reset for black&white */ |
ncolors = 2; } /* and reset for black&white */ |
} /* --- end-of-if(isaa) --- */ |
} /* --- end-of-if(isaa) --- */ |
|
if ( isaa && ispbmpgm && ptype>1 ) { /* -g2 switch */ |
|
raster pbm_raster; /*construct arg for write_pbmpgm()*/ |
|
pbm_raster.width = bp->width; pbm_raster.height = bp->height; |
|
pbm_raster.pixsz = 8; pbm_raster.pixmap = (pixbyte *)bytemap_raster; |
|
type_pbmpgm(&pbm_raster,ptype,pbm_outfile); } /*write grayscale file*/ |
} /* --- end-of-if(isaa) --- */ |
} /* --- end-of-if(isaa) --- */ |
} /* --- end-of-if(isaa) --- */ |
} /* --- end-of-if(isaa) --- */ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Line 10392 if ( (!isquery||isqlogging) || msglevel
|
Line 11874 if ( (!isquery||isqlogging) || msglevel
|
emit xbitmap or gif image, and exit |
emit xbitmap or gif image, and exit |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
if ( isquery /* called from browser (usual) */ |
if ( isquery /* called from browser (usual) */ |
|| isdumpimage /* or to emit dump of image */ |
|| (isdumpimage && !ispbmpgm) /* or to emit gif dump of image */ |
|| msglevel >= 99 ) /* or for debugging */ |
|| msglevel >= 99 ) /* or for debugging */ |
{ |
{ |
int igray = 0; /* grayscale index */ |
int igray = 0; /* grayscale index */ |
Line 10400 if ( isquery /* called from browser
|
Line 11882 if ( isquery /* called from browser
|
/* ------------------------------------------------------------------------ |
/* ------------------------------------------------------------------------ |
emit GIF image |
emit GIF image |
------------------------------------------------------------------------- */ |
------------------------------------------------------------------------- */ |
|
/* --- don't use memory buffer if outout file given --- */ |
|
if ( gif_outfile != NULL ) isinmemory = 0; /* reset memory buffer flag */ |
/* --- emit mime content-type line --- */ |
/* --- emit mime content-type line --- */ |
if ( !isdumpimage /* don't mix ascii with image dump */ |
if ( !isdumpimage /* don't mix ascii with image dump */ |
&& !iscaching ) /* already emitted if caching */ |
&& !isinmemory /* done below if in memory */ |
|
&& !iscaching ) /* done by emitcache() if caching */ |
{ fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
{ fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
/*fprintf( stdout, "Expires: Fri, 31 Oct 2003 23:59:59 GMT\n" );*/ |
/*fprintf( stdout, "Expires: Fri, 31 Oct 2003 23:59:59 GMT\n" );*/ |
/*fprintf( stdout, "Last-Modified: Wed, 15 Oct 2003 01:01:01 GMT\n" );*/ |
/*fprintf( stdout, "Last-Modified: Wed, 15 Oct 2003 01:01:01 GMT\n" );*/ |
fprintf( stdout, "Content-type: image/gif\n\n" ); } |
fprintf( stdout, "Content-type: image/gif\n\n" ); } |
|
/* --- write output to memory buffer, possibly for testing --- */ |
|
if ( isinmemory /* want gif written to memory */ |
|
|| isdumpbuffer ) /*or dump memory buffer for testing*/ |
|
if ( gif_outfile == NULL ) /* and don't already have a file */ |
|
{ *gif_buffer = '\000'; /* init buffer as empty string */ |
|
memset(gif_buffer,0,4096); /* zero out buffer */ |
|
gif_outfile = gif_buffer; /* and point outfile to buffer */ |
|
if ( isdumpbuffer ) /* buffer dump test requested */ |
|
isdumpbuffer = 999; } /* so signal dumping to buffer */ |
/* --- initialize gifsave library and colors --- */ |
/* --- initialize gifsave library and colors --- */ |
if ( msgfp!=NULL && msglevel>=999 ) |
if ( msgfp!=NULL && msglevel>=999 ) |
fprintf(msgfp,"main> calling GIF_Create(*,%d,%d,%d,8)\n", |
{ fprintf(msgfp,"main> calling GIF_Create(*,%d,%d,%d,8)\n", |
bp->width,bp->height,ncolors); |
bp->width,bp->height,ncolors); fflush(msgfp); } |
while ( 1 ) /* init gifsave lib, and retry if caching fails */ |
while ( 1 ) /* init gifsave lib, and retry if caching fails */ |
{ int status = GIF_Create(gif_outfile, bp->width,bp->height, ncolors, 8); |
{ int status = GIF_Create(gif_outfile, bp->width,bp->height, ncolors, 8); |
if ( status == 0 ) break; /* continue if succeeded */ |
if ( status == 0 ) break; /* continue if succeeded */ |
if ( iscaching == 0 ) goto end_of_job; /* quit if failed */ |
if ( iscaching == 0 ) goto end_of_job; /* quit if failed */ |
iscaching = 0; /* retry without cache file */ |
iscaching = 0; /* retry without cache file */ |
gif_outfile = (char *)NULL; } /* emit images to stdout */ |
isdumpbuffer = 0; /* reset isdumpbuffer signal */ |
|
if ( isquery ) isinmemory = 1; /* force in-memory image generation*/ |
|
if ( isinmemory ) { /* using memory buffer */ |
|
gif_outfile = gif_buffer; /* emit images to memory buffer */ |
|
*gif_outfile = '\000'; } /* empty string signals buffer */ |
|
else { /* or */ |
|
gif_outfile = (char *)NULL; /* emit images to stdout */ |
|
fprintf( stdout, "Cache-Control: max-age=%d\n",maxage ); |
|
fprintf( stdout, "Content-type: image/gif\n\n" ); } |
|
} /* --- end-of-while(1) --- */ |
GIF_SetColor(0,bgred,bggreen,bgblue); /* background white if all 255 */ |
GIF_SetColor(0,bgred,bggreen,bgblue); /* background white if all 255 */ |
if ( !isaa ) /* just b&w if not anti-aliased */ |
if ( !isaa ) /* just b&w if not anti-aliased */ |
{ GIF_SetColor(1,fgred,fggreen,fgblue); /* foreground black if all 0 */ |
{ GIF_SetColor(1,fgred,fggreen,fgblue); /* foreground black if all 0 */ |
Line 10441 if ( isquery /* called from browser
|
Line 11944 if ( isquery /* called from browser
|
/* --- emit compressed gif image (to stdout or cache file) --- */ |
/* --- emit compressed gif image (to stdout or cache file) --- */ |
GIF_CompressImage(0, 0, -1, -1, GetPixel); /* emit gif */ |
GIF_CompressImage(0, 0, -1, -1, GetPixel); /* emit gif */ |
GIF_Close(); /* close file */ |
GIF_Close(); /* close file */ |
/* --- may need to emit image from cached file --- */ |
if ( msgfp!=NULL && msglevel>=9 ) |
if ( isquery && iscaching ) /* caching enabled */ |
{ fprintf(msgfp,"main> created gifSize=%d\n", gifSize); |
emitcache(cachefile); /* cached image (hopefully) emitted*/ |
fflush(msgfp); } |
|
/* --- may need to emit image from cached file or from memory --- */ |
|
if ( isquery /* have an actual query string */ |
|
|| isdumpimage /* or dumping image */ |
|
|| msglevel >= 99 ) { /* or debugging */ |
|
int maxage2 = (isdumpimage?(-1):maxage); /* no headers if dumping image */ |
|
if ( iscaching ) /* caching enabled */ |
|
emitcache(cachefile,maxage2,0); /* cached image (hopefully) emitted*/ |
|
else if ( isinmemory ) /* or emit image from memory buffer*/ |
|
emitcache(gif_buffer,maxage2,1); } /* emitted from memory buffer */ |
|
/* --- for testing, may need to write image buffer to file --- */ |
|
if ( isdumpbuffer > 99 ) /* gif image in memory buffer */ |
|
if ( gifSize > 0 ) /* and it's not an empty buffer */ |
|
{ FILE *dumpfp = fopen("mimetex.gif","wb"); /* dump to mimetex.gif */ |
|
if ( dumpfp != NULL ) /* file opened successfully */ |
|
{ fwrite(gif_buffer,sizeof(unsigned char),gifSize,dumpfp); /*write*/ |
|
fclose(dumpfp); } /* and close file */ |
|
} /* --- end-of-if(isdumpbuffer>99) --- */ |
#else |
#else |
/* ------------------------------------------------------------------------ |
/* ------------------------------------------------------------------------ |
emit mime XBITMAP image |
emit mime XBITMAP image |
Line 10453 if ( isquery /* called from browser
|
Line 11973 if ( isquery /* called from browser
|
} /* --- end-of-if(isquery) --- */ |
} /* --- end-of-if(isquery) --- */ |
/* --- exit --- */ |
/* --- exit --- */ |
end_of_job: |
end_of_job: |
if ( bytemap_raster != NULL ) free(bytemap_raster); /*free bytemap_raster*/ |
if ( !isss ) /*bytemap raster in sp for supersamp*/ |
|
if ( bytemap_raster != NULL ) free(bytemap_raster);/*free bytemap_raster*/ |
if (colormap_raster != NULL )free(colormap_raster); /*and colormap_raster*/ |
if (colormap_raster != NULL )free(colormap_raster); /*and colormap_raster*/ |
|
if ( 0 && gif_buffer != NULL ) free(gif_buffer); /* free malloced buffer */ |
|
if ( 1 && sp != NULL ) delete_subraster(sp); /* and free expression */ |
if ( msgfp != NULL /* have message/log file open */ |
if ( msgfp != NULL /* have message/log file open */ |
&& msgfp != stdout ) /* and it's not stdout */ |
&& msgfp != stdout ) /* and it's not stdout */ |
{ fprintf(msgfp,"mimeTeX> successful end-of-job at %s\n",timestamp()); |
{ fprintf(msgfp,"mimeTeX> successful end-of-job at %s\n", |
|
timestamp(TZDELTA,0)); |
fprintf(msgfp,"%s\n",dashes); /* so log separator line */ |
fprintf(msgfp,"%s\n",dashes); /* so log separator line */ |
fclose(msgfp); } /* and close logfile */ |
fclose(msgfp); } /* and close logfile */ |
exit ( 0 ); |
/* --- dump memory leaks in debug window if in MS VC++ debug mode --- */ |
|
#if defined(_CRTDBG_MAP_ALLOC) |
|
_CrtDumpMemoryLeaks(); |
|
#endif |
|
/* --- exit() if not running as Windows DLL (see CreateGifFromEq()) --- */ |
|
#if !defined(_USRDLL) |
|
exit ( 0 ); |
|
#endif |
} /* --- end-of-function main() --- */ |
} /* --- end-of-function main() --- */ |
|
|
/* ========================================================================== |
/* ========================================================================== |
|
* Function: CreateGifFromEq ( expression, gifFileName ) |
|
* Purpose: shortcut method to create GIF file for expression, |
|
* with antialising and all other capabilities |
|
* -------------------------------------------------------------------------- |
|
* Arguments: expression (I) char *ptr to null-terminated string |
|
* containing LaTeX expression to be rendred |
|
* gifFileName (I) char *ptr to null-terminated string |
|
* containing name of output gif file |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) exit value from main (0 if successful) |
|
* -------------------------------------------------------------------------- |
|
* Notes: o This function is the entry point when mimeTeX is built |
|
* as a Win32 DLL rather then a standalone app or CGI |
|
* o Contributed to mimeTeX by Shital Shah. See his homepage |
|
* http://www.shitalshah.com |
|
* o Shital discusses the mimeTeX Win32 DLL project at |
|
* http://www.codeproject.com/dotnet/Eq2Img.asp |
|
* and you can download his latest code from |
|
* http://www.shitalshah.com/dev/eq2img_all.zip |
|
* ======================================================================= */ |
|
/* --- include function to expose Win32 DLL to outside world --- */ |
|
#if defined(_USRDLL) |
|
extern _declspec(dllexport)int _cdecl |
|
CreateGifFromEq ( char *expression, char *gifFileName ); |
|
#endif |
|
/* --- entry point --- */ |
|
int CreateGifFromEq ( char *expression, char *gifFileName ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
int main(); /* main() akways returns an int */ |
|
/* --- set constants --- */ |
|
int argc = 4; /* count of args supplied to main() */ |
|
char *argv[5] = /* command line args to run with -e option */ |
|
{ "MimeTeXWin32DLL", "-e", /* constant args */ |
|
/*gifFileName, expression,*/ NULL, NULL, NULL }; |
|
/* --- set argv[]'s not computable at load time --- */ |
|
argv[2] = gifFileName; /* args are -e gifFileName */ |
|
argv[3] = expression; /* and now -e gifFileName expression */ |
|
/* ------------------------------------------------------------------------- |
|
Run mimeTeX in command-line mode with -e (export) option, and then return |
|
-------------------------------------------------------------------------- */ |
|
return main ( argc, argv |
|
#ifdef DUMPENVP |
|
, NULL |
|
#endif |
|
) ; |
|
} /* --- end-of-function CreateGifFromEq() --- */ |
|
|
|
/* ========================================================================== |
* Function: isstrstr ( char *string, char *snippets, int iscase ) |
* Function: isstrstr ( char *string, char *snippets, int iscase ) |
* Purpose: determine whether any substring of 'string' |
* Purpose: determine whether any substring of 'string' |
* matches any of the comma-separated list of 'snippets', |
* matches any of the comma-separated list of 'snippets', |
Line 10669 char *value = NULL; /* getenv(name) to
|
Line 12251 char *value = NULL; /* getenv(name) to
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Log each variable |
Log each variable |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
fprintf(fp,"%s\n",timestamp()); /* emit timestamp before first var */ |
fprintf(fp,"%s\n",timestamp(TZDELTA,0)); /*emit timestamp before first var*/ |
if ( message != NULL ) /* optional message supplied */ |
if ( message != NULL ) /* optional message supplied */ |
fprintf(fp," MESSAGE = %s\n",message); /* emit caller-supplied message */ |
fprintf(fp," MESSAGE = %s\n",message); /* emit caller-supplied message */ |
if ( logvars != (logdata *)NULL ) /* have logvars */ |
if ( logvars != (logdata *)NULL ) /* have logvars */ |
Line 10686 return ( nlogged ); /* back to caller
|
Line 12268 return ( nlogged ); /* back to caller
|
} /* --- end-of-function logger() --- */ |
} /* --- end-of-function logger() --- */ |
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: emitcache ( cachefile ) |
* Function: emitcache ( cachefile, maxage, isbuffer ) |
* Purpose: dumps bytes from cachefile to stdout |
* Purpose: dumps bytes from cachefile to stdout |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Arguments: cachefile (I) pointer to null-terminated char string |
* Arguments: cachefile (I) pointer to null-terminated char string |
* containing full path to file to be dumped |
* containing full path to file to be dumped, |
|
* or contains buffer of bytes to be dumped |
|
* maxage (I) int containing maxage. in seconds, for |
|
* http header, or -1 to not emit headers |
|
* isbuffer (I) 1 if cachefile is buffer of bytes to be |
|
* dumped |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Returns: ( int ) #bytes dumped (0 signals error) |
* Returns: ( int ) #bytes dumped (0 signals error) |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
* Notes: o |
* Notes: o |
* ======================================================================= */ |
* ======================================================================= */ |
/* --- entry point --- */ |
/* --- entry point --- */ |
int emitcache ( char *cachefile ) |
int emitcache ( char *cachefile, int maxage, int isbuffer ) |
{ |
{ |
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
Allocations and Declarations |
Allocations and Declarations |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
FILE *cacheptr = fopen(cachefile,"rb"), /*open cachefile for binary read*/ |
int nbytes=gifSize, readcachefile(); /* read cache file */ |
*emitptr = stdout; /* emit cachefile to stdout */ |
FILE *emitptr = stdout; /* emit cachefile to stdout */ |
unsigned char buffer[64]; /* characters from cachefile */ |
unsigned char buffer[64000]; /* bytes from cachefile */ |
int buflen = 32, /* #bytes we try to read from cache*/ |
unsigned char *buffptr = buffer; /* ptr to buffer */ |
nread = 0, /* #bytes actually read */ |
|
nbytes = 0; /* total #bytes emitted */ |
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
initialization |
initialization |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
/* --- check that files opened okay --- */ |
/* --- check that files opened okay --- */ |
if ( cacheptr == (FILE *)NULL /* failed to open cachefile */ |
if ( emitptr == (FILE *)NULL ) /* failed to open emit file */ |
|| emitptr == (FILE *)NULL ) /* or failed to open emit file */ |
|
goto end_of_job; /* so return 0 bytes to caller */ |
goto end_of_job; /* so return 0 bytes to caller */ |
/* --- set stdout to binary mode (for Windows) --- */ |
/* --- read the file if necessary --- */ |
|
if ( isbuffer ) /* cachefile is buffer */ |
|
buffptr = (unsigned char *)cachefile; /* so reset buffer pointer */ |
|
else /* cachefile is file name */ |
|
if ( (nbytes = readcachefile(cachefile,buffer)) /* read the file */ |
|
< 1 ) goto end_of_job; /* quit if file not read */ |
|
/* --- first emit http headers if requested --- */ |
|
if ( maxage >= 0 ) /* caller wants http headers */ |
|
{ /* --- emit mime content-type line --- */ |
|
fprintf( emitptr, "Cache-Control: max-age=%d\n",maxage ); |
|
fprintf( emitptr, "Content-Length: %d\n",nbytes ); |
|
fprintf( emitptr, "Content-type: image/gif\n\n" ); } |
|
/* ------------------------------------------------------------------------- |
|
set stdout to binary mode (for Windows) |
|
-------------------------------------------------------------------------- */ |
/* emitptr = fdopen(STDOUT_FILENO,"wb"); */ /* doesn't work portably, */ |
/* emitptr = fdopen(STDOUT_FILENO,"wb"); */ /* doesn't work portably, */ |
#ifdef WINDOWS /* so instead... */ |
#ifdef WINDOWS /* so instead... */ |
#ifdef HAVE_SETMODE /* prefer (non-portable) setmode() */ |
#ifdef HAVE_SETMODE /* prefer (non-portable) setmode() */ |
Line 10732 if ( cacheptr == (FILE *)NULL /* failed
|
Line 12330 if ( cacheptr == (FILE *)NULL /* failed
|
/* ------------------------------------------------------------------------- |
/* ------------------------------------------------------------------------- |
emit bytes from cachefile |
emit bytes from cachefile |
-------------------------------------------------------------------------- */ |
-------------------------------------------------------------------------- */ |
|
/* --- write bytes to stdout --- */ |
|
if ( fwrite(buffptr,sizeof(unsigned char),nbytes,emitptr) /* write buffer */ |
|
< nbytes ) /* failed to write all bytes */ |
|
nbytes = 0; /* reset total count to 0 */ |
|
end_of_job: |
|
return ( nbytes ); /* back with #bytes emitted */ |
|
} /* --- end-of-function emitcache() --- */ |
|
|
|
/* ========================================================================== |
|
* Function: readcachefile ( cachefile, buffer ) |
|
* Purpose: read cachefile into buffer |
|
* -------------------------------------------------------------------------- |
|
* Arguments: cachefile (I) pointer to null-terminated char string |
|
* containing full path to file to be read |
|
* buffer (O) pointer to unsigned char string |
|
* returning contents of cachefile |
|
* (max 64000 bytes) |
|
* -------------------------------------------------------------------------- |
|
* Returns: ( int ) #bytes read (0 signals error) |
|
* -------------------------------------------------------------------------- |
|
* Notes: o |
|
* ======================================================================= */ |
|
/* --- entry point --- */ |
|
int readcachefile ( char *cachefile, unsigned char *buffer ) |
|
{ |
|
/* ------------------------------------------------------------------------- |
|
Allocations and Declarations |
|
-------------------------------------------------------------------------- */ |
|
FILE *cacheptr = fopen(cachefile,"rb"); /*open cachefile for binary read*/ |
|
unsigned char cachebuff[64]; /* bytes from cachefile */ |
|
int buflen = 32, /* #bytes we try to read from file */ |
|
nread = 0, /* #bytes actually read from file */ |
|
maxbytes = 64000, /* max #bytes returned in buffer */ |
|
nbytes = 0; /* total #bytes read */ |
|
/* ------------------------------------------------------------------------- |
|
initialization |
|
-------------------------------------------------------------------------- */ |
|
/* --- check that files opened okay --- */ |
|
if ( cacheptr == (FILE *)NULL ) goto end_of_job; /*failed to open cachefile*/ |
|
/* --- check that output buffer provided --- */ |
|
if ( buffer == (unsigned char *)NULL ) goto end_of_job; /* no buffer */ |
|
/* ------------------------------------------------------------------------- |
|
read bytes from cachefile |
|
-------------------------------------------------------------------------- */ |
while ( 1 ) |
while ( 1 ) |
{ |
{ |
/* --- read bytes from cachefile --- */ |
/* --- read bytes from cachefile --- */ |
nread = fread(buffer,sizeof(unsigned char),buflen,cacheptr); /* read */ |
nread = fread(cachebuff,sizeof(unsigned char),buflen,cacheptr); /* read */ |
|
if ( nbytes + nread > maxbytes ) /* block too big for buffer */ |
|
nread = maxbytes - nbytes; /* so truncate it */ |
if ( nread < 1 ) break; /* no bytes left in cachefile */ |
if ( nread < 1 ) break; /* no bytes left in cachefile */ |
/* --- write bytes to stdout --- */ |
/* --- store bytes in buffer --- */ |
if ( fwrite(buffer,sizeof(unsigned char),nread,emitptr) /* write buffer */ |
memcpy(buffer+nbytes,cachebuff,nread); /* copy current block to buffer */ |
< nread) /* failed to write all bytes */ |
/* --- ready to read next block --- */ |
{ nbytes = 0; /* reset total count to 0 */ |
|
goto end_of_job; } /* and signal error to caller */ |
|
nbytes += nread; /* bump total #bytes emitted */ |
nbytes += nread; /* bump total #bytes emitted */ |
if ( nread < buflen ) break; /* no bytes left in cachefile */ |
if ( nread < buflen ) break; /* no bytes left in cachefile */ |
|
if ( nbytes >= maxbytes ) break; /* avoid buffer overflow */ |
} /* --- end-of-while(1) --- */ |
} /* --- end-of-while(1) --- */ |
end_of_job: |
end_of_job: |
if ( cacheptr != NULL ) fclose(cacheptr); /* close file if opened */ |
if ( cacheptr != NULL ) fclose(cacheptr); /* close file if opened */ |
return ( nbytes ); /* back with #bytes emitted */ |
return ( nbytes ); /* back with #bytes emitted */ |
} /* --- end-of-function emitcache() --- */ |
} /* --- end-of-function readcachefile() --- */ |
|
|
/* ========================================================================== |
/* ========================================================================== |
* Function: md5str ( instr ) |
* Function: md5str ( instr ) |